Skip to content

Commit def2239

Browse files
committed
feat: add flappy dragon part 1
1 parent b550b33 commit def2239

File tree

2 files changed

+145
-0
lines changed

2 files changed

+145
-0
lines changed

books/hands-on-rust/flappy/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "flappy"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
bracket-lib = "~0.8.7"
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
use bracket_lib::prelude::*;
2+
3+
enum GameMode {
4+
Menu,
5+
Playing,
6+
End,
7+
}
8+
9+
const SCREEN_WIDTH: i32 = 80;
10+
const SCREEN_HEIGHT: i32 = 50;
11+
const FRAME_DURATION: f32 = 75.0;
12+
13+
struct State {
14+
player: Player,
15+
frame_time: f32,
16+
mode: GameMode,
17+
}
18+
19+
struct Player {
20+
x: i32,
21+
y: i32,
22+
velocity: f32,
23+
}
24+
25+
impl State {
26+
fn new() -> Self {
27+
State {
28+
player: Player::new(5, 25),
29+
frame_time: 0.0,
30+
mode: GameMode::Menu,
31+
}
32+
}
33+
34+
fn main_menu(&mut self, ctx: &mut BTerm) {
35+
ctx.cls();
36+
ctx.print_centered(5, "Welcome to Flappy Dragon");
37+
ctx.print_centered(8, "(P) Play Game");
38+
ctx.print_centered(9, "(Q) Quit Game");
39+
40+
if let Some(key) = ctx.key {
41+
match key {
42+
VirtualKeyCode::P => self.restart(),
43+
VirtualKeyCode::Q => ctx.quitting = true,
44+
_ => {}
45+
}
46+
}
47+
}
48+
49+
fn dead(&mut self, ctx: &mut BTerm) {
50+
ctx.cls();
51+
ctx.print_centered(5, "You are dead!");
52+
ctx.print_centered(8, "(P) Play Again");
53+
ctx.print_centered(9, "(Q) Quit Game");
54+
55+
if let Some(key) = ctx.key {
56+
match key {
57+
VirtualKeyCode::P => self.restart(),
58+
VirtualKeyCode::Q => ctx.quitting = true,
59+
_ => {}
60+
}
61+
}
62+
}
63+
64+
fn restart(&mut self) {
65+
self.player = Player::new(5, 25);
66+
self.frame_time = 0.0;
67+
self.mode = GameMode::Playing;
68+
}
69+
70+
fn play(&mut self, ctx: &mut BTerm) {
71+
ctx.cls_bg(NAVY);
72+
self.frame_time += ctx.frame_time_ms;
73+
if self.frame_time > FRAME_DURATION {
74+
self.frame_time = 0.0;
75+
self.player.gravity_and_move();
76+
}
77+
if let Some(VirtualKeyCode::Space) = ctx.key {
78+
self.player.flap();
79+
}
80+
self.player.render(ctx);
81+
ctx.print(0, 0, "Press SPACE to flap.");
82+
if self.player.y > SCREEN_HEIGHT {
83+
self.mode = GameMode::End;
84+
}
85+
}
86+
}
87+
88+
impl GameState for State {
89+
fn tick(&mut self, ctx: &mut BTerm) {
90+
match self.mode {
91+
GameMode::Menu => self.main_menu(ctx),
92+
GameMode::End => self.dead(ctx),
93+
GameMode::Playing => self.play(ctx),
94+
}
95+
}
96+
}
97+
98+
impl Player {
99+
fn new(x: i32, y: i32) -> Self {
100+
Player {
101+
x,
102+
y,
103+
velocity: 0.0,
104+
}
105+
}
106+
107+
fn render(&mut self, ctx: &mut BTerm) {
108+
ctx.set(
109+
0,
110+
self.y,
111+
YELLOW,
112+
BLACK,
113+
to_cp437('@')
114+
);
115+
}
116+
117+
fn gravity_and_move(&mut self) {
118+
if self.velocity < 2.0 {
119+
self.velocity += 0.2;
120+
}
121+
self.y += self.velocity as i32;
122+
self.x += 1;
123+
if self.y < 0 {
124+
self.y = 0;
125+
}
126+
}
127+
128+
fn flap(&mut self) {
129+
self.velocity -= 2.0;
130+
}
131+
}
132+
133+
fn main() -> BError {
134+
let context = BTermBuilder::simple80x50()
135+
.with_title("Flappy Dragon")
136+
.build()?;
137+
main_loop(context, State::new())
138+
}

0 commit comments

Comments
 (0)