# Construir um Jogo Espacial Parte 6: Fim e Reinício ```mermaid journey title A Sua Jornada de Conclusão do Jogo section Condições Finais Definir estados de vitória/derrota: 3: Student Implementar verificação de condições: 4: Student Gerir transições de estado: 4: Student section Experiência do Jogador Desenhar sistemas de feedback: 4: Student Criar mecânicas de reinício: 5: Student Aprimorar interface do utilizador: 5: Student section Integração do Sistema Gerir ciclo de vida do jogo: 5: Student Tratar limpeza de memória: 5: Student Criar experiência completa: 5: Student ``` Todo jogo ótimo precisa de condições claras de fim e um mecanismo suave de reinício. Já construíste um jogo espacial impressionante com movimento, combate e pontuação – agora é hora de adicionar as peças finais que o fazem sentir-se completo. O teu jogo atualmente corre indefinidamente, como as sondas Voyager que a NASA lançou em 1977 – ainda a viajar pelo espaço décadas depois. Embora isso seja ótimo para exploração espacial, os jogos precisam de pontos finais definidos para criar experiências satisfatórias. Hoje, vamos implementar condições adequadas de vitória/derrota e um sistema de reinício. No final desta lição, terás um jogo polido que os jogadores podem completar e jogar novamente, tal como os clássicos jogos de arcada que definiram o meio. ```mermaid mindmap root((Conclusão do Jogo)) Condições de Fim Estados de Vitória Condições de Derrota Acompanhamento de Progresso Validação de Estado Feedback do Jogador Mensagens Visuais Psicologia das Cores Comunicação Clara Resposta Emocional Gestão de Estado Controlo do Loop do Jogo Limpeza de Memória Ciclo de Vida dos Objetos Gestão de Eventos Sistemas de Reinício Gestão de Entrada Reinicialização do Estado Inicialização Nova Experiência do Utilizador Elementos de Polimento Exibição de Mensagens Transições Suaves Prevenção de Erros Acessibilidade ``` ## Questionário Pré-Lição [Questionário pré-lição](https://ff-quizzes.netlify.app/web/quiz/39) ## Compreender as Condições de Fim de Jogo Quando deverá o teu jogo terminar? Esta questão fundamental moldou o design de jogos desde a era inicial dos arcades. Pac-Man termina quando és apanhado pelos fantasmas ou limpas todos os pontos, enquanto Space Invaders termina quando os alienígenas chegam ao fundo ou quando os destróis todos. Como criador do jogo, tu defines as condições de vitória e derrota. Para o nosso jogo espacial, aqui estão abordagens comprovadas que criam jogabilidade envolvente: ```mermaid flowchart TD A["🎮 Início do Jogo"] --> B{"Verificar Condições"} B --> C["Contagem de Inimigos"] B --> D["Vidas do Herói"] B --> E["Limite de Pontuação"] B --> F["Progresso do Nível"] C --> C1{"Inimigos = 0?"} D --> D1{"Vidas = 0?"} E --> E1{"Pontuação ≥ Objetivo?"} F --> F1{"Objetivos Completos?"} C1 -->|Sim| G["🏆 Vitória"] D1 -->|Sim| H["💀 Derrota"] E1 -->|Sim| G F1 -->|Sim| G C1 -->|Não| B D1 -->|Não| B E1 -->|Não| B F1 -->|Não| B G --> I["🔄 Opção de Reiniciar"] H --> I style G fill:#e8f5e8 style H fill:#ffebee style I fill:#e3f2fd ``` - **Foram destruídos `N` navios inimigos**: É bastante comum, se divides o jogo em diferentes níveis, que seja necessário destruir `N` navios inimigos para completar um nível - **O teu navio foi destruído**: Existem definitivamente jogos onde perdes se o teu navio for destruído. Outra abordagem comum é o conceito de vidas. Sempre que o teu navio é destruído, perdes uma vida. Depois de esgotares todas as vidas, perdes o jogo. - **Coleccionaste `N` pontos**: Outra condição comum de fim é coleccionares pontos. Como consegues pontos fica ao teu critério, mas é comum atribuir pontos a várias atividades, como destruir um navio inimigo ou talvez recolher itens que caem quando são destruídos. - **Completar um nível**: Isto pode envolver várias condições, como destruir `X` navios inimigos, coleccionar `Y` pontos ou talvez recolher um item específico. ## Implementar Funcionalidade de Reinício do Jogo Bons jogos incentivam a rejogabilidade através de mecanismos suaves de reinício. Quando os jogadores completam um jogo (ou são derrotados), muitas vezes querem tentar novamente imediatamente – seja para superar a sua pontuação ou melhorar a sua performance. ```mermaid stateDiagram-v2 [*] --> Playing: Início do Jogo Playing --> Victory: Todos os inimigos destruídos Playing --> Defeat: Vidas = 0 Victory --> MessageDisplay: Mostrar mensagem de vitória Defeat --> MessageDisplay: Mostrar mensagem de derrota MessageDisplay --> WaitingRestart: Pedido de premir Enter WaitingRestart --> Resetting: Tecla Enter premida Resetting --> CleanupMemory: Limpar intervalos CleanupMemory --> ClearEvents: Remover ouvintes ClearEvents --> InitializeGame: Novo início InitializeGame --> Playing: Novo jogo começa note right of MessageDisplay Feedback codificado por cores: Verde = Vitória Vermelho = Derrota end note note right of Resetting Reset completo do estado previne fugas de memória end note ``` O Tetris exemplifica isso na perfeição: quando as tuas peças chegam ao topo, podes começar instantaneamente um novo jogo sem navegar por menus complexos. Vamos construir um sistema de reinício semelhante que redefine o estado do jogo de forma limpa e faz com que os jogadores voltem rapidamente à ação. ✅ **Reflexão**: Pensa nos jogos que jogaste. Em que condições terminam e como és convidado a reiniciar? O que torna a experiência de reinício suave em vez de frustrante? ## O Que Vais Construir Irás implementar as funcionalidades finais que transformam o teu projeto numa experiência de jogo completa. Estes elementos distinguem jogos polidos de protótipos básicos. **Aqui está o que vamos adicionar hoje:** 1. **Condição de vitória**: Elimina todos os inimigos e recebe uma celebração adequada (muito merecida!) 2. **Condição de derrota**: Fica sem vidas e enfrenta a derrota com um ecrã de derrota 3. **Mecanismo de reinício**: Pressiona Enter para reiniciar imediatamente – porque um jogo nunca é suficiente 4. **Gestão de estado**: Começar de novo sempre – sem inimigos deixados para trás ou glitches estranhos do último jogo ## Começar Vamos preparar o teu ambiente de desenvolvimento. Deves ter todos os ficheiros do teu jogo espacial das lições anteriores prontos. **O teu projeto deverá parecer algo assim:** ```bash -| assets -| enemyShip.png -| player.png -| laserRed.png -| life.png -| index.html -| app.js -| package.json ``` **Inicia o servidor de desenvolvimento:** ```bash cd your-work npm start ``` **Este comando:** - Corre um servidor local em `http://localhost:5000` - Serve os teus ficheiros corretamente - Atualiza automaticamente quando fazes alterações Abre `http://localhost:5000` no teu navegador e verifica que o jogo está a correr. Deves conseguir mover, disparar e interagir com os inimigos. Após confirmado, podemos prosseguir com a implementação. > 💡 **Dica Profissional**: Para evitar avisos no Visual Studio Code, declara `gameLoopId` no topo do teu ficheiro como `let gameLoopId;` em vez de declarar dentro da função `window.onload`. Isto segue as melhores práticas modernas de declaração de variáveis em JavaScript. ```mermaid flowchart TD A["1. Seguimento de Condições"] --> B["2. Manipuladores de Eventos"] B --> C["3. Constantes de Mensagem"] C --> D["4. Controlo de Reinício"] D --> E["5. Apresentação de Mensagem"] E --> F["6. Reiniciar Sistema"] G["heroiMorto()\ninimigosMortos()"] --> A H["Eventos de Colisão\nEventos de Fim de Jogo"] --> B I["FIM_JOGO_VITORIA\nFIM_JOGO_DERROTA"] --> C J["Tecla Enter\nGatilho de Reinício"] --> D K["Vitória/Derrota\nTexto codificado por cor"] --> E L["Limpeza de Estado\nInicialização Limpa"] --> F F --> M["🎮 Jogo Completo"] style A fill:#e3f2fd style B fill:#e8f5e8 style C fill:#fff3e0 style D fill:#f3e5f5 style E fill:#e0f2f1 style F fill:#fce4ec style M fill:#e1f5fe ``` ## Passos de Implementação ### Passo 1: Criar Funções de Monitorização da Condição de Fim Precisamos de funções para monitorizar quando o jogo deve terminar. Como sensores na Estação Espacial Internacional que monitorizam constantemente sistemas críticos, estas funções irão verificar continuamente o estado do jogo. ```javascript function isHeroDead() { return hero.life <= 0; } function isEnemiesDead() { const enemies = gameObjects.filter((go) => go.type === "Enemy" && !go.dead); return enemies.length === 0; } ``` **Aqui está o que está a acontecer por trás dos panos:** - **Verifica** se o nosso herói ficou sem vidas (ai!) - **Conta** quantos inimigos ainda estão vivos e ativos - **Retorna** `true` quando o campo de batalha está livre de inimigos - **Usa** lógica simples de verdadeiro/falso para manter a simplicidade - **Filtra** através de todos os objetos do jogo para encontrar os sobreviventes ### Passo 2: Atualizar Manipuladores de Eventos para Condições de Fim Agora vamos ligar estas verificações de condição ao sistema de eventos do jogo. Sempre que ocorre uma colisão, o jogo irá avaliar se isso desencadeia uma condição de fim. Isto cria um feedback imediato para eventos críticos do jogo. ```mermaid sequenceDiagram participant Collision participant GameLogic participant Conditions participant EventSystem participant Display Collision->>GameLogic: Laser atinge inimigo GameLogic->>GameLogic: Destruir objetos GameLogic->>Conditions: Verificar isEnemiesDead() alt Todos os inimigos derrotados Conditions->>EventSystem: Emitir GAME_END_WIN EventSystem->>Display: Mostrar mensagem de vitória else Inimigos permanecem Conditions->>GameLogic: Continuar jogo end Collision->>GameLogic: Inimigo atinge herói GameLogic->>GameLogic: Diminuir vidas GameLogic->>Conditions: Verificar isHeroDead() alt Vidas = 0 Conditions->>EventSystem: Emitir GAME_END_LOSS EventSystem->>Display: Mostrar mensagem de derrota else Vidas permanecem GameLogic->>Conditions: Verificar isEnemiesDead() alt Todos os inimigos derrotados Conditions->>EventSystem: Emitir GAME_END_WIN end end ``` ```javascript eventEmitter.on(Messages.COLLISION_ENEMY_LASER, (_, { first, second }) => { first.dead = true; second.dead = true; hero.incrementPoints(); if (isEnemiesDead()) { eventEmitter.emit(Messages.GAME_END_WIN); } }); eventEmitter.on(Messages.COLLISION_ENEMY_HERO, (_, { enemy }) => { enemy.dead = true; hero.decrementLife(); if (isHeroDead()) { eventEmitter.emit(Messages.GAME_END_LOSS); return; // perda antes da vitória } if (isEnemiesDead()) { eventEmitter.emit(Messages.GAME_END_WIN); } }); eventEmitter.on(Messages.GAME_END_WIN, () => { endGame(true); }); eventEmitter.on(Messages.GAME_END_LOSS, () => { endGame(false); }); ``` **O que está a acontecer aqui:** - **Laser atinge inimigo**: Ambos desaparecem, ganhas pontos e verificamos se ganhaste - **Inimigo atinge-te**: Perdes uma vida e verificamos se ainda estás vivo - **Ordem inteligente**: Verificamos a derrota primeiro (ninguém quer ganhar e perder ao mesmo tempo!) - **Reações instantâneas**: Assim que algo importante acontece, o jogo sabe disso ### Passo 3: Adicionar Novas Constantes de Mensagem Terás de adicionar novos tipos de mensagem ao teu objeto constante `Messages`. Estas constantes ajudam a manter a consistência e evitam erros ortográficos no sistema de eventos. ```javascript GAME_END_LOSS: "GAME_END_LOSS", GAME_END_WIN: "GAME_END_WIN", ``` **No acima, nós:** - **Adicionámos** constantes para eventos de fim de jogo para manter a consistência - **Usámos** nomes descritivos que indicam claramente o propósito do evento - **Seguímos** a convenção de nomes já existente para tipos de mensagens ### Passo 4: Implementar Controlo de Reinício Agora vais adicionar controlos de teclado que permitem aos jogadores reiniciar o jogo. A tecla Enter é uma escolha natural, pois está associada a confirmar ações e iniciar novos jogos. **Adiciona deteção da tecla Enter ao teu atual listener de evento keydown:** ```javascript else if(evt.key === "Enter") { eventEmitter.emit(Messages.KEY_EVENT_ENTER); } ``` **Adiciona a nova constante de mensagem:** ```javascript KEY_EVENT_ENTER: "KEY_EVENT_ENTER", ``` **O que precisas de saber:** - **Estende** o teu sistema existente de controlo por teclado - **Usa** a tecla Enter como gatilho para reiniciar para uma experiência intuitiva - **Emite** um evento personalizado que outras partes do teu jogo podem escutar - **Mantém** o mesmo padrão das tuas outras controlos de teclado ### Passo 5: Criar o Sistema de Exibição de Mensagens O teu jogo precisa comunicar os resultados claramente aos jogadores. Vamos criar um sistema de mensagens que exibe os estados de vitória e derrota utilizando texto codificado por cores, semelhante às interfaces de terminais dos sistemas computacionais iniciais, onde verde indica sucesso e vermelho sinaliza erros. **Cria a função `displayMessage()`:** ```javascript function displayMessage(message, color = "red") { ctx.font = "30px Arial"; ctx.fillStyle = color; ctx.textAlign = "center"; ctx.fillText(message, canvas.width / 2, canvas.height / 2); } ``` **Passo a passo, isto é o que acontece:** - **Define** o tamanho e a família da fonte para um texto claro e legível - **Aplica** um parâmetro de cor com "vermelho" como padrão para avisos - **Centraliza** o texto horizontalmente e verticalmente no canvas - **Usa** parâmetros padrão modernos do JavaScript para opções de cor flexíveis - **Aproveita** o contexto 2D do canvas para renderizar texto diretamente **Cria a função `endGame()`:** ```javascript function endGame(win) { clearInterval(gameLoopId); // Definir um atraso para garantir que quaisquer renderizações pendentes sejam concluídas setTimeout(() => { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "black"; ctx.fillRect(0, 0, canvas.width, canvas.height); if (win) { displayMessage( "Victory!!! Pew Pew... - Press [Enter] to start a new game Captain Pew Pew", "green" ); } else { displayMessage( "You died !!! Press [Enter] to start a new game Captain Pew Pew" ); } }, 200) } ``` **O que esta função faz:** - **Congela** tudo no lugar – nada de navios ou lasers a mover - **Tira** uma pequena pausa (200ms) para deixar o último frame acabar de desenhar - **Limpa** o ecrã e pinta-o de preto para efeito dramático - **Mostra** mensagens diferentes para vencedores e perdedores - **Codifica as cores** da notícia – verde para bom, vermelho para… nem por isso - **Diz** aos jogadores exatamente como reiniciar ### 🔄 **Verificação Pedagógica** **Gestão do Estado do Jogo**: Antes de implementar a funcionalidade de reinício, certifica-te que entendes: - ✅ Como as condições de fim criam objetivos claros de jogo - ✅ Porque é que o feedback visual é essencial para o entendimento do jogador - ✅ A importância de limpeza adequada para evitar vazamentos de memória - ✅ Como a arquitetura orientada a eventos permite transições limpas de estado **Teste Rápido**: O que aconteceria se não limpasses os ouvintes de eventos durante o reinício? *Resposta: Vazamentos de memória e múltiplos manipuladores de evento podem causar comportamento imprevisível* **Princípios de Design de Jogos**: Agora estás a implementar: - **Objetivos Claros**: Os jogadores sabem exatamente o que define sucesso e fracasso - **Feedback Imediato**: As mudanças no estado do jogo são comunicadas imediatamente - **Controlo do Utilizador**: Os jogadores podem reiniciar quando quiserem - **Confiabilidade do Sistema**: A limpeza adequada previne bugs e problemas de performance ### Passo 6: Implementar Funcionalidade de Reset do Jogo O sistema de reset precisa limpar completamente o estado atual do jogo e inicializar uma nova sessão limpa. Isto assegura que os jogadores tenham um começo limpo sem dados remanescentes do jogo anterior. **Cria a função `resetGame()`:** ```javascript function resetGame() { if (gameLoopId) { clearInterval(gameLoopId); eventEmitter.clear(); initGame(); gameLoopId = setInterval(() => { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "black"; ctx.fillRect(0, 0, canvas.width, canvas.height); drawPoints(); drawLife(); updateGameObjects(); drawGameObjects(ctx); }, 100); } } ``` **Vamos entender cada parte:** - **Verifica** se um loop de jogo está a correr antes de reiniciar - **Limpa** o loop existente para parar toda a atividade atual do jogo - **Remove** todos os ouvintes de evento para prevenir vazamentos de memória - **Reinicializa** o estado do jogo com objetos e variáveis novos - **Inicia** um novo loop de jogo com todas as funções essenciais - **Mantém** o mesmo intervalo de 100ms para performance consistente **Adiciona o manipulador da tecla Enter à tua função `initGame()`:** ```javascript eventEmitter.on(Messages.KEY_EVENT_ENTER, () => { resetGame(); }); ``` **Adiciona o método `clear()` à tua classe EventEmitter:** ```javascript clear() { this.listeners = {}; } ``` **Pontos-chave para lembrar:** - **Liga** a tecla Enter à funcionalidade de reset do jogo - **Regista** este ouvinte de evento durante a inicialização do jogo - **Fornece** uma forma limpa de remover todos os ouvintes ao reiniciar - **Previne** vazamentos de memória ao limpar manipuladores entre jogos - **Reseta** o objeto de ouvintes para um estado vazio para nova inicialização ## Parabéns! 🎉 👽 💥 🚀 Conseguiste construir um jogo completo desde o início. Tal como os programadores que criaram os primeiros videojogos na década de 1970, transformaste linhas de código numa experiência interativa com mecânicas adequadas e feedback ao utilizador. 🚀 💥 👽 **Conseguiste:** - **Implementar** condições completas de vitória e derrota com feedback ao utilizador - **Criar** um sistema de reinício fluido para jogo contínuo - **Desenhar** comunicação visual clara para os estados do jogo - **Gerir** transições complexas de estado e limpeza - **Reunir** todos os componentes num jogo coeso e jogável ### 🔄 **Verificação Pedagógica** **Sistema Completo de Desenvolvimento de Jogos**: Celebra a tua maestria do ciclo completo de desenvolvimento: - ✅ Como as condições finais criam experiências satisfatórias para o jogador? - ✅ Porque é que a gestão adequada do estado é crítica para estabilidade do jogo? - ✅ Como o feedback visual melhora a compreensão do jogador? - ✅ Que papel tem o sistema de reinício na retenção do jogador? **Domínio do Sistema**: O teu jogo completo demonstra: - **Desenvolvimento Full-Stack de Jogos**: Desde gráficos a input e gestão de estado - **Arquitetura Profissional**: Sistemas orientados a eventos com limpeza adequada - **Design de Experiência do Utilizador**: Feedback claro e controlos intuitivos - **Otimização de Performance**: Renderização eficiente e gestão de memória - **Polimento e Completude**: Todos os detalhes que fazem um jogo parecer acabado **Competências Preparadas para a Indústria**: Implementaste: - **Arquitetura do Loop de Jogo**: Sistemas em tempo real com performance consistente - **Programação Orientada a Eventos**: Sistemas desacoplados que escalam eficazmente - **Gestão de Estado**: Manipulação complexa de dados e ciclo de vida - **Design de Interfaces**: Comunicação clara e controlos responsivos - **Testes e Debugging**: Desenvolvimento iterativo e resolução de problemas ### ⚡ **O Que Podes Fazer nos Próximos 5 Minutos** - [ ] Jogar o teu jogo completo e testar todas as condições de vitória e derrota - [ ] Experimentar diferentes parâmetros das condições finais - [ ] Tentar adicionar declarações console.log para acompanhar mudanças de estado - [ ] Partilhar o teu jogo com amigos e recolher feedback ### 🎯 **O Que Podes Alcançar Nesta Hora** - [ ] Completar o questionário pós-lição e refletir sobre a tua jornada de desenvolvimento - [ ] Adicionar efeitos áudio para estados de vitória e derrota - [ ] Implementar condições adicionais de fim, como limites de tempo ou objetivos bónus - [ ] Criar níveis de dificuldade diferentes com várias quantidades de inimigos - [ ] Polir a apresentação visual com fontes e cores melhores ### 📅 **O Teu Domínio de Desenvolvimento de Jogos em Uma Semana** - [ ] Completar o jogo espacial melhorado com vários níveis e progressão - [ ] Adicionar funcionalidades avançadas como power-ups, tipos diferentes de inimigos e armas especiais - [ ] Criar um sistema de pontuações altas com armazenamento persistente - [ ] Desenhar interfaces para menus, configurações e opções de jogo - [ ] Otimizar a performance para dispositivos e navegadores diferentes - [ ] Publicar o teu jogo online e partilhá-lo com a comunidade ### 🌟 **A Tua Carreira de Desenvolvimento de Jogos de Um Mês** - [ ] Constrói múltiplos jogos completos explorando diferentes géneros e mecânicas - [ ] Aprende frameworks avançados de desenvolvimento de jogos como Phaser ou Three.js - [ ] Contribui para projetos de desenvolvimento de jogos open source - [ ] Estuda princípios de design de jogos e psicologia do jogador - [ ] Cria um portefólio que mostra as tuas competências em desenvolvimento de jogos - [ ] Liga-te à comunidade de desenvolvimento de jogos e continua a aprender ## 🎯 O Teu Cronograma Completo de Domínio em Desenvolvimento de Jogos ```mermaid timeline title Progressão Completa de Aprendizagem do Desenvolvimento de Jogos section Fundação (Aulas 1-2) Game Architecture: Estrutura do projeto : Gestão de ativos : Noções básicas de canvas : Sistemas de eventos section Sistemas de Interação (Aulas 3-4) Player Control: Gestão de entradas : Mecânicas de movimento : Detecção de colisões : Simulação de física section Mecânicas de Jogo (Aula 5) Feedback Systems: Mecanismos de pontuação : Gestão de vidas : Comunicação visual : Motivação do jogador section Conclusão do Jogo (Aula 6) Polish & Flow: Condições de término : Gestão de estado : Sistemas de reinício : Experiência do utilizador section Funcionalidades Avançadas (1 semana) Enhancement Skills: Integração de áudio : Efeitos visuais : Progressão de níveis : Otimização de desempenho section Desenvolvimento Profissional (1 mês) Industry Readiness: Domínio do framework : Colaboração em equipa : Desenvolvimento de portfólio : Envolvimento comunitário section Avanço na Carreira (3 meses) Specialization: Motores de jogo avançados : Implantação em plataformas : Estratégias de monetização : Rede de contactos na indústria ``` ### 🛠️ Resumo Completo do Teu Kit de Ferramentas de Desenvolvimento de Jogos Após completares toda esta série de jogos espaciais, agora dominaste: - **Arquitetura de Jogos**: Sistemas orientados a eventos, ciclos de jogo e gestão de estados - **Programação Gráfica**: API Canvas, renderização de sprites e efeitos visuais - **Sistemas de Entrada**: Manipulação do teclado, deteção de colisões e controlos responsivos - **Design de Jogos**: Feedback ao jogador, sistemas de progressão e mecânicas de envolvimento - **Otimização de Performance**: Renderização eficiente, gestão de memória e controlo da taxa de frames - **Experiência do Utilizador**: Comunicação clara, controlos intuitivos e detalhes de polimento - **Padrões Profissionais**: Código limpo, técnicas de debug e organização de projetos **Aplicações no Mundo Real**: As tuas competências em desenvolvimento de jogos aplicam-se diretamente a: - **Aplicações Web Interativas**: Interfaces dinâmicas e sistemas em tempo real - **Visualização de Dados**: Gráficos animados e gráficos interativos - **Tecnologia Educacional**: Gamificação e experiências de aprendizagem envolventes - **Desenvolvimento Mobile**: Interações táctil e otimização de performance - **Software de Simulação**: Motores de física e modelação em tempo real - **Indústrias Criativas**: Arte interativa, entretenimento e experiências digitais **Competências Profissionais Adquiridas**: Agora podes: - **Arquitetar** sistemas interativos complexos desde o início - **Depurar** aplicações em tempo real usando abordagens sistemáticas - **Otimizar** a performance para experiências suaves do utilizador - **Desenhar** interfaces de utilizador envolventes e padrões de interação - **Colaborar** eficazmente em projetos técnicos com organização adequada de código **Conceitos de Desenvolvimento de Jogos Dominados**: - **Sistemas em Tempo Real**: Ciclos de jogo, gestão da taxa de frames e performance - **Arquitetura Orientada a Eventos**: Sistemas desacoplados e passagem de mensagens - **Gestão de Estado**: Manipulação complexa de dados e gestão do ciclo de vida - **Programação de Interface de Utilizador**: Gráficos Canvas e design responsivo - **Teoria do Design de Jogos**: Psicologia do jogador e mecânicas de envolvimento **Próximo Nível**: Estás pronto para explorar frameworks avançados de jogos, gráficos 3D, sistemas multijogador, ou transitar para funções profissionais de desenvolvimento de jogos! 🌟 **Conquista Desbloqueada**: Completaste uma jornada completa de desenvolvimento de jogos e construíste uma experiência interativa de qualidade profissional desde o início! **Bem-vindo à comunidade de desenvolvimento de jogos!** 🎮✨ ## Desafio do Agente GitHub Copilot 🚀 Usa o modo Agente para completares o seguinte desafio: **Descrição:** Melhora o jogo espacial implementando um sistema de progressão de níveis com dificuldade crescente e funcionalidades bónus. **Prompt:** Cria um sistema de jogo espacial multi-nível onde cada nível tem mais naves inimigas com maior velocidade e saúde. Adiciona um multiplicador de pontuação que aumenta com cada nível, e implementa power-ups (como tiro rápido ou escudo) que aparecem aleatoriamente quando inimigos são destruídos. Inclui um bónus de conclusão de nível e mostra o nível atual no ecrã juntamente com a pontuação e vidas existentes. Sabe mais sobre o [modo agente](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) aqui. ## 🚀 Desafio Opcional de Melhoria **Adiciona Áudio ao Teu Jogo**: Melhora a tua experiência de jogo implementando efeitos sonoros! Considera adicionar áudio para: - **Disparos de laser** quando o jogador atira - **Destruição de inimigos** quando as naves são atingidas - **Dano ao herói** quando o jogador sofre hits - **Música de vitória** quando o jogo é ganho - **Som de derrota** quando o jogo é perdido **Exemplo de implementação de áudio:** ```javascript // Criar objetos de áudio const laserSound = new Audio('assets/laser.wav'); const explosionSound = new Audio('assets/explosion.wav'); // Reproduzir sons durante eventos do jogo function playLaserSound() { laserSound.currentTime = 0; // Repor para o início laserSound.play(); } ``` **O que precisas de saber:** - **Cria** objetos Audio para diferentes efeitos sonoros - **Reseta** o `currentTime` para permitir efeitos sonoros de disparo rápido - **Consegue contornar** políticas de autoplay do browser acionando sons a partir de interações do utilizador - **Gere** o volume do áudio e temporização para melhor experiência de jogo > 💡 **Recurso de aprendizagem**: Explora este [sandbox de áudio](https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_audio_play) para aprender mais sobre como implementar áudio em jogos JavaScript. ## Quiz Pós-Aula [Quiz pós-aula](https://ff-quizzes.netlify.app/web/quiz/40) ## Revisão & Estudo Autónomo A tua tarefa é criar um jogo de exemplo do zero, por isso explora alguns dos jogos interessantes que existem para veres que tipo de jogo podes criar. ## Tarefa [Constrói um Jogo de Exemplo](assignment.md) --- **Aviso Legal**: Este documento foi traduzido utilizando o serviço de tradução automática [Co-op Translator](https://github.com/Azure/co-op-translator). Embora nos empenhemos em garantir a precisão, informamos que traduções automáticas podem conter erros ou imprecisões. O documento original na sua língua nativa deve ser considerado a fonte autorizada. Para informações cruciais, recomenda-se a tradução profissional por um tradutor humano. Não nos responsabilizamos por quaisquer mal-entendidos ou interpretações incorretas decorrentes da utilização desta tradução.