diff --git a/src/draw.rs b/src/draw.rs new file mode 100644 index 0000000..4c43a2c --- /dev/null +++ b/src/draw.rs @@ -0,0 +1,35 @@ +pub trait Drawable { + fn draw(&self); +} + +impl Drawable for Box { + fn draw(&self) { + self.as_ref().draw(); + } +} + +impl Drawable for Vec { + fn draw(&self) { + self.iter().for_each(|item| item.draw()); + } +} + +impl Drawable for Option { + fn draw(&self) { + if let Some(item) = self { + item.draw(); + } + } +} + +impl Drawable for &T { + fn draw(&self) { + (*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 new file mode 100644 index 0000000..d216d60 --- /dev/null +++ b/src/ecs.rs @@ -0,0 +1,30 @@ +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/gun.rs b/src/gun.rs index 60b9879..6bcba0f 100644 --- a/src/gun.rs +++ b/src/gun.rs @@ -1,46 +1,36 @@ use macroquad::prelude::*; +use crate::movement::*; + /// The shot made by a player or an enemy -#[derive(Debug, Default)] +#[derive(Debug, Clone, Copy)] pub struct Bullet { - /// The position of the bullet - pos: Vec2, - /// The bullet travels at constant speed - speed: f32, + movement: Movement, /// The damage the bullet does damage: u32, - /// Source of the bullet - source: Vec2, } impl Bullet { - pub fn new(pos: Vec2, speed: f32, damage: u32, source: Vec2) -> Self { - Self { - pos, - speed, - damage, - source, - } - } - pub fn draw(&self) { - draw_circle(self.pos.x, self.pos.y, 4.0, GREEN); - } - - /// Every tick the bullet moves in the direction it was shot from source by speed - pub fn tick(&mut self) { - self.pos += self.source.normalize() * self.speed; - } - - /// Spawns a bullet to the mouse position from source - pub fn shoot(source: Vec2) -> Self { - let mouse = mouse_position(); - let mouse = vec2(mouse.0, mouse.1); - Self { - pos: (source - mouse).normalize(), - speed: 10.0, - damage: 10, - source, - } + draw_circle(self.movement.pos.x, self.movement.pos.y, 4.0, GREEN); + } +} + +pub struct Gun { + pub direction: Vec2, + pub bullets: Vec, +} + +impl Gun { + pub fn shoot(&mut self, pos: Vec2) { + let bullet = Bullet { + movement: Movement { + pos, + direction: self.direction, + type_: MovementType::Speed(5.0), + }, + damage: 10, + }; + self.bullets.push(bullet); } } diff --git a/src/main.rs b/src/main.rs index 6050594..075c3c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,9 @@ mod enemy; mod gun; mod player; mod world; +mod movement; +mod ecs; +mod draw; fn window_conf() -> Conf { Conf { diff --git a/src/movement.rs b/src/movement.rs new file mode 100644 index 0000000..f626585 --- /dev/null +++ b/src/movement.rs @@ -0,0 +1,31 @@ +use macroquad::prelude::*; +#[derive(Debug, Clone, Copy)] +pub enum MovementType { + Speed(f32), + Acceleration(Vec2), +} + +#[derive(Debug, Clone, Copy)] +pub struct Movement { + pub pos: Vec2, + pub direction: Vec2, // Direction of the movement normalized to 1 + pub type_: MovementType, +} + +impl Movement { + pub 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 + } +} diff --git a/src/player.rs b/src/player.rs index 4de64d3..9bf4f08 100644 --- a/src/player.rs +++ b/src/player.rs @@ -4,35 +4,36 @@ use macroquad::prelude::*; pub struct Player { pub pos: Vec2, pub pointing: Vec2, + pub direction: Vec2, pub velocity: Vec2, } impl Player { - pub fn new(pos: Vec2, pointing: Vec2, velocity: Vec2) -> Self { + pub fn new(pos: Vec2, velocity: Vec2) -> Self { + let mouse_pos = mouse_position(); + let pointing = vec2(mouse_pos.0, mouse_pos.1); + let direction = (pos - pointing).normalize(); Self { pos, pointing, + direction, velocity, } } pub fn handle_inputs(&mut self) { - self.handle_mouse(); - let distance = self.pos.distance(self.pointing); - // increase the velocity scaled to the distance - self.velocity = (self.pointing - self.pos).normalize() * distance / 15f32; - } - - pub fn handle_mouse(&mut self) { let mouse_pos = mouse_position(); self.pointing = vec2(mouse_pos.0, mouse_pos.1); + self.direction = (self.pos - self.pointing).normalize(); + let distance = self.pos.distance(self.pointing); + self.velocity = self.direction * distance / 15f32; } pub fn draw(&self) { draw_circle(self.pos.x, self.pos.y, 16.0, BLUE); } - pub fn move_with_velocity(&mut self) { + pub fn tick(&mut self) { self.pos += self.velocity; } } diff --git a/src/world.rs b/src/world.rs index b9670f5..205501d 100644 --- a/src/world.rs +++ b/src/world.rs @@ -1,6 +1,7 @@ use macroquad::prelude::*; use miniquad::window::screen_size; +use crate::ecs::Entity; use crate::enemy::Enemy; use crate::gun::Bullet; use crate::player::Player; @@ -10,36 +11,21 @@ use crate::player::Player; #[derive(Debug, Default)] pub struct World { player: Player, - enemies: Vec, - bullets: Vec, center: Vec2, size: Vec2, tick: u64, + entities: Vec, } impl World { pub fn new() -> Self { let (x, y) = screen_size(); let center = vec2(x / 2., y / 2.); - - Self { - player: Player::new(center, center, center), - enemies: Vec::default(), - center, - size: vec2(x, y), - ..Default::default() - } } pub fn handle_inputs(&mut self) { self.player.handle_inputs(); } - pub fn draw(&self) { - self.player.draw(); - self.enemies.iter().for_each(|enemy| enemy.draw()); - self.bullets.iter().for_each(|bullet| bullet.draw()); - } - pub fn spawn_enemy(&mut self) { let enemy = Enemy { pos: random_vec2_in_bounds(self.size), @@ -51,7 +37,7 @@ impl World { pub fn tick(&mut self) { self.tick += 1; - self.player.move_with_velocity(); + 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(); @@ -61,10 +47,10 @@ impl World { enemy.pos += enemy.velocity; } for bullet in self.bullets.iter_mut() { - bullet.tick(); + // bullet.tick(); } if self.tick % 12 == 0 { - self.bullets.push(Bullet::shoot(self.player.pos)); + // self.bullets.push(Bullet::shoot(self.player.pos)); } } }