Capítulo 20: Projeto Final - Dungeon Crawler (Parte 2) 🎮🏆
Chegou o grande momento! Vamos implementar o loop principal de movimento, a coleta da chave e a condição de vitória para finalizar o nosso jogo e o curso de C++! Usaremos tudo o que aprendemos sobre Objetos e Classes.
📖 O Loop Principal
Para o jogo funcionar continuamente, precisamos de um loop while que só pare quando o jogador vencer ou decidir sair.
📖 Exemplo Guiado: O Jogo Completo
Vamos completar o código do capítulo anterior adicionando o controle de movimento (W, A, S, D) e as regras do jogo dentro das classes!
- Crie o arquivo
jogo_completo.cppna pastasrc/:
#include <iostream>
#include <vector>
using namespace std;
#define TAM 5
class Jogador {
private:
int x, y;
bool tem_chave;
public:
Jogador() {
x = 0;
y = 0;
tem_chave = false;
}
int get_x() { return x; }
int get_y() { return y; }
bool get_chave() { return tem_chave; }
void set_chave(bool valor) { tem_chave = valor; }
void mover(char comando) {
if ((comando == 'w' || comando == 'W') && y > 0) y--;
else if ((comando == 's' || comando == 'S') && y < TAM - 1) y++;
else if ((comando == 'a' || comando == 'A') && x > 0) x--;
else if ((comando == 'd' || comando == 'D') && x < TAM - 1) x++;
}
};
class Mapa {
private:
int grade[TAM][TAM];
public:
Mapa() {
int inicial[TAM][TAM] = {
{0, 0, 0, 0, 0},
{0, 2, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 3}
};
for(int i=0; i<TAM; i++)
for(int j=0; j<TAM; j++)
grade[i][j] = inicial[i][j];
}
void desenhar(Jogador j) {
cout << "\n--- DUNGEON ---" << endl;
for (int i = 0; i < TAM; i++) {
for (int k = 0; k < TAM; k++) {
if (i == j.get_y() && k == j.get_x()) {
cout << "[L] ";
} else if (grade[i][k] == 2) {
cout << "[K] ";
} else if (grade[i][k] == 3) {
cout << "[D] ";
} else {
cout << "[.] ";
}
}
cout << endl;
}
}
int get_item(int x, int y) { return grade[x][y]; }
void remover_item(int x, int y) { grade[x][y] = 0; }
};
int main() {
Mapa meu_mapa;
Jogador link;
char comando;
bool jogando = true;
cout << "Bem-vindo ao Zelda Dungeon Crawler em C++!" << endl;
cout << "Controles: W (Cima), S (Baixo), A (Esquerda), D (Direita), Q (Sair)" << endl;
while (jogando) {
meu_mapa.desenhar(link);
cout << "Comando: ";
cin >> comando;
if (comando == 'q' || comando == 'Q') {
cout << "Voce desistiu da jornada." << endl;
break;
}
link.mover(comando);
// Regra 1: Pegar a chave
if (meu_mapa.get_item(link.get_y(), link.get_x()) == 2) {
cout << endl << "🔑 Voce encontrou a Chave da Masmorra!" << endl;
link.set_chave(true);
meu_mapa.remover_item(link.get_y(), link.get_x());
}
// Regra 2: Chegar na porta
if (meu_mapa.get_item(link.get_y(), link.get_x()) == 3) {
if (link.get_chave()) {
cout << endl << "🏆 Parabens! Voce abriu a porta e escapou!" << endl;
jogando = false;
} else {
cout << endl << "⛔ A porta esta trancada! Voce precisa da chave." << endl;
}
}
}
return 0;
}🕹️ Como Executar e Testar no VS Code
- Abra le terminal integrado.
- Compile:
g++ jogo_completo.cpp -o jogo_completo - Execute:
./jogo_completo
📊 Ilustração Visual: Fluxo de Regras
Veja as verificações feitas a cada passo:
graph TD A[Nova Posição] --> B{"É a Chave?"} B -->|Sim| C[tem_chave = true] B -->|Não| D{"É a Porta?"} C --> D D -->|Sim| E{"Tem Chave?"} E -->|Sim| F[Vitória!] E -->|Não| G[Mensagem: Trancada] D -->|Não| H[Continua]
🛠️ Prática Obrigatória 1: Adicionando um Monstro
Adicione um monstro no mapa (valor 4 na matriz, pode ser o símbolo [M]). Se o Link pisar na mesma posição do monstro, ele perde o jogo! (Dica: use métodos das classes para gerenciar isso).
🔑 Gabarito de Código
Prática 1: Fragmento com o Monstro
// Adicione a verificação no loop principal:
if (meu_mapa.get_item(link.get_y(), link.get_x()) == 4) {
cout << endl << "💀 Voce foi pego por um monstro! GAME OVER." << endl;
jogando = false;
}📤 Instruções de Entrega (GitHub Desktop + Microsoft Teams)
(Siga o padrão estabelecido no Guia)
Parabéns por concluir o curso de C++! Você agora domina a base da programação orientada a objetos.