From 80da680532d8e245cc6c364127b73edfa58cd76a Mon Sep 17 00:00:00 2001 From: Thilo Behnke Date: Sun, 24 Apr 2022 20:05:22 +0200 Subject: [PATCH] wip - issues with trait bounds --- pong/src/collision.rs | 4 +- pong/src/game_field.rs | 108 +++++++++++++++++++--------------------- pong/src/game_object.rs | 71 +++++++++++++++++++------- 3 files changed, 107 insertions(+), 76 deletions(-) diff --git a/pong/src/collision.rs b/pong/src/collision.rs index c839198..ffceae1 100644 --- a/pong/src/collision.rs +++ b/pong/src/collision.rs @@ -10,7 +10,7 @@ pub mod collision { CollisionDetector {} } - pub fn detect_collisions(&self, objs: Vec<&GameObject>) -> Box { + pub fn detect_collisions(&self, objs: Vec<&dyn GameObject>) -> Box { if objs.is_empty() { return Box::new(Collisions::new(vec![])); } @@ -74,7 +74,7 @@ pub mod collision { pub fn new() -> CollisionHandler { CollisionHandler {} } - pub fn handle(&self, obj_a: &mut GameObject, obj_b: &GameObject) { + pub fn handle(&self, obj_a: &mut dyn GameObject, obj_b: &dyn GameObject) { if !obj_a.is_static { obj_a.vel.reflect(&obj_b.orientation); if obj_b.vel != Vector::zero() { diff --git a/pong/src/game_field.rs b/pong/src/game_field.rs index 1efbdd0..e26c667 100644 --- a/pong/src/game_field.rs +++ b/pong/src/game_field.rs @@ -1,6 +1,8 @@ use crate::collision::collision::{Collision, CollisionDetector, CollisionHandler, CollisionRegistry, Collisions}; -use crate::game_object::game_object::{GameObject, ShapeType}; +use crate::game_object::components::{DefaultGeomComp, DefaultPhysicsComp}; +use crate::game_object::game_object::GameObject; use crate::geom::geom::Vector; +use crate::geom::shape::{Circle, Rect}; use crate::utils::utils::{Logger, NoopLogger}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -161,49 +163,51 @@ impl Field { #[derive(Clone, Debug, PartialEq)] pub struct Player { - pub obj: GameObject, + pub obj: Box, } impl Player { pub fn new(id: u16, x: u16, y: u16, field: &Field) -> Player { Player { - obj: GameObject { + obj: GameObject::new( id, - pos: Vector {x: x as f64, y: y as f64}, - orientation: Vector::new(0., 1.), - shape: ShapeType::Rect, - shape_params: vec![field.width / 25, field.height / 5], - vel: Vector::zero(), - is_static: true, - }, + Box::new(DefaultGeomComp::new( + Box::new(Rect::new(Vector { x: x as f64, y: y as f64 }, Vector::new(0., 1.), (field.width as f64) / 25, (field.height as f64) / 5)) + )), + Box::new(DefaultPhysicsComp::new( + Vector::zero(), + true + )) + ) } } } #[derive(Clone, Debug, PartialEq)] pub struct Ball { - pub obj: GameObject, + pub obj: Box, } impl Ball { pub fn new(id: u16, x: u16, y: u16, field: &Field) -> Ball { Ball { - obj: GameObject { + obj: GameObject::new( id, - pos: Vector {x: x as f64, y: y as f64}, - orientation: Vector::zero(), - shape: ShapeType::Circle, - shape_params: vec![field.width / 80], - vel: Vector::zero(), - is_static: false, - }, + Box::new(DefaultGeomComp::new( + Box::new(Circle::new(Vector { x: x as f64, y: y as f64 }, Vector::zero(), (field.width as f64) / 80) + ))), + Box::new(DefaultPhysicsComp::new( + Vector::zero(), + false + )) + ) } } } #[derive(Debug)] pub struct Bounds { - pub objs: Vec, + pub objs: Vec>, } impl Bounds { @@ -211,45 +215,37 @@ impl Bounds { Bounds { objs: vec![ // top - GameObject { - id: 90, - pos: Vector {x: (width / 2) as f64, y: 0 as f64}, - orientation: Vector::new(1., 0.), - shape: ShapeType::Rect, - shape_params: vec![width, 2], - is_static: true, - vel: Vector::zero(), - }, + GameObject::new( + 90, + Box::new(DefaultGeomComp::new( + Box::new(Rect::new(Vector {x: (width / 2) as f64, y: 0 as f64}, Vector::new(1., 0.), width as f64, 2.) + ))), + Box::new(DefaultPhysicsComp::new_static()) + ), // bottom - GameObject { - id: 91, - pos: Vector {x: (width / 2) as f64, y: height as f64}, - orientation: Vector::new(-1., 0.), - shape: ShapeType::Rect, - shape_params: vec![width, 2], - is_static: true, - vel: Vector::zero(), - }, + GameObject::new( + 91, + Box::new(DefaultGeomComp::new( + Box::new(Rect::new(Vector {x: (width / 2) as f64, y: height as f64}, Vector::new(-1., 0.), width as f64, 2.) + ))), + Box::new(DefaultPhysicsComp::new_static()) + ), // left - GameObject { - id: 92, - pos: Vector {x: 0 as f64, y: (height / 2) as f64}, - orientation: Vector::new(0., 1.), - shape: ShapeType::Rect, - shape_params: vec![2, height], - is_static: true, - vel: Vector::zero(), - }, + GameObject::new( + 92, + Box::new(DefaultGeomComp::new( + Box::new(Rect::new(Vector {x: 0 as f64, y: (height / 2) as f64}, Vector::new(0., 1.), 2., height as f64) + ))), + Box::new(DefaultPhysicsComp::new_static()) + ), // right - GameObject { - id: 93, - pos: Vector {x: width as f64, y: (height / 2) as f64}, - orientation: Vector::new(0., -1.), - shape: ShapeType::Rect, - shape_params: vec![2, height], - is_static: true, - vel: Vector::zero(), - }, + GameObject::new( + 93, + Box::new(DefaultGeomComp::new( + Box::new(Rect::new(Vector {x: width as f64, y: (height / 2) as f64}, Vector::new(0., -1.), 2., height as f64) + ))), + Box::new(DefaultPhysicsComp::new_static()) + ) ], } } diff --git a/pong/src/game_object.rs b/pong/src/game_object.rs index 4454d20..270216a 100644 --- a/pong/src/game_object.rs +++ b/pong/src/game_object.rs @@ -1,47 +1,68 @@ pub mod game_object { + use std::fmt::Debug; use crate::game_object::components::{GeomComp, PhysicsComp}; use crate::geom::geom::{BoundingBox, Vector}; use crate::geom::shape::ShapeType; - #[derive(Clone, Debug, PartialEq)] - pub struct GameObject { - pub id: u16, - pub geom: Box, - pub physics: Box + pub trait GameObject { + fn update_pos(&mut self); + fn vel(&self) -> &Vector; + fn set_vel_x(&mut self, x: f64); + fn set_vel_y(&mut self, y: f64); + fn bounding_box(&self) -> BoundingBox; } - impl GameObject { - pub fn update_pos(&mut self) { + #[derive(Clone, Debug, PartialEq)] + pub struct DefaultGameObject { + pub id: u16, + geom: Box, + physics: Box + } + + impl DefaultGameObject { + pub fn new(id: u16, geom: Box, physics: Box) -> DefaultGameObject { + DefaultGameObject {id, geom, physics} + } + } + + impl GameObject for DefaultGameObject { + fn update_pos(&mut self) { + let vel = self.vel(); let center = self.geom.center_mut(); - center.add(&self.vel); + center.add(vel); // Keep last orientation if vel is now zero. - let vel = self.physics.vel(); - if vel == Vector::zero() { + if *vel == Vector::zero() { return; } - let mut orientation = vel.clone(); - orientation.normalize(); - self.orientation = orientation; + let mut updated_orientation = vel.clone(); + updated_orientation.normalize(); + let orientation = self.geom.orientation_mut(); + orientation.x = updated_orientation.x; + orientation.y = updated_orientation.y; } - pub fn set_vel_x(&mut self, x: f64) { + fn vel(&self) -> &Vector { + &self.physics.vel() + } + + fn set_vel_x(&mut self, x: f64) { let vel = self.physics.vel_mut(); vel.x = x; } - pub fn set_vel_y(&mut self, y: f64) { + fn set_vel_y(&mut self, y: f64) { let vel = self.physics.vel_mut(); vel.y = y; } - pub fn bounding_box(&self) -> BoundingBox { - self.geom.shape().bounding_box() + fn bounding_box(&self) -> BoundingBox { + self.geom.bounding_box() } } } pub mod components { - use crate::geom::geom::Vector; + use crate::geom::geom::{BoundingBox, Vector}; use crate::geom::shape::Shape; pub trait GeomComp { @@ -49,16 +70,19 @@ pub mod components { fn orientation_mut(&mut self) -> &mut Vector; fn center(&self) -> &Vector; fn center_mut(&mut self) -> &mut Vector; + fn bounding_box(&self) -> BoundingBox; } pub struct DefaultGeomComp { shape: Box } + impl DefaultGeomComp { pub fn new(shape: Box) -> DefaultGeomComp { DefaultGeomComp {shape} } } + impl GeomComp for DefaultGeomComp { fn orientation(&self) -> &Vector { &self.shape.orientation() @@ -75,6 +99,10 @@ pub mod components { fn center_mut(&mut self) -> &mut Vector { &mut self.shape.center() } + + fn bounding_box(&self) -> BoundingBox { + self.bounding_box() + } } pub trait PhysicsComp { @@ -91,6 +119,13 @@ pub mod components { pub fn new(vel: Vector, is_static: bool) -> DefaultPhysicsComp { DefaultPhysicsComp {vel, is_static} } + + pub fn new_static() -> DefaultPhysicsComp { + DefaultPhysicsComp::new( + Vector::zero(), + true + ) + } } impl PhysicsComp for DefaultPhysicsComp { fn vel(&self) -> &Vector {