使用Rust開發(fā)小游戲完成過程
本文是對 使用 Rust 開發(fā)一個微型游戲【已完結(jié)】
cargo new flappy
在Cargo.toml的[dependencies]
下方增加:
bracket-lib = "~0.8.7"
main.rs中:
use bracket_lib::prelude::*; struct State {} impl GameState for State { fn tick(&mut self, ctx: &mut BTerm) { ctx.cls(); ctx.print(1, 1, "Hello,Bracket Terminal!"); } } fn main() -> BError { let context: BTerm = BTermBuilder::simple80x50() .with_title("爽哥做游戲--Flappy Dragon") .build()?; main_loop(context, State {}) }
cargo run后,可以看到
use bracket_lib::prelude::*; // 游戲3種模式(菜單,游戲中,結(jié)束) enum GameMode { Menu, Playing, End, } struct State { mode: GameMode, } impl State { fn new() -> Self { State { mode: GameMode::Menu, } } fn play(&mut self, ctx: &mut BTerm) { //TODO self.mode = GameMode::End; } fn restart(&mut self) { self.mode = GameMode::Playing; } fn main_menu(&mut self, ctx: &mut BTerm) { ctx.cls(); ctx.print_centered(5, "歡迎來到游戲~"); ctx.print_centered(8, "Press P key to start Game"); ctx.print_centered(9, "Press Q to quit Game"); if let Some(key) = ctx.key { match key { VirtualKeyCode::P => self.restart(), VirtualKeyCode::Q => ctx.quitting = true, _ => {} } {} } } fn dead(&mut self, ctx: &mut BTerm) { ctx.cls(); ctx.print_centered(5, "你掛了.."); ctx.print_centered(8, "按P鍵 再來一局"); ctx.print_centered(9, "按Q鍵 退出游戲"); if let Some(key) = ctx.key { match key { VirtualKeyCode::P => self.restart(), VirtualKeyCode::Q => ctx.quitting = true, _ => {} } {} } } } impl GameState for State { fn tick(&mut self, ctx: &mut BTerm) { match self.mode { GameMode::Menu => self.main_menu(ctx), GameMode::End => self.dead(ctx), GameMode::Playing => self.play(ctx), } // ctx.cls(); // ctx.print(1, 1, "Hello,Bracket Terminal!"); } } fn main() -> BError { let context: BTerm = BTermBuilder::simple80x50() .with_title("爽哥做游戲--Flappy Dragon") .build()?; main_loop(context, State::new()) }
增加玩家
use bracket_lib::prelude::*; // 游戲3種模式(菜單,游戲中,結(jié)束) enum GameMode { Menu, Playing, End, } const SCREEN_WIDTH: i32 = 80; const SCREEN_HEIGHT: i32 = 50; const FRAME_DURATION: f32 = 75.0; struct Player { x: i32, y: i32, velocity: f32, } impl Player { fn new(x: i32, y: i32) -> Self { Player { x: 0, y: 0, velocity: 0.0, } } fn render(&mut self, ctx: &mut BTerm) { ctx.set(0, self.y, YELLOW, BLACK, to_cp437('@')); } fn gravity_and_move(&mut self) { if self.velocity < 2.0 { self.velocity += 0.2; } self.y += self.velocity as i32; self.x += 1; if self.y < 0 { self.y = 0; } } fn flap(&mut self) { self.velocity = -2.0; } } struct State { player: Player, frame_time: f32, mode: GameMode, } impl State { fn new() -> Self { State { player: Player::new(5, 25), frame_time: 0.0, mode: GameMode::Menu, } } fn play(&mut self, ctx: &mut BTerm) { ctx.cls_bg(NAVY); self.frame_time += ctx.frame_time_ms; if self.frame_time >= FRAME_DURATION { self.player.gravity_and_move(); self.frame_time = 0.0; } // 按空格 if let Some(VirtualKeyCode::Space) = ctx.key { self.player.flap(); } self.player.render(ctx); ctx.print(0, 0, "按空格起飛~"); if self.player.y > SCREEN_HEIGHT { self.mode = GameMode::End; } } fn restart(&mut self) { self.player = Player::new(5, 25); self.frame_time = 0.0; self.mode = GameMode::Playing; } fn main_menu(&mut self, ctx: &mut BTerm) { ctx.cls(); ctx.print_centered(5, "歡迎來到游戲~"); ctx.print_centered(8, "Press P key to start Game"); ctx.print_centered(9, "Press Q to quit Game"); if let Some(key) = ctx.key { match key { VirtualKeyCode::P => self.restart(), VirtualKeyCode::Q => ctx.quitting = true, _ => {} } {} } } fn dead(&mut self, ctx: &mut BTerm) { ctx.cls(); ctx.print_centered(5, "你掛了.."); ctx.print_centered(8, "按P鍵 再來一局"); ctx.print_centered(9, "按Q鍵 退出游戲"); if let Some(key) = ctx.key { match key { VirtualKeyCode::P => self.restart(), VirtualKeyCode::Q => ctx.quitting = true, _ => {} } {} } } } impl GameState for State { fn tick(&mut self, ctx: &mut BTerm) { match self.mode { GameMode::Menu => self.main_menu(ctx), GameMode::End => self.dead(ctx), GameMode::Playing => self.play(ctx), } // ctx.cls(); // ctx.print(1, 1, "Hello,Bracket Terminal!"); } } fn main() -> BError { let context: BTerm = BTermBuilder::simple80x50() .with_title("爽哥做游戲--Flappy Dragon") .build()?; main_loop(context, State::new()) }
增加障礙
use std::fmt::format; use bracket_lib::prelude::*; // 游戲3種模式(菜單,游戲中,結(jié)束) enum GameMode { Menu, Playing, End, } const SCREEN_WIDTH: i32 = 80; const SCREEN_HEIGHT: i32 = 50; const FRAME_DURATION: f32 = 75.0; struct Player { x: i32, y: i32, velocity: f32, } impl Player { fn new(x: i32, y: i32) -> Self { Player { x: 0, y: 0, velocity: 0.0, } } fn render(&mut self, ctx: &mut BTerm) { ctx.set(0, self.y, YELLOW, BLACK, to_cp437('@')); } fn gravity_and_move(&mut self) { if self.velocity < 2.0 { self.velocity += 0.2; } self.y += self.velocity as i32; self.x += 1; if self.y < 0 { self.y = 0; } } fn flap(&mut self) { self.velocity = -2.0; } } struct State { player: Player, frame_time: f32, mode: GameMode, obstacle: Obstacle, score: i32, } impl State { fn new() -> Self { State { player: Player::new(5, 25), frame_time: 0.0, mode: GameMode::Menu, obstacle: Obstacle::new(SCREEN_WIDTH, 0), score: 0, } } fn play(&mut self, ctx: &mut BTerm) { ctx.cls_bg(NAVY); self.frame_time += ctx.frame_time_ms; if self.frame_time >= FRAME_DURATION { self.player.gravity_and_move(); self.frame_time = 0.0; } // 按空格 if let Some(VirtualKeyCode::Space) = ctx.key { self.player.flap(); } self.player.render(ctx); ctx.print(0, 0, "按空格起飛~"); // 障礙物&積分 // 實時打印分數(shù) ctx.print(0, 1, &format!("Score: {}", self.score)); self.obstacle.render(ctx, self.player.x); if self.player.x > self.obstacle.x { self.score += 1; // 分數(shù)+1 self.obstacle = Obstacle::new(self.player.x + SCREEN_WIDTH, self.score); } if self.player.y > SCREEN_HEIGHT || self.obstacle.hit_obstacle(&self.player) { self.mode = GameMode::End; } } fn restart(&mut self) { self.player = Player::new(5, 25); self.frame_time = 0.0; self.mode = GameMode::Playing; // 重置分數(shù)和障礙物 self.obstacle = Obstacle::new(SCREEN_WIDTH, 0); self.score = 0; } fn main_menu(&mut self, ctx: &mut BTerm) { ctx.cls(); ctx.print_centered(5, "歡迎來到游戲~"); ctx.print_centered(8, "Press P key to start Game"); ctx.print_centered(9, "Press Q to quit Game"); if let Some(key) = ctx.key { match key { VirtualKeyCode::P => self.restart(), VirtualKeyCode::Q => ctx.quitting = true, _ => {} } {} } } fn dead(&mut self, ctx: &mut BTerm) { ctx.cls(); ctx.print_centered(5, "你掛了.."); // 掛了后顯示一下分數(shù) ctx.print_centered(6, &format!("本局獲得了 {} 分", self.score)); ctx.print_centered(8, "按P鍵 再來一局"); ctx.print_centered(9, "按Q鍵 退出游戲"); if let Some(key) = ctx.key { match key { VirtualKeyCode::P => self.restart(), VirtualKeyCode::Q => ctx.quitting = true, _ => {} } {} } } } impl GameState for State { fn tick(&mut self, ctx: &mut BTerm) { match self.mode { GameMode::Menu => self.main_menu(ctx), GameMode::End => self.dead(ctx), GameMode::Playing => self.play(ctx), } } } struct Obstacle { x: i32, gap_y: i32, size: i32, } impl Obstacle { fn new(x: i32, score: i32) -> Self { let mut random: RandomNumberGenerator = RandomNumberGenerator::new(); Obstacle { x, gap_y: random.range(10, 40), size: i32::max(2, 20 - score), } } fn render(&mut self, ctx: &mut BTerm, player_x: i32) { let screen_x = self.x - player_x; let half_size = self.size / 2; for y in 0..self.gap_y - half_size { ctx.set(screen_x, y, RED, BLACK, to_cp437('|')); } for y in self.gap_y + half_size..SCREEN_HEIGHT { ctx.set(screen_x, y, RED, BLACK, to_cp437('|')); } } fn hit_obstacle(&self, player: &Player) -> bool { let half_size = self.size / 2; let does_x_match = player.x == self.x; let player_above_gap = player.y < self.gap_y - half_size; let player_below_gap = player.y > self.gap_y + half_size; does_x_match && (player_above_gap || player_below_gap) } } fn main() -> BError { let context: BTerm = BTermBuilder::simple80x50() .with_title("爽哥做游戲--Flappy Dragon") .build()?; main_loop(context, State::new()) }
參考資料[1]
使用 Rust 開發(fā)一個微型游戲【已完結(jié)】: https://www.bilibili.com/video/BV1vM411J74S
到此這篇關(guān)于使用Rust開發(fā)小游戲的文章就介紹到這了,更多相關(guān)Rust開發(fā)小游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust 連接 SQLite 數(shù)據(jù)庫的過程解析
本文通過一個例子給大家介紹了Rust 連接 SQLite 數(shù)據(jù)庫的詳細過程,我使用rusqlite這個crate,對Rust 連接 SQLite 數(shù)據(jù)庫相關(guān)知識感興趣的朋友跟隨小編一起看看吧2022-01-01深入探究在Rust中函數(shù)、方法和關(guān)聯(lián)函數(shù)有什么區(qū)別
在 Rust 中,函數(shù)、方法和關(guān)聯(lián)函數(shù)都是用來封裝行為的,它們之間的區(qū)別主要在于它們的定義和調(diào)用方式,本文將通過一個簡單的rust代碼示例來給大家講講Rust中函數(shù)、方法和關(guān)聯(lián)函數(shù)區(qū)別,需要的朋友可以參考下2023-08-08