diff --git a/src/enemy.rs b/src/enemy.rs new file mode 100644 index 0000000..90721ae --- /dev/null +++ b/src/enemy.rs @@ -0,0 +1,27 @@ +use macroquad::prelude::*; +/// The basic enemy data +/// This condaions just he enemy position +/// and the enemy class +/// The enemy just moves towards the player constantly if there's nothing in the way. +#[derive(Debug, Default)] +pub struct Enemy { + /// The current position of the enemy + pub pos: Vec2, + /// Health of the enemy + pub health: u32, + /// Velocity of the enemy moving towards the player // This is normalized to 1 + pub velocity: Vec2, +} + +impl Enemy { + pub fn new(pos: Vec2, health: u32, velocity: Vec2) -> Self { + Self { + pos, + health, + velocity, + } + } + pub fn draw(&self) { + draw_circle(self.pos.x, self.pos.y, 16.0, RED); + } +} diff --git a/src/gun.rs b/src/gun.rs new file mode 100644 index 0000000..60b9879 --- /dev/null +++ b/src/gun.rs @@ -0,0 +1,46 @@ +use macroquad::prelude::*; + +/// The shot made by a player or an enemy +#[derive(Debug, Default)] +pub struct Bullet { + /// The position of the bullet + pos: Vec2, + /// The bullet travels at constant speed + speed: f32, + /// 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, + } + } +} diff --git a/src/main.rs b/src/main.rs index 74ae0e4..6050594 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,9 @@ #![allow(dead_code)] use macroquad::prelude::*; -use miniquad::window::screen_size; - -#[derive(Debug, Default, Clone)] -pub struct Player { - pos: Vec2, - pointing: Vec2, - velocity: Vec2, -} +mod enemy; +mod gun; +mod player; +mod world; fn window_conf() -> Conf { Conf { @@ -24,7 +20,7 @@ fn window_conf() -> Conf { #[macroquad::main(window_conf)] async fn main() { let mut cursor = Cursor::default(); - let mut world = World::new(); + let mut world = world::World::new(); loop { world.handle_inputs(); @@ -37,36 +33,6 @@ async fn main() { } } -impl Player { - pub fn new(pos: Vec2, pointing: Vec2, velocity: Vec2) -> Self { - Self { - pos, - pointing, - 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); - } - - pub fn draw(&self) { - draw_circle(self.pos.x, self.pos.y, 16.0, BLUE); - } - - pub fn move_with_velocity(&mut self) { - self.pos += self.velocity; - } -} - #[derive(Default)] pub struct Cursor { pos: Vec2, @@ -87,97 +53,3 @@ impl Cursor { ); } } - -/// The basic enemy data -/// This condaions just he enemy position -/// and the enemy class -/// The enemy just moves towards the player constantly if there's nothing in the way. -pub struct Enemy { - /// The current position of the enemy - pos: Vec2, - /// Health of the enemy - health: u32, - /// Velocity of the enemy moving towards the player // This is normalized to 1 - velocity: Vec2, -} - -impl Enemy { - pub fn new(pos: Vec2, health: u32, velocity: Vec2) -> Self { - Self { - pos, - health, - velocity, - } - } - pub fn draw(&self) { - draw_circle(self.pos.x, self.pos.y, 16.0, RED); - } -} - -/// The shot made by a player or an enemy -pub struct Bullet { - /// The position of the bullet - pos: Vec2, - /// The bullet travels at constant speed - speed: f32, - // velocity: Vec2, - damage: u32, -} - -/// The world struct -/// This contains the player, the enemies, and the center of the world -pub struct World { - player: Player, - enemies: Vec, - center: Vec2, - size: Vec2, -} - -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), - } - } - 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()); - } - - 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.player.move_with_velocity(); - 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; - } - } -} - -fn random_vec2_in_bounds(bounds: Vec2) -> Vec2 { - vec2( - rand::gen_range(0.0, bounds.x), - rand::gen_range(0.0, bounds.y), - ) -} diff --git a/src/player.rs b/src/player.rs new file mode 100644 index 0000000..4de64d3 --- /dev/null +++ b/src/player.rs @@ -0,0 +1,38 @@ +use macroquad::prelude::*; + +#[derive(Debug, Default, Clone)] +pub struct Player { + pub pos: Vec2, + pub pointing: Vec2, + pub velocity: Vec2, +} + +impl Player { + pub fn new(pos: Vec2, pointing: Vec2, velocity: Vec2) -> Self { + Self { + pos, + pointing, + 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); + } + + pub fn draw(&self) { + draw_circle(self.pos.x, self.pos.y, 16.0, BLUE); + } + + pub fn move_with_velocity(&mut self) { + self.pos += self.velocity; + } +} diff --git a/src/world.rs b/src/world.rs new file mode 100644 index 0000000..b9670f5 --- /dev/null +++ b/src/world.rs @@ -0,0 +1,77 @@ +use macroquad::prelude::*; +use miniquad::window::screen_size; + +use crate::enemy::Enemy; +use crate::gun::Bullet; +use crate::player::Player; + +/// The world struct +/// This contains the player, the enemies, and the center of the world +#[derive(Debug, Default)] +pub struct World { + player: Player, + enemies: Vec, + bullets: Vec, + center: Vec2, + size: Vec2, + tick: u64, +} + +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), + health: 100, + velocity: vec2(0., 0.), + }; + self.enemies.push(enemy); + } + + pub fn tick(&mut self) { + self.tick += 1; + self.player.move_with_velocity(); + 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)); + } + } +} + +fn random_vec2_in_bounds(bounds: Vec2) -> Vec2 { + vec2( + rand::gen_range(0.0, bounds.x), + rand::gen_range(0.0, bounds.y), + ) +}