feat(jogos): telão com contagem regressiva, jogadas lado a lado e resultado
- comando "telao" (validado: texto curto, tom, símbolos permitidos, até 2 lados) e letreiro por cima do rosto: título enorme que estoura e pisca, as duas jogadas (VOCÊ ✊ × ✋ CARINHA), cor por resultado; - pedra, papel e tesoura: 3, 2, 1 piscando, "JÁ!", o que ele leu da sua mão, "VENCI!!!" / "VOCÊ GANHOU!" / "EMPATE!" com placar e o campeão; quantos dedos e achou! também usam o telão; - o cartão do painel mostra o mesmo destaque. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,27 @@
|
||||
@keyframes aparecerFigura{from{opacity:0}to{opacity:1}}
|
||||
@media(prefers-reduced-motion:reduce){.iconeOlho,.figurinhaDinamica{animation:none}}
|
||||
#fps{position:fixed;left:4px;top:2px;color:#2b3a4a;font:12px monospace;display:none}
|
||||
/* telão dos jogos: por cima do rosto, texto grande na cor dos olhos (o resultado tem cor própria) */
|
||||
#telao{position:fixed;inset:0;z-index:8;display:flex;flex-direction:column;align-items:center;justify-content:center;
|
||||
gap:2vh;background:rgba(0,0,0,.9);font-family:system-ui,sans-serif;color:var(--cor);text-align:center;pointer-events:none}
|
||||
#telao .titulo{font-weight:900;font-size:clamp(40px,24vh,240px);line-height:1;letter-spacing:.02em;
|
||||
text-shadow:0 0 .25em currentColor}
|
||||
#telao .sub{font-size:clamp(14px,6vh,48px);font-weight:600;opacity:.9}
|
||||
#telao .lados{display:flex;align-items:center;gap:5vw}
|
||||
#telao .lado{display:flex;flex-direction:column;align-items:center;gap:1vh;min-width:22vw}
|
||||
#telao .rot{font-size:clamp(12px,5vh,36px);font-weight:700;letter-spacing:.1em;text-transform:uppercase;opacity:.85}
|
||||
#telao .sim{font-size:clamp(40px,26vh,220px);line-height:1}
|
||||
#telao .nome{font-size:clamp(12px,5vh,36px);font-weight:600}
|
||||
#telao .x{font-size:clamp(24px,12vh,110px);font-weight:300;opacity:.7}
|
||||
#telao.tom-eu .titulo{color:#ffd166}
|
||||
#telao.tom-voce .titulo{color:#7ae582}
|
||||
#telao.tom-empate .titulo{color:#cfe8ff}
|
||||
#telao.tom-conta .titulo{font-size:clamp(60px,48vh,420px)}
|
||||
#telao.entra .titulo,#telao.entra .lados{animation:telaoEstoura .45s cubic-bezier(.2,1.6,.4,1)}
|
||||
#telao.piscar.entra .titulo{animation:telaoEstoura .45s cubic-bezier(.2,1.6,.4,1),telaoPisca .5s steps(2) .45s infinite}
|
||||
@keyframes telaoEstoura{from{transform:scale(.3);opacity:0}to{transform:scale(1);opacity:1}}
|
||||
@keyframes telaoPisca{50%{opacity:.25}}
|
||||
@media(prefers-reduced-motion:reduce){#telao *{animation:none!important}}
|
||||
/* sem a placa: placa ✕ celular na cor dos olhos. Deitado, o rosto dormindo fica onde está e o
|
||||
desenho fica em pé no canto direito; em pé, o rosto sobe e o desenho vai embaixo. */
|
||||
#semServidor{position:fixed;right:2.5vw;top:50%;transform:translateY(-50%);width:min(24vw,42vh);
|
||||
@@ -646,6 +667,27 @@ function falarFrase(texto, segundos) { // "dizer ..." do modo vida: le
|
||||
if (window.MotorRosto) window.MotorRosto.faixa('legenda', { texto, segundos: segundos || Math.max(4, Math.min(14, texto.length / 9)) });
|
||||
falar(texto);
|
||||
}
|
||||
/* Telão dos jogos: contagem regressiva piscando, as duas jogadas lado a lado e o resultado grande. */
|
||||
let telaoAte = null;
|
||||
function mostrarTelao(json) {
|
||||
let t;
|
||||
try { t = JSON.parse(json); } catch (e) { return; }
|
||||
let el = document.getElementById('telao');
|
||||
if (!el) { el = document.createElement('div'); el.id = 'telao'; document.body.appendChild(el); }
|
||||
const esc = (s) => String(s || '').replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[c]));
|
||||
const lados = (t.lados || []).map((l) =>
|
||||
'<div class="lado"><span class="rot">' + esc(l.rotulo) + '</span><span class="sim">' + esc(l.simbolo) + '</span>' +
|
||||
'<span class="nome">' + esc(l.nome) + '</span></div>').join('<div class="x">×</div>');
|
||||
el.className = 'tom-' + (t.tom || 'neutro') + (t.piscar ? ' piscar' : '');
|
||||
el.style.setProperty('--cor', 'rgb(' + CIANO.map(Math.round).join(',') + ')');
|
||||
el.innerHTML = (lados ? '<div class="lados">' + lados + '</div>' : '') +
|
||||
(t.titulo ? '<div class="titulo">' + esc(t.titulo) + '</div>' : '') + (t.sub ? '<div class="sub">' + esc(t.sub) + '</div>' : '');
|
||||
el.hidden = false;
|
||||
void el.offsetWidth; el.classList.add('entra'); // reinicia a animação a cada letreiro
|
||||
if (r.dormindo) r.dormindo = false;
|
||||
clearTimeout(telaoAte);
|
||||
telaoAte = setTimeout(() => { el.hidden = true; }, (t.segundos || 2.5) * 1000);
|
||||
}
|
||||
let olhosAte = null;
|
||||
function mostrarNosOlhos(texto) { // "✌️ 2.5": símbolo nos olhos; "- 0" apaga
|
||||
const i = texto.lastIndexOf(' ');
|
||||
@@ -868,6 +910,7 @@ function trata(ordem) {
|
||||
if (/^aprendi /i.test(bruta)) { contarAprendi(bruta.slice(8).trim()); return; } // sem minúsculas: é uma frase
|
||||
if (/^dizer /i.test(bruta)) { falarFrase(bruta.slice(6).trim()); return; }
|
||||
if (/^olhos /i.test(bruta)) { mostrarNosOlhos(bruta.slice(6).trim()); return; } // jogos: ✊ ✋ ✌️ e números
|
||||
if (/^telao /i.test(bruta)) { mostrarTelao(bruta.slice(6)); return; } // letreiro grande dos jogos
|
||||
ordem = bruta.toLowerCase();
|
||||
if (!ordem) return;
|
||||
if(ordem==='recarregar') {
|
||||
|
||||
@@ -20,6 +20,27 @@
|
||||
@keyframes aparecerFigura{from{opacity:0}to{opacity:1}}
|
||||
@media(prefers-reduced-motion:reduce){.iconeOlho,.figurinhaDinamica{animation:none}}
|
||||
#fps{position:fixed;left:4px;top:2px;color:#2b3a4a;font:12px monospace;display:none}
|
||||
/* telão dos jogos: por cima do rosto, texto grande na cor dos olhos (o resultado tem cor própria) */
|
||||
#telao{position:fixed;inset:0;z-index:8;display:flex;flex-direction:column;align-items:center;justify-content:center;
|
||||
gap:2vh;background:rgba(0,0,0,.9);font-family:system-ui,sans-serif;color:var(--cor);text-align:center;pointer-events:none}
|
||||
#telao .titulo{font-weight:900;font-size:clamp(40px,24vh,240px);line-height:1;letter-spacing:.02em;
|
||||
text-shadow:0 0 .25em currentColor}
|
||||
#telao .sub{font-size:clamp(14px,6vh,48px);font-weight:600;opacity:.9}
|
||||
#telao .lados{display:flex;align-items:center;gap:5vw}
|
||||
#telao .lado{display:flex;flex-direction:column;align-items:center;gap:1vh;min-width:22vw}
|
||||
#telao .rot{font-size:clamp(12px,5vh,36px);font-weight:700;letter-spacing:.1em;text-transform:uppercase;opacity:.85}
|
||||
#telao .sim{font-size:clamp(40px,26vh,220px);line-height:1}
|
||||
#telao .nome{font-size:clamp(12px,5vh,36px);font-weight:600}
|
||||
#telao .x{font-size:clamp(24px,12vh,110px);font-weight:300;opacity:.7}
|
||||
#telao.tom-eu .titulo{color:#ffd166}
|
||||
#telao.tom-voce .titulo{color:#7ae582}
|
||||
#telao.tom-empate .titulo{color:#cfe8ff}
|
||||
#telao.tom-conta .titulo{font-size:clamp(60px,48vh,420px)}
|
||||
#telao.entra .titulo,#telao.entra .lados{animation:telaoEstoura .45s cubic-bezier(.2,1.6,.4,1)}
|
||||
#telao.piscar.entra .titulo{animation:telaoEstoura .45s cubic-bezier(.2,1.6,.4,1),telaoPisca .5s steps(2) .45s infinite}
|
||||
@keyframes telaoEstoura{from{transform:scale(.3);opacity:0}to{transform:scale(1);opacity:1}}
|
||||
@keyframes telaoPisca{50%{opacity:.25}}
|
||||
@media(prefers-reduced-motion:reduce){#telao *{animation:none!important}}
|
||||
/* sem a placa: placa ✕ celular na cor dos olhos. Deitado, o rosto dormindo fica onde está e o
|
||||
desenho fica em pé no canto direito; em pé, o rosto sobe e o desenho vai embaixo. */
|
||||
#semServidor{position:fixed;right:2.5vw;top:50%;transform:translateY(-50%);width:min(24vw,42vh);
|
||||
@@ -646,6 +667,27 @@ function falarFrase(texto, segundos) { // "dizer ..." do modo vida: le
|
||||
if (window.MotorRosto) window.MotorRosto.faixa('legenda', { texto, segundos: segundos || Math.max(4, Math.min(14, texto.length / 9)) });
|
||||
falar(texto);
|
||||
}
|
||||
/* Telão dos jogos: contagem regressiva piscando, as duas jogadas lado a lado e o resultado grande. */
|
||||
let telaoAte = null;
|
||||
function mostrarTelao(json) {
|
||||
let t;
|
||||
try { t = JSON.parse(json); } catch (e) { return; }
|
||||
let el = document.getElementById('telao');
|
||||
if (!el) { el = document.createElement('div'); el.id = 'telao'; document.body.appendChild(el); }
|
||||
const esc = (s) => String(s || '').replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[c]));
|
||||
const lados = (t.lados || []).map((l) =>
|
||||
'<div class="lado"><span class="rot">' + esc(l.rotulo) + '</span><span class="sim">' + esc(l.simbolo) + '</span>' +
|
||||
'<span class="nome">' + esc(l.nome) + '</span></div>').join('<div class="x">×</div>');
|
||||
el.className = 'tom-' + (t.tom || 'neutro') + (t.piscar ? ' piscar' : '');
|
||||
el.style.setProperty('--cor', 'rgb(' + CIANO.map(Math.round).join(',') + ')');
|
||||
el.innerHTML = (lados ? '<div class="lados">' + lados + '</div>' : '') +
|
||||
(t.titulo ? '<div class="titulo">' + esc(t.titulo) + '</div>' : '') + (t.sub ? '<div class="sub">' + esc(t.sub) + '</div>' : '');
|
||||
el.hidden = false;
|
||||
void el.offsetWidth; el.classList.add('entra'); // reinicia a animação a cada letreiro
|
||||
if (r.dormindo) r.dormindo = false;
|
||||
clearTimeout(telaoAte);
|
||||
telaoAte = setTimeout(() => { el.hidden = true; }, (t.segundos || 2.5) * 1000);
|
||||
}
|
||||
let olhosAte = null;
|
||||
function mostrarNosOlhos(texto) { // "✌️ 2.5": símbolo nos olhos; "- 0" apaga
|
||||
const i = texto.lastIndexOf(' ');
|
||||
@@ -868,6 +910,7 @@ function trata(ordem) {
|
||||
if (/^aprendi /i.test(bruta)) { contarAprendi(bruta.slice(8).trim()); return; } // sem minúsculas: é uma frase
|
||||
if (/^dizer /i.test(bruta)) { falarFrase(bruta.slice(6).trim()); return; }
|
||||
if (/^olhos /i.test(bruta)) { mostrarNosOlhos(bruta.slice(6).trim()); return; } // jogos: ✊ ✋ ✌️ e números
|
||||
if (/^telao /i.test(bruta)) { mostrarTelao(bruta.slice(6)); return; } // letreiro grande dos jogos
|
||||
ordem = bruta.toLowerCase();
|
||||
if (!ordem) return;
|
||||
if(ordem==='recarregar') {
|
||||
|
||||
@@ -240,9 +240,38 @@ def ordem_de_comando(tipo, valor):
|
||||
except (TypeError, ValueError):
|
||||
raise ValueError("Segundos inválidos") from None
|
||||
return "olhos %s %.1f" % (simbolo or "-", segundos)
|
||||
if tipo == "telao": # letreiro grande por cima do rosto (jogos)
|
||||
return "telao " + json.dumps(validar_telao(valor), ensure_ascii=False, separators=(",", ":"))
|
||||
raise ValueError("Tipo de comando inválido")
|
||||
|
||||
|
||||
TONS_TELAO = ("neutro", "eu", "voce", "empate", "conta")
|
||||
|
||||
|
||||
def validar_telao(v):
|
||||
"""{titulo, sub, tom, piscar, segundos, lados:[{rotulo, simbolo, nome}]} só com texto curto e símbolos permitidos."""
|
||||
if not isinstance(v, dict):
|
||||
raise ValueError("Telão inválido")
|
||||
texto = lambda x, n: " ".join(str(x or "").split())[:n]
|
||||
t = dict(titulo=texto(v.get("titulo"), 24), sub=texto(v.get("sub"), 80),
|
||||
tom=v.get("tom") if v.get("tom") in TONS_TELAO else "neutro", piscar=v.get("piscar") is True)
|
||||
try:
|
||||
t["segundos"] = max(0.3, min(10.0, float(v.get("segundos", 2.5))))
|
||||
except (TypeError, ValueError):
|
||||
raise ValueError("Segundos inválidos") from None
|
||||
lados = v.get("lados") or []
|
||||
if not isinstance(lados, list) or len(lados) > 2:
|
||||
raise ValueError("Lados inválidos")
|
||||
t["lados"] = []
|
||||
for l in lados:
|
||||
if not isinstance(l, dict) or (l.get("simbolo") and l.get("simbolo") not in OLHOS_JOGO):
|
||||
raise ValueError("Símbolo inválido no telão")
|
||||
t["lados"].append(dict(rotulo=texto(l.get("rotulo"), 12), simbolo=l.get("simbolo") or "", nome=texto(l.get("nome"), 14)))
|
||||
if not t["titulo"] and not t["lados"]:
|
||||
raise ValueError("Telão vazio")
|
||||
return t
|
||||
|
||||
|
||||
class Handler(SimpleHTTPRequestHandler):
|
||||
extensoes_map = {".html": "text/html; charset=utf-8",
|
||||
".js": "text/javascript; charset=utf-8",
|
||||
|
||||
@@ -93,6 +93,18 @@ class ServidorTest(unittest.TestCase):
|
||||
self.assertEqual(codigo, 200)
|
||||
self.assertIn('dizer Já!', kiosk.FILA.ordens())
|
||||
|
||||
def test_telao_dos_jogos(self):
|
||||
ordem = kiosk.ordem_de_comando('telao', {'titulo': 'VENCI!!!', 'tom': 'eu', 'sub': 'Você 0 × 1 Carinha', 'segundos': 3,
|
||||
'lados': [{'rotulo': 'Você', 'simbolo': '✊', 'nome': 'pedra'},
|
||||
{'rotulo': 'Carinha', 'simbolo': '✋', 'nome': 'papel'}]})
|
||||
self.assertTrue(ordem.startswith('telao {'))
|
||||
t = json.loads(ordem[6:])
|
||||
self.assertEqual((t['titulo'], t['tom'], len(t['lados'])), ('VENCI!!!', 'eu', 2))
|
||||
self.assertEqual(json.loads(kiosk.ordem_de_comando('telao', {'titulo': 'x' * 99, 'tom': 'roxo'})[6:])['tom'], 'neutro')
|
||||
for ruim in ({}, {'titulo': 'a', 'lados': [{'simbolo': '<img>'}]}, {'titulo': 'a', 'lados': [{}, {}, {}]}, 'texto'):
|
||||
with self.assertRaises(ValueError):
|
||||
kiosk.ordem_de_comando('telao', ruim)
|
||||
|
||||
def test_pagina_do_rosto_sempre_conferida_e_api_sem_cache(self):
|
||||
# o WebView do celular não pode seguir com uma carinha.html velha depois de um deploy
|
||||
for rota, esperado in (('/carinha.html', 'no-cache'), ('/gestos', 'no-store')):
|
||||
|
||||
@@ -32,6 +32,21 @@
|
||||
</div>
|
||||
<p class="fase">{jogos.fase || 'Começando…'}</p>
|
||||
<p class="vendo">A câmera vê: <strong>{jogos.vendo || '…'}</strong></p>
|
||||
{#if jogos.destaque}
|
||||
{@const d = jogos.destaque}
|
||||
<div class="destaque tom-{d.tom ?? 'neutro'}">
|
||||
{#if d.lados?.length}
|
||||
<div class="lados">
|
||||
{#each d.lados as l, i (i)}
|
||||
{#if i}<span class="x">×</span>{/if}
|
||||
<span class="lado"><small>{l.rotulo}</small><b>{l.simbolo}</b><small>{l.nome}</small></span>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{#if d.titulo}<strong class="titulo">{d.titulo}</strong>{/if}
|
||||
{#if d.sub}<small>{d.sub}</small>{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if jogos.ativo === 'ppt'}
|
||||
<p class="placar"><span>Você {jogos.placar.voce}</span> × <span>{jogos.placar.carinha} Carinha</span></p>
|
||||
{/if}
|
||||
@@ -77,6 +92,40 @@
|
||||
font-variant-numeric: tabular-nums;
|
||||
color: var(--texto) !important;
|
||||
}
|
||||
.destaque {
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
gap: 4px;
|
||||
padding: var(--e-3);
|
||||
border-radius: var(--raio);
|
||||
background: var(--superficie-3);
|
||||
text-align: center;
|
||||
}
|
||||
.destaque .titulo {
|
||||
font-size: var(--t-xl);
|
||||
font-weight: 800;
|
||||
}
|
||||
.destaque.tom-eu .titulo { color: #d39b00; }
|
||||
.destaque.tom-voce .titulo { color: var(--ok); }
|
||||
.destaque .lados {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--e-4);
|
||||
}
|
||||
.destaque .lado {
|
||||
display: grid;
|
||||
justify-items: center;
|
||||
}
|
||||
.destaque .lado b {
|
||||
font-size: 2.2rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
.destaque .x {
|
||||
color: var(--texto-3);
|
||||
}
|
||||
.destaque small {
|
||||
color: var(--texto-2);
|
||||
}
|
||||
.lista {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
||||
|
||||
@@ -21,11 +21,22 @@ const NOME: Record<Jogada, string> = { pedra: 'pedra', papel: 'papel', tesoura:
|
||||
|
||||
class Parou extends Error {}
|
||||
|
||||
export interface Telao {
|
||||
titulo?: string;
|
||||
sub?: string;
|
||||
tom?: 'neutro' | 'eu' | 'voce' | 'empate' | 'conta';
|
||||
piscar?: boolean;
|
||||
segundos?: number;
|
||||
lados?: { rotulo: string; simbolo: string; nome: string }[];
|
||||
}
|
||||
|
||||
class Jogos {
|
||||
ativo = $state<IdJogo | null>(null);
|
||||
fase = $state(''); // o que está acontecendo agora (aparece no painel)
|
||||
vendo = $state(''); // o que a câmera está lendo da sua mão
|
||||
placar = $state({ voce: 0, carinha: 0 });
|
||||
/** O que o telão do Carinha está mostrando (o painel mostra igual). */
|
||||
destaque = $state<Telao | null>(null);
|
||||
private rodada = 0;
|
||||
private maos: Ponto[][] = [];
|
||||
private faces = 0;
|
||||
@@ -54,6 +65,11 @@ class Jogos {
|
||||
private dizer = (texto: string) => this.ordem('dizer', texto);
|
||||
private gesto = (nome: string) => this.ordem('gesto', nome);
|
||||
private olhos = (simbolo: string, segundos = 2.5) => this.ordem('olhos', { simbolo, segundos });
|
||||
/** Letreiro grande por cima do rosto (e no cartão do painel). */
|
||||
private telao(t: Telao) {
|
||||
this.destaque = t;
|
||||
return this.ordem('telao', t);
|
||||
}
|
||||
|
||||
private esperar(ms: number) {
|
||||
return new Promise<void>((ok, nao) => {
|
||||
@@ -93,6 +109,7 @@ class Jogos {
|
||||
} finally {
|
||||
this.ativo = null;
|
||||
this.fase = '';
|
||||
this.destaque = null;
|
||||
this.olhos('', 0.5);
|
||||
}
|
||||
}
|
||||
@@ -121,31 +138,42 @@ class Jogos {
|
||||
}
|
||||
this.rodada++;
|
||||
this.fase = `Rodada ${this.rodada}: contando`;
|
||||
for (const palavra of ['Pedra...', 'Papel...', 'Tesoura...']) {
|
||||
await this.dizer(palavra);
|
||||
await this.esperar(750);
|
||||
const palavras = ['Pedra...', 'Papel...', 'Tesoura...'];
|
||||
for (let i = 0; i < 3; i++) {
|
||||
await this.telao({ titulo: String(3 - i), sub: palavras[i], tom: 'conta', piscar: true, segundos: 1.0 });
|
||||
await this.dizer(palavras[i]);
|
||||
await this.esperar(850);
|
||||
}
|
||||
const minha = (['pedra', 'papel', 'tesoura'] as Jogada[])[Math.floor(Math.random() * 3)];
|
||||
this.jogadaEstavel.limpar();
|
||||
await this.olhos(SIMBOLO[minha], 3.5);
|
||||
await this.telao({ titulo: 'JÁ!', sub: 'Mostra a mão parada!', tom: 'conta', segundos: 1.8 });
|
||||
await this.dizer('Já!');
|
||||
this.fase = `Rodada ${this.rodada}: lendo a sua mão`;
|
||||
const leitura = { v: null as Jogada | null };
|
||||
await this.ate(() => (leitura.v = this.jogadaEstavel.valor()) !== null, 2200);
|
||||
const sua = leitura.v;
|
||||
if (!sua) {
|
||||
await this.telao({ titulo: '?', sub: 'Não vi sua mão... de novo!', segundos: 2.2 });
|
||||
await this.dizer('Não vi direito... de novo!');
|
||||
await this.gesto('confuso');
|
||||
await this.esperar(2200);
|
||||
continue;
|
||||
}
|
||||
const r = vence(sua, minha);
|
||||
if (r > 0) this.placar.voce++;
|
||||
else if (r < 0) this.placar.carinha++;
|
||||
await this.telao({
|
||||
titulo: r > 0 ? 'VOCÊ GANHOU!' : r < 0 ? 'VENCI!!!' : 'EMPATE!',
|
||||
tom: r > 0 ? 'voce' : r < 0 ? 'eu' : 'empate',
|
||||
sub: `Você ${this.placar.voce} × ${this.placar.carinha} Carinha`,
|
||||
segundos: 3.4,
|
||||
lados: [{ rotulo: 'Você', simbolo: SIMBOLO[sua], nome: NOME[sua] }, { rotulo: 'Carinha', simbolo: SIMBOLO[minha], nome: NOME[minha] }],
|
||||
});
|
||||
if (r > 0) {
|
||||
this.placar.voce++;
|
||||
await this.dizer(`${NOME[sua]} ganha de ${NOME[minha]}... Você ganhou essa!`);
|
||||
await this.gesto('triste');
|
||||
} else if (r < 0) {
|
||||
this.placar.carinha++;
|
||||
await this.dizer(`${NOME[minha]} ganha de ${NOME[sua]}! Essa é minha!`);
|
||||
await this.gesto('comemorar');
|
||||
} else {
|
||||
@@ -155,7 +183,10 @@ class Jogos {
|
||||
this.fase = `Você ${this.placar.voce} × ${this.placar.carinha} Carinha`;
|
||||
await this.esperar(3200);
|
||||
}
|
||||
if (this.placar.voce > this.placar.carinha) {
|
||||
const ganhou = this.placar.voce > this.placar.carinha;
|
||||
await this.telao({ titulo: ganhou ? 'VOCÊ É O CAMPEÃO!' : 'EU SOU O CAMPEÃO!!!', tom: ganhou ? 'voce' : 'eu', piscar: true,
|
||||
sub: `Você ${this.placar.voce} × ${this.placar.carinha} Carinha`, segundos: 4.5 });
|
||||
if (ganhou) {
|
||||
await this.dizer(`Você ganhou de ${this.placar.voce} a ${this.placar.carinha}! Revanche depois, hein?`);
|
||||
await this.gesto('rir');
|
||||
} else {
|
||||
@@ -179,8 +210,12 @@ class Jogos {
|
||||
this.fase = `Rodada ${this.rodada} de 5: pediu ${alvo}`;
|
||||
this.dedosEstavel.limpar();
|
||||
if (mostra) await this.olhos(String(alvo), 6);
|
||||
await this.telao(mostra ? { titulo: String(alvo), sub: 'Mostra esse tanto de dedos!', tom: 'conta', segundos: 3 }
|
||||
: { titulo: '?', sub: `Mostra ${alvo} ${alvo === 1 ? 'dedo' : 'dedos'}!`, segundos: 3 });
|
||||
await this.dizer(mostra ? 'Mostra esse tanto de dedos!' : `Mostra ${alvo} ${alvo === 1 ? 'dedo' : 'dedos'}!`);
|
||||
const acertou = await this.ate(() => this.dedosEstavel.valor() === alvo, 9000);
|
||||
await this.telao(acertou ? { titulo: '✔ ACERTOU!', tom: 'voce', sub: `${alvo} ${alvo === 1 ? 'dedo' : 'dedos'}`, segundos: 2.6 }
|
||||
: { titulo: `ERAM ${alvo}!`, tom: 'empate', sub: 'Vamos pro próximo', segundos: 2.6 });
|
||||
if (acertou) {
|
||||
this.placar.voce++;
|
||||
await this.dizer(['Isso!', 'Acertou!', 'Muito bem!', 'Boa!'][this.rodada % 4]);
|
||||
@@ -218,6 +253,7 @@ class Jogos {
|
||||
await this.dizer(['Cadê? Cadê?', 'Sumiu!', 'Onde você foi?'][this.rodada - 1]);
|
||||
// apareceu de novo
|
||||
if (await this.ate(() => this.faces > 0, 15000)) {
|
||||
await this.telao({ titulo: 'ACHOU!', tom: 'voce', piscar: true, segundos: 2.2 });
|
||||
await this.gesto('rir');
|
||||
await this.dizer('Achou!');
|
||||
this.placar.voce++;
|
||||
|
||||
Reference in New Issue
Block a user