From f04bb2a419816e942a3f8b236790b653b8de0e6c Mon Sep 17 00:00:00 2001 From: uttarayan21 Date: Wed, 19 Jun 2024 22:18:29 +0530 Subject: [PATCH] fix: Fix compilation and make tick and drawable traits --- src/draw.rs | 6 ---- src/ecs.rs | 30 ----------------- src/enemy.rs | 11 +++++- src/entity.rs | 89 +++++++++++++++++++++++++++++++++++++++++++++++++ src/gun.rs | 19 +++++++---- src/main.rs | 6 ++-- src/movement.rs | 23 +++++++++++-- src/player.rs | 27 +++++++++++---- src/tick.rs | 23 +++++++++++++ src/world.rs | 75 ++++++++++++++++++++--------------------- 10 files changed, 216 insertions(+), 93 deletions(-) delete mode 100644 src/ecs.rs create mode 100644 src/entity.rs create mode 100644 src/tick.rs diff --git a/src/draw.rs b/src/draw.rs index 4c43a2c..ed6e72e 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -27,9 +27,3 @@ impl Drawable for &T { (*self).draw(); } } - -// impl> Drawable for I { -// fn draw(&self) { -// self.for_each(|item| item.draw()); -// } -// } diff --git a/src/ecs.rs b/src/ecs.rs deleted file mode 100644 index d216d60..0000000 --- a/src/ecs.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::{draw::Drawable, enemy::Enemy, gun::Bullet, player::Player}; - -pub enum Entity { - Player(Player), - Enemies(Enemy), - Bullet(Bullet), - Custom(Box), -} - -impl core::fmt::Debug for Entity { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - Entity::Player(player) => write!(f, "Entity::Player({:?})", player), - Entity::Enemies(enemy) => write!(f, "Entity::Enemies({:?})", enemy), - Entity::Bullet(bullet) => write!(f, "Entity::Bullet({:?})", bullet), - Entity::Custom(_) => write!(f, "Entity::Custom(...)"), - } - } -} - -impl Drawable for Entity { - fn draw(&self) { - match self { - Entity::Player(player) => player.draw(), - Entity::Enemies(enemy) => enemy.draw(), - Entity::Bullet(bullet) => bullet.draw(), - Entity::Custom(drawable) => drawable.draw(), - } - } -} diff --git a/src/enemy.rs b/src/enemy.rs index 90721ae..db543f8 100644 --- a/src/enemy.rs +++ b/src/enemy.rs @@ -1,4 +1,6 @@ use macroquad::prelude::*; + +use crate::draw::Drawable; /// The basic enemy data /// This condaions just he enemy position /// and the enemy class @@ -21,7 +23,14 @@ impl Enemy { velocity, } } - pub fn draw(&self) { + + fn draw(&self) { draw_circle(self.pos.x, self.pos.y, 16.0, RED); } } + +impl Drawable for Enemy { + fn draw(&self) { + self.draw(); + } +} diff --git a/src/entity.rs b/src/entity.rs new file mode 100644 index 0000000..8925902 --- /dev/null +++ b/src/entity.rs @@ -0,0 +1,89 @@ +use crate::{draw::Drawable, enemy::Enemy, gun::Bullet, player::Player, tick::Tick}; + +pub trait EntityTrait { + fn as_tick(&mut self) -> &mut dyn Tick; + fn as_draw(&self) -> &dyn Drawable; +} + +impl EntityTrait for T { + fn as_tick(&mut self) -> &mut dyn Tick { + self + } + + fn as_draw(&self) -> &dyn Drawable { + self + } +} + +impl Drawable for Box { + fn draw(&self) { + self.as_draw().draw(); + } +} + +impl Tick for Box { + fn tick(&mut self) { + self.as_tick().tick(); + } +} + +// impl EntityTrait for Entity { +// fn as_tick(&mut self) -> &mut dyn Tick { +// match self { +// Entity::Player(player) => player, +// Entity::Enemies(enemy) => enemy, +// Entity::Bullet(bullet) => bullet, +// Entity::Custom(entity) => entity.as_tick(), +// } +// } +// +// fn as_draw(&self) -> &dyn Drawable { +// match self { +// Entity::Player(player) => player, +// Entity::Enemies(enemy) => enemy, +// Entity::Bullet(bullet) => bullet, +// Entity::Custom(entity) => entity.as_draw(), +// } +// } +// } + +pub enum Entity { + Player(Player), + Enemies(Enemy), + Bullet(Bullet), + Custom(Box), +} + +impl core::fmt::Debug for Entity { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Entity::Player(player) => write!(f, "Entity::Player({:?})", player), + Entity::Enemies(enemy) => write!(f, "Entity::Enemies({:?})", enemy), + Entity::Bullet(bullet) => write!(f, "Entity::Bullet({:?})", bullet), + Entity::Custom(_) => write!(f, "Entity::Custom(...)"), + } + } +} + +impl Drawable for Entity { + fn draw(&self) { + match self { + Entity::Player(player) => player.draw(), + Entity::Enemies(enemy) => enemy.draw(), + Entity::Bullet(bullet) => bullet.draw(), + Entity::Custom(drawable) => drawable.draw(), + } + } +} + +impl Tick for Entity { + fn tick(&mut self) { + match self { + Entity::Player(player) => player.tick(), + // Entity::Enemies(enemy) => enemy.tick(), + // Entity::Bullet(bullet) => bullet.tick(), + Entity::Custom(tick) => tick.tick(), + _ => (), + } + } +} diff --git a/src/gun.rs b/src/gun.rs index 6bcba0f..63e4b56 100644 --- a/src/gun.rs +++ b/src/gun.rs @@ -16,21 +16,28 @@ impl Bullet { } } +pub enum GunType { + ShotGun, + Pistol, + Sniper, +} + +/// This is basically an abstraction of a bullet_factory lets say pub struct Gun { + pub damage: u32, pub direction: Vec2, - pub bullets: Vec, + pub type_: GunType, } impl Gun { - pub fn shoot(&mut self, pos: Vec2) { - let bullet = Bullet { + pub fn shoot(&mut self, pos: Vec2) -> Bullet { + Bullet { movement: Movement { pos, direction: self.direction, type_: MovementType::Speed(5.0), }, - damage: 10, - }; - self.bullets.push(bullet); + damage: self.damage, + } } } diff --git a/src/main.rs b/src/main.rs index 075c3c3..d13509c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,14 @@ #![allow(dead_code)] +use draw::Drawable as _; +use tick::Tick as _; use macroquad::prelude::*; mod enemy; mod gun; mod player; mod world; mod movement; -mod ecs; +mod entity; +mod tick; mod draw; fn window_conf() -> Conf { @@ -26,7 +29,6 @@ async fn main() { let mut world = world::World::new(); loop { - world.handle_inputs(); world.tick(); world.draw(); diff --git a/src/movement.rs b/src/movement.rs index f626585..ad97832 100644 --- a/src/movement.rs +++ b/src/movement.rs @@ -1,8 +1,19 @@ use macroquad::prelude::*; + +use crate::tick::Tick; #[derive(Debug, Clone, Copy)] pub enum MovementType { Speed(f32), - Acceleration(Vec2), + Acceleration(f32), +} + +impl MovementType { + const FAST: Self = Self::Speed(5.0); + const MEDIUM: Self = Self::Speed(3.0); + const SLOW: Self = Self::Speed(1.0); + const STOP: Self = Self::Speed(0.0); + const FASTER: Self = Self::Acceleration(1.0); + const SLOWER: Self = Self::Acceleration(-1.0); } #[derive(Debug, Clone, Copy)] @@ -13,19 +24,25 @@ pub struct Movement { } impl Movement { - pub fn tick(&mut self) { + fn tick(&mut self) { match self.type_ { MovementType::Speed(speed) => { self.pos += self.direction * speed; } MovementType::Acceleration(acceleration) => { self.direction += acceleration; - self.direction = self.direction.normalize(); self.pos += self.direction; } } } + pub fn pos(&self) -> Vec2 { self.pos } } + +impl Tick for Movement { + fn tick(&mut self) { + self.tick(); + } +} diff --git a/src/player.rs b/src/player.rs index 9bf4f08..18f2da9 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,5 +1,7 @@ use macroquad::prelude::*; +use crate::{draw::Drawable, tick::Tick}; + #[derive(Debug, Default, Clone)] pub struct Player { pub pos: Vec2, @@ -9,7 +11,7 @@ pub struct Player { } impl Player { - pub fn new(pos: Vec2, velocity: Vec2) -> Self { + pub fn new(pos: Vec2) -> Self { let mouse_pos = mouse_position(); let pointing = vec2(mouse_pos.0, mouse_pos.1); let direction = (pos - pointing).normalize(); @@ -17,23 +19,36 @@ impl Player { pos, pointing, direction, - velocity, + velocity: vec2(0.0, 0.0), } } - pub fn handle_inputs(&mut self) { + fn handle_inputs(&mut self) { let mouse_pos = mouse_position(); self.pointing = vec2(mouse_pos.0, mouse_pos.1); - self.direction = (self.pos - self.pointing).normalize(); + self.direction = (self.pointing - self.pos).normalize(); let distance = self.pos.distance(self.pointing); self.velocity = self.direction * distance / 15f32; } - pub fn draw(&self) { + fn draw(&self) { draw_circle(self.pos.x, self.pos.y, 16.0, BLUE); } - pub fn tick(&mut self) { + fn tick(&mut self) { self.pos += self.velocity; } } + +impl Drawable for Player { + fn draw(&self) { + self.draw(); + } +} + +impl Tick for Player { + fn tick(&mut self) { + self.handle_inputs(); + self.tick(); + } +} diff --git a/src/tick.rs b/src/tick.rs new file mode 100644 index 0000000..9f97a2f --- /dev/null +++ b/src/tick.rs @@ -0,0 +1,23 @@ +pub trait Tick { + fn tick(&mut self); +} + +impl Tick for Box { + fn tick(&mut self) { + self.as_mut().tick(); + } +} + +impl Tick for Vec { + fn tick(&mut self) { + self.iter_mut().for_each(|item| item.tick()); + } +} + +impl Tick for Option { + fn tick(&mut self) { + if let Some(item) = self { + item.tick(); + } + } +} diff --git a/src/world.rs b/src/world.rs index 205501d..b62c00d 100644 --- a/src/world.rs +++ b/src/world.rs @@ -1,10 +1,10 @@ +use macroquad::miniquad::window::screen_size; use macroquad::prelude::*; -use miniquad::window::screen_size; -use crate::ecs::Entity; -use crate::enemy::Enemy; -use crate::gun::Bullet; +use crate::draw::Drawable; +use crate::entity::Entity; use crate::player::Player; +use crate::tick::Tick; /// The world struct /// This contains the player, the enemies, and the center of the world @@ -15,49 +15,46 @@ pub struct World { size: Vec2, tick: u64, entities: Vec, + frame_time: f32, // The rolling average frame time for the last 5 frames } impl World { pub fn new() -> Self { - let (x, y) = screen_size(); - let center = vec2(x / 2., y / 2.); - } - pub fn handle_inputs(&mut self) { - self.player.handle_inputs(); + let size = screen_size(); + let size = vec2(size.0, size.1); + let center = size / 2.0; + Self { + player: Player::new(center), + center, + size, + ..Default::default() + } } - pub fn spawn_enemy(&mut self) { - let enemy = Enemy { - pos: random_vec2_in_bounds(self.size), - health: 100, - velocity: vec2(0., 0.), - }; - self.enemies.push(enemy); - } - - pub fn tick(&mut self) { - self.tick += 1; + fn tick(&mut self) { self.player.tick(); - let enemies_count = self.enemies.len(); - if enemies_count < 10 && (macroquad::time::get_time() / (2 * enemies_count) as f64) > 1.0 { - self.spawn_enemy(); - } - for enemy in self.enemies.iter_mut() { - enemy.velocity = (self.player.pos - enemy.pos).normalize(); - enemy.pos += enemy.velocity; - } - for bullet in self.bullets.iter_mut() { - // bullet.tick(); - } - if self.tick % 12 == 0 { - // self.bullets.push(Bullet::shoot(self.player.pos)); - } + self.entities.tick(); + } + + // fn next_frame(&mut self) { + // let current_frame_time = get_frame_time(); + // if self.frame_time == 0.0 { + // self.frame_time = current_frame_time; + // } else { + // self.frame_time = (self.frame_time * 4.0 + current_frame_time) / 5.0; + // } + // } +} + +impl Drawable for World { + fn draw(&self) { + self.player.draw(); + self.entities.draw(); } } -fn random_vec2_in_bounds(bounds: Vec2) -> Vec2 { - vec2( - rand::gen_range(0.0, bounds.x), - rand::gen_range(0.0, bounds.y), - ) +impl Tick for World { + fn tick(&mut self) { + self.tick() + } }