feat: restructure draw and movement
This commit is contained in:
+35
@@ -0,0 +1,35 @@
|
||||
pub trait Drawable {
|
||||
fn draw(&self);
|
||||
}
|
||||
|
||||
impl<T: Drawable> Drawable for Box<T> {
|
||||
fn draw(&self) {
|
||||
self.as_ref().draw();
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Drawable> Drawable for Vec<T> {
|
||||
fn draw(&self) {
|
||||
self.iter().for_each(|item| item.draw());
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Drawable> Drawable for Option<T> {
|
||||
fn draw(&self) {
|
||||
if let Some(item) = self {
|
||||
item.draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Drawable> Drawable for &T {
|
||||
fn draw(&self) {
|
||||
(*self).draw();
|
||||
}
|
||||
}
|
||||
|
||||
// impl<T: Drawable, I: Iterator<Item = T>> Drawable for I {
|
||||
// fn draw(&self) {
|
||||
// self.for_each(|item| item.draw());
|
||||
// }
|
||||
// }
|
||||
+30
@@ -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<dyn Drawable>),
|
||||
}
|
||||
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
-34
@@ -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<Bullet>,
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ mod enemy;
|
||||
mod gun;
|
||||
mod player;
|
||||
mod world;
|
||||
mod movement;
|
||||
mod ecs;
|
||||
mod draw;
|
||||
|
||||
fn window_conf() -> Conf {
|
||||
Conf {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
+10
-9
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-19
@@ -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<Enemy>,
|
||||
bullets: Vec<Bullet>,
|
||||
center: Vec2,
|
||||
size: Vec2,
|
||||
tick: u64,
|
||||
entities: Vec<Entity>,
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user