fix: Fix compilation and make tick and drawable traits

This commit is contained in:
uttarayan21
2024-06-19 22:18:29 +05:30
parent 39c1096b87
commit f04bb2a419
10 changed files with 216 additions and 93 deletions
-6
View File
@@ -27,9 +27,3 @@ impl<T: Drawable> Drawable for &T {
(*self).draw(); (*self).draw();
} }
} }
// impl<T: Drawable, I: Iterator<Item = T>> Drawable for I {
// fn draw(&self) {
// self.for_each(|item| item.draw());
// }
// }
-30
View File
@@ -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<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(),
}
}
}
+10 -1
View File
@@ -1,4 +1,6 @@
use macroquad::prelude::*; use macroquad::prelude::*;
use crate::draw::Drawable;
/// The basic enemy data /// The basic enemy data
/// This condaions just he enemy position /// This condaions just he enemy position
/// and the enemy class /// and the enemy class
@@ -21,7 +23,14 @@ impl Enemy {
velocity, velocity,
} }
} }
pub fn draw(&self) {
fn draw(&self) {
draw_circle(self.pos.x, self.pos.y, 16.0, RED); draw_circle(self.pos.x, self.pos.y, 16.0, RED);
} }
} }
impl Drawable for Enemy {
fn draw(&self) {
self.draw();
}
}
+89
View File
@@ -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<T: Tick + Drawable> EntityTrait for T {
fn as_tick(&mut self) -> &mut dyn Tick {
self
}
fn as_draw(&self) -> &dyn Drawable {
self
}
}
impl Drawable for Box<dyn EntityTrait> {
fn draw(&self) {
self.as_draw().draw();
}
}
impl Tick for Box<dyn EntityTrait> {
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<dyn EntityTrait>),
}
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(),
_ => (),
}
}
}
+13 -6
View File
@@ -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 struct Gun {
pub damage: u32,
pub direction: Vec2, pub direction: Vec2,
pub bullets: Vec<Bullet>, pub type_: GunType,
} }
impl Gun { impl Gun {
pub fn shoot(&mut self, pos: Vec2) { pub fn shoot(&mut self, pos: Vec2) -> Bullet {
let bullet = Bullet { Bullet {
movement: Movement { movement: Movement {
pos, pos,
direction: self.direction, direction: self.direction,
type_: MovementType::Speed(5.0), type_: MovementType::Speed(5.0),
}, },
damage: 10, damage: self.damage,
}; }
self.bullets.push(bullet);
} }
} }
+4 -2
View File
@@ -1,11 +1,14 @@
#![allow(dead_code)] #![allow(dead_code)]
use draw::Drawable as _;
use tick::Tick as _;
use macroquad::prelude::*; use macroquad::prelude::*;
mod enemy; mod enemy;
mod gun; mod gun;
mod player; mod player;
mod world; mod world;
mod movement; mod movement;
mod ecs; mod entity;
mod tick;
mod draw; mod draw;
fn window_conf() -> Conf { fn window_conf() -> Conf {
@@ -26,7 +29,6 @@ async fn main() {
let mut world = world::World::new(); let mut world = world::World::new();
loop { loop {
world.handle_inputs();
world.tick(); world.tick();
world.draw(); world.draw();
+20 -3
View File
@@ -1,8 +1,19 @@
use macroquad::prelude::*; use macroquad::prelude::*;
use crate::tick::Tick;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum MovementType { pub enum MovementType {
Speed(f32), 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)] #[derive(Debug, Clone, Copy)]
@@ -13,19 +24,25 @@ pub struct Movement {
} }
impl Movement { impl Movement {
pub fn tick(&mut self) { fn tick(&mut self) {
match self.type_ { match self.type_ {
MovementType::Speed(speed) => { MovementType::Speed(speed) => {
self.pos += self.direction * speed; self.pos += self.direction * speed;
} }
MovementType::Acceleration(acceleration) => { MovementType::Acceleration(acceleration) => {
self.direction += acceleration; self.direction += acceleration;
self.direction = self.direction.normalize();
self.pos += self.direction; self.pos += self.direction;
} }
} }
} }
pub fn pos(&self) -> Vec2 { pub fn pos(&self) -> Vec2 {
self.pos self.pos
} }
} }
impl Tick for Movement {
fn tick(&mut self) {
self.tick();
}
}
+21 -6
View File
@@ -1,5 +1,7 @@
use macroquad::prelude::*; use macroquad::prelude::*;
use crate::{draw::Drawable, tick::Tick};
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct Player { pub struct Player {
pub pos: Vec2, pub pos: Vec2,
@@ -9,7 +11,7 @@ pub struct Player {
} }
impl Player { impl Player {
pub fn new(pos: Vec2, velocity: Vec2) -> Self { pub fn new(pos: Vec2) -> Self {
let mouse_pos = mouse_position(); let mouse_pos = mouse_position();
let pointing = vec2(mouse_pos.0, mouse_pos.1); let pointing = vec2(mouse_pos.0, mouse_pos.1);
let direction = (pos - pointing).normalize(); let direction = (pos - pointing).normalize();
@@ -17,23 +19,36 @@ impl Player {
pos, pos,
pointing, pointing,
direction, direction,
velocity, velocity: vec2(0.0, 0.0),
} }
} }
pub fn handle_inputs(&mut self) { fn handle_inputs(&mut self) {
let mouse_pos = mouse_position(); let mouse_pos = mouse_position();
self.pointing = vec2(mouse_pos.0, mouse_pos.1); 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); let distance = self.pos.distance(self.pointing);
self.velocity = self.direction * distance / 15f32; self.velocity = self.direction * distance / 15f32;
} }
pub fn draw(&self) { fn draw(&self) {
draw_circle(self.pos.x, self.pos.y, 16.0, BLUE); draw_circle(self.pos.x, self.pos.y, 16.0, BLUE);
} }
pub fn tick(&mut self) { fn tick(&mut self) {
self.pos += self.velocity; 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();
}
}
+23
View File
@@ -0,0 +1,23 @@
pub trait Tick {
fn tick(&mut self);
}
impl<T: Tick> Tick for Box<T> {
fn tick(&mut self) {
self.as_mut().tick();
}
}
impl<T: Tick> Tick for Vec<T> {
fn tick(&mut self) {
self.iter_mut().for_each(|item| item.tick());
}
}
impl<T: Tick> Tick for Option<T> {
fn tick(&mut self) {
if let Some(item) = self {
item.tick();
}
}
}
+34 -37
View File
@@ -1,10 +1,10 @@
use macroquad::miniquad::window::screen_size;
use macroquad::prelude::*; use macroquad::prelude::*;
use miniquad::window::screen_size;
use crate::ecs::Entity; use crate::draw::Drawable;
use crate::enemy::Enemy; use crate::entity::Entity;
use crate::gun::Bullet;
use crate::player::Player; use crate::player::Player;
use crate::tick::Tick;
/// The world struct /// The world struct
/// This contains the player, the enemies, and the center of the world /// This contains the player, the enemies, and the center of the world
@@ -15,49 +15,46 @@ pub struct World {
size: Vec2, size: Vec2,
tick: u64, tick: u64,
entities: Vec<Entity>, entities: Vec<Entity>,
frame_time: f32, // The rolling average frame time for the last 5 frames
} }
impl World { impl World {
pub fn new() -> Self { pub fn new() -> Self {
let (x, y) = screen_size(); let size = screen_size();
let center = vec2(x / 2., y / 2.); let size = vec2(size.0, size.1);
let center = size / 2.0;
Self {
player: Player::new(center),
center,
size,
..Default::default()
} }
pub fn handle_inputs(&mut self) {
self.player.handle_inputs();
} }
pub fn spawn_enemy(&mut self) { fn tick(&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.tick(); self.player.tick();
let enemies_count = self.enemies.len(); self.entities.tick();
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 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 { impl Tick for World {
vec2( fn tick(&mut self) {
rand::gen_range(0.0, bounds.x), self.tick()
rand::gen_range(0.0, bounds.y), }
)
} }