🧩 Exercícios - Cap 12: Arquitetura de Jogo (MVVM)
🎯 Antes de começar
No Cap 12 você conheceu o padrão MVVM e, nas Práticas Obrigatórias, criou o PersonagemViewModel (com vida privada + receberDano()) e a ArenaScreen que o exibe. Depois de completar as duas Práticas, faça o exercício extra abaixo para adicionar um segundo estado ao ViewModel e uma função de reinício.
💪 Exercício Extra 1: Contador de Golpes + Botão “Reiniciar” (20 min)
Objetivo: Praticar múltiplos estados encapsulados no mesmo ViewModel e uma função que reseta o estado do jogo.
Passos:
- No
PersonagemViewModel, adicione um segundo estado privado:private val _golpesRecebidos = mutableStateOf(0) val golpesRecebidos: State<Int> = _golpesRecebidos - Atualize
receberDano()para também contar os golpes:fun receberDano() { if (_vida.value > 0) { _vida.value -= 10 _golpesRecebidos.value += 1 } } - Adicione uma função
reiniciar():fun reiniciar() { _vida.value = 100 _golpesRecebidos.value = 0 } - Na
ArenaScreen, mostre o novo estado e adicione o botão:Text("Golpes recebidos: ${vm.golpesRecebidos.value}") Button(onClick = { vm.reiniciar() }) { Text("Reiniciar") }
✅ Resultado Esperado
- Cada toque em “Receber Golpe” diminui a
vidaem 10 e aumentagolpesRecebidosem 1, até a vida chegar a 0 (depois disso, nada muda). - Ao tocar em “Reiniciar”,
vidavolta para100egolpesRecebidosvolta para0— a tela inteira atualiza automaticamente. - Ambos os estados (
vidaegolpesRecebidos) continuam privados (_vida,_golpesRecebidos) — a tela só os lê, nunca os altera diretamente.
🆘 Resolução de Problemas Comuns
| Erro | Causa | Solução |
|---|---|---|
Unresolved reference: reiniciar |
A função foi adicionada na Screen, não no ViewModel |
Confirme que reiniciar() está dentro da classe PersonagemViewModel |
| Golpes continuam contando após a vida chegar a 0 | O += 1 de golpesRecebidos está fora do if (_vida.value > 0) |
Garanta que o incremento de golpesRecebidos esteja dentro do mesmo if que o decremento da vida |
| Tela não atualiza após “Reiniciar” | Esqueceu de usar .value = ao resetar (ex: trocou a referência do mutableStateOf inteiro) |
Sempre altere com _vida.value = 100, nunca crie um novo mutableStateOf |