🚚 Moved dragon and obstacle to their own modules

The book implementation had everything in one file, probably for not introducing too many concepts in the same chapter.
This looks much nicer and opens the door to a bit of customizing of the program
main
Pau Costa Ferrer 2023-11-02 10:45:22 +01:00
parent 4f87e79324
commit dbbe26a855
3 changed files with 107 additions and 95 deletions

44
src/dragon.rs Normal file
View File

@ -0,0 +1,44 @@
use bracket_lib::prelude::*;
pub struct Dragon {
pub x: i32,
pub y: i32,
velocity: f32,
}
impl Dragon{
pub fn new(x: i32, y: i32)-> Self {
Dragon{
x,
y,
velocity: 0.0,
}
}
pub fn render(&mut self, ctx: &mut BTerm){
ctx.set(
0,
self. y,
YELLOW,
BLACK,
to_cp437('@')
);
}
pub 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;
}
}
pub fn flap(&mut self){
self.velocity = - 2.0;
}
}

View File

@ -1,5 +1,10 @@
pub mod obstacle;
pub mod dragon;
use bracket_lib::prelude::*; use bracket_lib::prelude::*;
use dragon::Dragon;
use obstacle::Obstacle;
enum GameMode { enum GameMode {
Menu, Menu,
@ -11,106 +16,12 @@ const SCREEN_WIDTH : i32 = 80;
const SCREEN_HEIGHT : i32 = 50; const SCREEN_HEIGHT : i32 = 50;
const FRAME_DURATION : f32 = 75.0; const FRAME_DURATION : f32 = 75.0;
struct Obstacle {
x: i32,
gap_y: i32,
size: i32
}
impl Obstacle{
fn new(x: i32, score: i32) -> Self{
let mut random = 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;
// Draw the top half of the obstacle
for y in 0..self.gap_y - half_size{
ctx.set(
screen_x,
y,
RED,
BLACK,
to_cp437('|'),
);
}
// Draw the bottom half of the obstacle
for y in self.gap_y + half_size..SCREEN_HEIGHT{
ctx.set(
screen_x,
y,
RED,
BLACK,
to_cp437('|')
)
}
}
fn hit_obstacle(&self, player: &Dragon) -> 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_below_gap || player_above_gap)
}
}
struct Dragon {
x: i32,
y: i32,
velocity: f32,
}
impl Dragon{
fn new(x: i32, y: i32)-> Self {
Dragon{
x,
y,
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{ struct State{
mode: GameMode, mode: GameMode,
player: Dragon, player: Dragon,
frame_time: f32, frame_time: f32,
score: i32, score: i32,
obstacle: Obstacle, obstacle: obstacle::Obstacle,
} }
impl State{ impl State{

57
src/obstacle.rs Normal file
View File

@ -0,0 +1,57 @@
use bracket_lib::prelude::*;
use crate::Dragon;
pub struct Obstacle {
pub x: i32,
gap_y: i32,
size: i32
}
impl Obstacle{
pub fn new(x: i32, score: i32) -> Self{
let mut random = RandomNumberGenerator::new();
Obstacle {
x,
gap_y: random.range(10, 40),
size: i32::max(2, 20 - score)
}
}
pub fn render(&mut self, ctx: &mut BTerm, player_x : i32){
let screen_x = self.x - player_x;
let half_size = self.size / 2;
// Draw the top half of the obstacle
for y in 0..self.gap_y - half_size{
ctx.set(
screen_x,
y,
RED,
BLACK,
to_cp437('|'),
);
}
// Draw the bottom half of the obstacle
for y in self.gap_y + half_size..crate::SCREEN_HEIGHT{
ctx.set(
screen_x,
y,
RED,
BLACK,
to_cp437('|')
)
}
}
pub fn hit_obstacle(&self, player: &Dragon) -> 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_below_gap || player_above_gap)
}
}