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#!


📖 O Loop Principal

Para o jogo funcionar continuamente, precisamos de um loop que só pare quando o jogador vencer ou decidir sair. Usaremos o laço while(true) para isso!


📖 Exemplo Guiado: O Jogo Completo em C#

Vamos completar o código do capítulo anterior adicionando o controle de movimento (W, A, S, D) e as regras do jogo.

  1. Crie o arquivo jogo_completo.cs na pasta src/:
using System;
 
// Código principal
int TAM = 5;
Jogador link = new Jogador(0, 0);
Mapa mapa = new Mapa(TAM);
mapa.Grade[1, 1] = 2; // Chave
mapa.Grade[4, 4] = 3; // Porta
 
bool jogando = true;
 
Console.WriteLine("Bem-vindo ao Zelda Dungeon Crawler em C#!");
Console.WriteLine("Controles: W (Cima), S (Baixo), A (Esquerda), D (Direita), Q (Sair)");
 
while (jogando) {
    mapa.Desenhar(link);
    
    Console.Write("Comando: ");
    string comando = Console.ReadLine();
 
    if (comando.ToLower() == "q") {
        Console.WriteLine("Voce desistiu da jornada.");
        break;
    }
 
    link.Mover(comando, TAM);
 
    // Regra 1: Pegar a chave
    if (mapa.Grade[link.Y, link.X] == 2) {
        Console.WriteLine("\n🔑 Voce encontrou a Chave da Masmorra!");
        link.TemChave = true;
        mapa.Grade[link.Y, link.X] = 0; // Remove a chave do mapa
    }
 
    // Regra 2: Chegar na porta
    if (mapa.Grade[link.Y, link.X] == 3) {
        if (link.TemChave) {
            Console.WriteLine("\n🏆 Parabens! Voce abriu a porta e escapou!");
            jogando = false;
        } else {
            Console.WriteLine("\n⛔ A porta esta trancada! Voce precisa da chave.");
        }
    }
}
 
public class Jogador {
    public int X { get; set; }
    public int Y { get; set; }
    public bool TemChave { get; set; }
 
    public Jogador(int x, int y) {
        X = x;
        Y = y;
        TemChave = false;
    }
 
    public void Mover(string comando, int tam) {
        switch (comando.ToLower()) {
            case "w": if (Y > 0) Y--; break;
            case "s": if (Y < tam - 1) Y++; break;
            case "a": if (X > 0) X--; break;
            case "d": if (X < tam - 1) X++; break;
            default: Console.WriteLine("Comando invalido!"); break;
        }
    }
}
 
public class Mapa {
    public int[,] Grade { get; set; }
    public int Tamanho { get; set; }
 
    public Mapa(int tamanho) {
        Tamanho = tamanho;
        Grade = new int[tamanho, tamanho];
    }
 
    public void Desenhar(Jogador j) {
        Console.WriteLine("\n--- DUNGEON ---");
        for (int i = 0; i < Tamanho; i++) {
            for (int k = 0; k < Tamanho; k++) {
                if (i == j.Y && k == j.X) {
                    Console.Write("[L] ");
                } else if (Grade[i, k] == 2) {
                    Console.Write("[K] ");
                } else if (Grade[i, k] == 3) {
                    Console.Write("[D] ");
                } else {
                    Console.Write("[. ] ");
                }
            }
            Console.WriteLine();
        }
    }
}

🕹️ Como Executar e Testar no VS Code

  1. Execute o projeto usando dotnet run.

📊 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[TemChave = 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!


🔑 Gabarito de Código

Prática 1: Fragmento com o Monstro

using System;
 
int TAM = 5;
Jogador link = new Jogador(0, 0);
Mapa mapa = new Mapa(TAM);
mapa.Grade[1, 1] = 2; // Chave
mapa.Grade[4, 4] = 3; // Porta
mapa.Grade[2, 2] = 4; // Monstro!
 
bool jogando = true;
 
while (jogando) {
    mapa.Desenhar(link);
    Console.Write("Comando: ");
    string comando = Console.ReadLine();
 
    link.Mover(comando, TAM);
 
    if (mapa.Grade[link.Y, link.X] == 2) {
        Console.WriteLine("\n🔑 Voce encontrou a Chave!");
        link.TemChave = true;
        mapa.Grade[link.Y, link.X] = 0;
    }
 
    if (mapa.Grade[link.Y, link.X] == 3) {
        if (link.TemChave) {
            Console.WriteLine("\n🏆 Vitoria!");
            jogando = false;
        } else {
            Console.WriteLine("\n⛔ Trancado!");
        }
    }
 
    if (mapa.Grade[link.Y, link.X] == 4) {
        Console.WriteLine("\n💀 Voce foi pego por um monstro! GAME OVER.");
        jogando = false;
    }
}
 
public class Jogador {
    public int X { get; set; }
    public int Y { get; set; }
    public bool TemChave { get; set; }
    public Jogador(int x, int y) { X = x; Y = y; }
    public void Mover(string comando, int tam) {
        switch (comando.ToLower()) {
            case "w": if (Y > 0) Y--; break;
            case "s": if (Y < tam - 1) Y++; break;
            case "a": if (X > 0) X--; break;
            case "d": if (X < tam - 1) X++; break;
        }
    }
}
 
public class Mapa {
    public int[,] Grade { get; set; }
    public int Tamanho { get; set; }
    public Mapa(int tamanho) { Tamanho = tamanho; Grade = new int[tamanho, tamanho]; }
    public void Desenhar(Jogador j) {
        for (int i = 0; i < Tamanho; i++) {
            for (int k = 0; k < Tamanho; k++) {
                if (i == j.Y && k == j.X) Console.Write("[L] ");
                else if (Grade[i, k] == 2) Console.Write("[K] ");
                else if (Grade[i, k] == 3) Console.Write("[D] ");
                else if (Grade[i, k] == 4) Console.Write("[M] ");
                else Console.Write("[. ] ");
            }
            Console.WriteLine();
        }
    }
}

Parabéns por concluir o curso de C#! Você agora domina uma das linguagens mais poderosas do mercado.


Capitulo Anterior