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!

  1. Crie o arquivo jogo_completo.cpp na pasta src/:
#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

  1. Abra le terminal integrado.
  2. Compile: g++ jogo_completo.cpp -o jogo_completo
  3. 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.


Capitulo Anterior