feat(jogos): pedra, papel e tesoura, quantos dedos e achou! com a mão

- lib/maos.ts: dedos esticados pelos 21 pontos do MediaPipe (vale em
  qualquer rotação), contagem, jogada e leitura estável (mão parada);
- lib/jogos.svelte.ts: os três jogos conversam com o Carinha por comandos
  (fala com legenda, gestos e símbolo nos olhos) e contam como brincadeira
  para o modo vida; cartão "Jogos com a mão" no Ao vivo liga a câmera e o
  rastreamento com um toque;
- servidor: comandos "dizer" (até 120 caracteres) e "olhos" (símbolos e
  números permitidos, 0,5 a 8 s); rosto mostra o símbolo nos olhos.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
julio
2026-10-11 19:53:48 -03:00
co-authored by Claude Opus 5.5
parent 92701e8a16
commit 3d954efc03
10 changed files with 479 additions and 1 deletions
+10
View File
@@ -646,6 +646,15 @@ 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);
}
let olhosAte = null;
function mostrarNosOlhos(texto) { // "✌️ 2.5": símbolo nos olhos; "- 0" apaga
const i = texto.lastIndexOf(' ');
const simbolo = i > 0 ? texto.slice(0, i) : texto, seg = i > 0 ? parseFloat(texto.slice(i + 1)) : 2.5;
clearTimeout(olhosAte);
if (r.dormindo) { r.dormindo = false; }
window.carinhaOlhosIcone = simbolo && simbolo !== '-' ? simbolo : null;
if (window.carinhaOlhosIcone) olhosAte = setTimeout(() => { window.carinhaOlhosIcone = null; }, (seg || 2.5) * 1000);
}
function hesitar(fn, gesto) { // às vezes pensa um instante antes de agir
if (['surpreso', 'piscar', 'piscar2'].indexOf(gesto) >= 0 || Math.random() > 0.3) return fn();
setTimeout(fn, 150 + Math.random() * 450);
@@ -858,6 +867,7 @@ function trata(ordem) {
const bruta = (ordem || "").trim();
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
ordem = bruta.toLowerCase();
if (!ordem) return;
if(ordem==='recarregar') {