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 Rust!
📖 O Loop Principal
Para o jogo funcionar continuamente, precisamos de um loop que só pare quando o jogador vencer ou decidir sair. No Rust, o laço loop é perfeito para isso!
📖 Exemplo Guiado: O Jogo Completo em Rust
Vamos completar o código do capítulo anterior adicionando o controle de movimento (W, A, S, D) e as regras do jogo.
- Crie o arquivo
jogo_completo.rsna pastasrc/:
use std::io;
const TAM: usize = 5;
struct Jogador {
x: usize,
y: usize,
tem_chave: bool,
}
impl Jogador {
fn new() -> Jogador {
Jogador { x: 0, y: 0, tem_chave: false }
}
fn mover(&mut self, comando: &str) {
match comando {
"w" | "W" => if self.y > 0 { self.y -= 1; },
"s" | "S" => if self.y < TAM - 1 { self.y += 1; },
"a" | "A" => if self.x > 0 { self.x -= 1; },
"d" | "D" => if self.x < TAM - 1 { self.x += 1; },
_ => println!("Comando invalido!"),
}
}
}
struct Mapa {
grade: [[i32; TAM]; TAM],
}
impl Mapa {
fn new() -> Mapa {
Mapa {
grade: [
[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]
]
}
}
fn desenhar(&self, j: &Jogador) {
println!("\n--- DUNGEON ---");
for i in 0..TAM {
for k in 0..TAM {
if i == j.y && k == j.x {
print!("[L] ");
} else if self.grade[i][k] == 2 {
print!("[K] ");
} else if self.grade[i][k] == 3 {
print!("[D] ");
} else {
print!("[.] ");
}
}
println!();
}
}
}
fn main() {
let mut link = Jogador::new();
let mut mapa = Mapa::new();
let mut jogando = true;
println!("Bem-vindo ao Zelda Dungeon Crawler em Rust!");
println!("Controles: W (Cima), S (Baixo), A (Esquerda), D (Direita), Q (Sair)");
while jogando {
mapa.desenhar(&link);
println!("Comando: ");
let mut comando = String::new();
io::stdin().read_line(&mut comando).unwrap();
let comando = comando.trim();
if comando == "q" || comando == "Q" {
println!("Voce desistiu da jornada.");
break;
}
link.mover(comando);
// Regra 1: Pegar a chave
if mapa.grade[link.y][link.x] == 2 {
println!("\n🔑 Voce encontrou a Chave da Masmorra!");
link.tem_chave = 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.tem_chave {
println!("\n🏆 Parabens! Voce abriu a porta e escapou!");
jogando = false;
} else {
println!("\n⛔ A porta esta trancada! Voce precisa da chave.");
}
}
}
}🕹️ Como Executar e Testar no VS Code
- Abra le terminal integrado.
- Compile:
rustc jogo_completo.rs - 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!
🔑 Gabarito de Código
Prática 1: Fragmento com o Monstro
// Adicione a verificação no loop principal:
if mapa.grade[link.y][link.x] == 4 {
println!("\n💀 Voce foi pego por um monstro! GAME OVER.");
jogando = false;
}📤 Instruções de Entrega (GitHub Desktop + Microsoft Teams)
(Siga o padrão estabelecido no Guia)
Parabéns por concluir o curso de Rust! Você agora domina a linguagem mais segura e moderna do mundo.