mirror of
https://github.com/thilo-behnke/wasm-pong.git
synced 2026-07-11 02:29:25 +00:00
object composition really right approach? would be much simpler to just copy the game objs if needed
This commit is contained in:
@@ -2,7 +2,7 @@ pub mod collision {
|
||||
use crate::game_object::game_object::GameObject;
|
||||
use crate::geom::geom::Vector;
|
||||
use std::alloc::handle_alloc_error;
|
||||
use std::cell::{Ref, RefCell};
|
||||
use std::cell::{Ref, RefCell, RefMut};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
use std::rc::Rc;
|
||||
@@ -78,7 +78,7 @@ pub mod collision {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CollisionHandler {
|
||||
handlers: HashMap<(String, String), fn(&mut Box<dyn GameObject>, &mut Box<dyn GameObject>)>,
|
||||
handlers: HashMap<(String, String), fn(Rc<RefCell<Box<dyn GameObject>>>, Rc<RefCell<Box<dyn GameObject>>>)>
|
||||
}
|
||||
|
||||
impl CollisionHandler {
|
||||
@@ -91,7 +91,7 @@ pub mod collision {
|
||||
pub fn register(
|
||||
&mut self,
|
||||
mapping: (String, String),
|
||||
callback: fn(&mut Box<dyn GameObject>, &mut Box<dyn GameObject>),
|
||||
callback: fn(Rc<RefCell<Box<dyn GameObject>>>, Rc<RefCell<Box<dyn GameObject>>>),
|
||||
) {
|
||||
if self.handlers.contains_key(&mapping) {
|
||||
panic!(
|
||||
@@ -104,10 +104,10 @@ pub mod collision {
|
||||
|
||||
pub fn handle(
|
||||
&self,
|
||||
obj_a: &mut Box<dyn GameObject>,
|
||||
obj_b: &mut Box<dyn GameObject>,
|
||||
obj_a: Rc<RefCell<Box<dyn GameObject>>>,
|
||||
obj_b: Rc<RefCell<Box<dyn GameObject>>>,
|
||||
) -> bool {
|
||||
let key = (obj_a.obj_type().to_string(), obj_b.obj_type().to_string());
|
||||
let key = (RefCell::borrow(&obj_a).obj_type().to_string(), RefCell::borrow(&obj_b).obj_type().to_string());
|
||||
if !self.handlers.contains_key(&key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -136,6 +136,7 @@ impl Field {
|
||||
{
|
||||
for obj in self.objs.iter() {
|
||||
let mut obj_mut = RefCell::borrow_mut(obj);
|
||||
self.logger.log("update player");
|
||||
obj_mut.update_pos();
|
||||
}
|
||||
}
|
||||
@@ -144,35 +145,12 @@ impl Field {
|
||||
|
||||
let collision_handler = self.collision_handler.clone();
|
||||
for collision in collisions.get_collisions().iter() {
|
||||
// TODO: This is fine because an obj will not collide with itself - better abstraction?
|
||||
// let idx
|
||||
// let (obj_a, obj_b) = self.objs.split_at_mut();
|
||||
// let obj_a = self.get_obj(collision.0, self.objs.borrow_mut());
|
||||
// let obj_b = self.get_obj(collision.1, self.objs.borrow_mut());
|
||||
// collision_handler.handle(obj_a, obj_b)
|
||||
let objs = &self.objs;
|
||||
let obj_a = objs.iter().find(|o| RefCell::borrow(o).id() == collision.0).unwrap().clone();
|
||||
let obj_b = objs.iter().find(|o| RefCell::borrow(o).id() == collision.1).unwrap().clone();
|
||||
self.logger.log(&*format!("Handling collision between {:?} and {:?}", obj_a, obj_b));
|
||||
collision_handler.handle(obj_a, obj_b);
|
||||
}
|
||||
//
|
||||
// for ball in self.balls.iter_mut() {
|
||||
// let collisions = self.collisions.get_collisions_by_id(ball.obj.id());
|
||||
// if collisions.is_empty() {
|
||||
// continue;
|
||||
// }
|
||||
// let other = match collisions[0] {
|
||||
// Collision(obj_a_id, obj_b_id) if *obj_a_id == ball.obj.id() => {
|
||||
// objs.iter().find(|o| o.id() == *obj_b_id).unwrap()
|
||||
// }
|
||||
// collision => objs.iter().find(|o| o.id() == collision.0).unwrap(),
|
||||
// };
|
||||
//
|
||||
// self.logger.log("### BEFORE COLLISION ###");
|
||||
// self.logger.log(&*format!("{:?}", ball.obj));
|
||||
// self.logger.log(&*format!("{:?}", other));
|
||||
// collision_handler.handle(&mut ball.obj, other);
|
||||
// self.logger.log("### AFTER COLLISION ###");
|
||||
// self.logger.log(&*format!("{:?}", ball.obj));
|
||||
// self.logger.log(&*format!("{:?}", other));
|
||||
// self.logger.log("### DONE ###");
|
||||
// }
|
||||
}
|
||||
|
||||
fn get_collisions(&self) -> Box<dyn CollisionRegistry> {
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
pub mod pong_collisions {
|
||||
use std::cell::{RefCell, RefMut};
|
||||
use std::ops::Add;
|
||||
use std::rc::Rc;
|
||||
use crate::game_object::game_object::GameObject;
|
||||
use crate::geom::geom::Vector;
|
||||
use crate::geom::shape::ShapeType;
|
||||
|
||||
pub fn handle_player_ball_collision(
|
||||
ball: &mut Box<dyn GameObject>,
|
||||
player: &mut Box<dyn GameObject>,
|
||||
ball: Rc<RefCell<Box<dyn GameObject>>>,
|
||||
player: Rc<RefCell<Box<dyn GameObject>>>,
|
||||
) {
|
||||
// reflect
|
||||
let mut ball = RefCell::borrow_mut(&ball);
|
||||
let player = player.borrow();
|
||||
ball.vel_mut().reflect(&player.orientation());
|
||||
// use vel of player obj
|
||||
if *player.vel() != Vector::zero() {
|
||||
@@ -24,16 +28,20 @@ pub mod pong_collisions {
|
||||
}
|
||||
|
||||
pub fn handle_ball_bounds_collision(
|
||||
ball: &mut Box<dyn GameObject>,
|
||||
bound: &mut Box<dyn GameObject>,
|
||||
ball: Rc<RefCell<Box<dyn GameObject>>>,
|
||||
bound: Rc<RefCell<Box<dyn GameObject>>>,
|
||||
) {
|
||||
let mut ball = RefCell::borrow_mut(&ball);
|
||||
let bound = RefCell::borrow(&bound);
|
||||
ball.vel_mut().reflect(&bound.orientation());
|
||||
}
|
||||
|
||||
pub fn handle_player_bound_collision(
|
||||
player: &mut Box<dyn GameObject>,
|
||||
bound: &mut Box<dyn GameObject>,
|
||||
player: Rc<RefCell<Box<dyn GameObject>>>,
|
||||
bound: Rc<RefCell<Box<dyn GameObject>>>,
|
||||
) {
|
||||
let mut player = RefCell::borrow_mut(&player);
|
||||
let bound = RefCell::borrow(&bound);
|
||||
let shape = player.shape().clone();
|
||||
let player_orientation = player.orientation().clone();
|
||||
let height = match shape {
|
||||
|
||||
@@ -90,6 +90,10 @@ impl GameObject for MockGameObject {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn orientation_mut(&mut self) -> &mut Vector {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn update_pos(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use rstest::rstest;
|
||||
use pong::game_field::{Bound, Field};
|
||||
use pong::game_object::game_object::{DefaultGameObject, GameObject};
|
||||
@@ -47,29 +49,29 @@ use pong::utils::utils::NoopLogger;
|
||||
get_bound(Bound::TOP)
|
||||
)]
|
||||
pub fn should_correctly_handle_player_bounds_collision(
|
||||
#[case] mut player: Box<dyn GameObject>,
|
||||
#[case] mut bounds: Box<dyn GameObject>,
|
||||
#[case] mut player_expected: Box<dyn GameObject>,
|
||||
#[case] mut bounds_expected: Box<dyn GameObject>
|
||||
#[case] mut player: Rc<RefCell<Box<dyn GameObject>>>,
|
||||
#[case] mut bounds: Rc<RefCell<Box<dyn GameObject>>>,
|
||||
#[case] mut player_expected: Rc<RefCell<Box<dyn GameObject>>>,
|
||||
#[case] mut bounds_expected: Rc<RefCell<Box<dyn GameObject>>>
|
||||
) {
|
||||
handle_player_bound_collision(&mut player, &mut bounds);
|
||||
assert_eq!(player_expected.pos(), player.pos());
|
||||
assert_eq!(bounds_expected.pos(), bounds.pos());
|
||||
handle_player_bound_collision(player.clone(), bounds.clone());
|
||||
assert_eq!(player_expected.borrow().pos(), player.borrow().pos());
|
||||
assert_eq!(bounds_expected.borrow().pos(), bounds.borrow().pos());
|
||||
}
|
||||
|
||||
fn create_player(id: u16, x: u16, y: u16, orientation: Vector) -> Box<dyn GameObject> {
|
||||
fn create_player(id: u16, x: u16, y: u16, orientation: Vector) -> Rc<RefCell<Box<dyn GameObject>>> {
|
||||
let field = Field::new(Box::new(NoopLogger{}));
|
||||
let mut player = DefaultGameObject::player(id, x, y, &field);
|
||||
let player_orientation = player.orientation_mut();
|
||||
player_orientation.x = orientation.x;
|
||||
player_orientation.y = orientation.y;
|
||||
player
|
||||
Rc::new(RefCell::new(player))
|
||||
}
|
||||
|
||||
fn get_bound(bound: Bound) -> Box<dyn GameObject> {
|
||||
fn get_bound(bound: Bound) -> Rc<RefCell<Box<dyn GameObject>>> {
|
||||
let field = Field::new(Box::new(NoopLogger{}));
|
||||
let bounds = DefaultGameObject::bounds(field.width, field.height);
|
||||
return bounds.into_iter().find(|b| {
|
||||
return Rc::new(RefCell::new(bounds.into_iter().find(|b| {
|
||||
b.0 == bound
|
||||
}).unwrap().inner();
|
||||
}).unwrap().inner()));
|
||||
}
|
||||
|
||||
11
src/lib.rs
11
src/lib.rs
@@ -1,5 +1,6 @@
|
||||
mod utils;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use pong::collision::collision::{Collision, CollisionDetector};
|
||||
use pong::game_field::{Field, Input, InputType};
|
||||
use pong::game_object::game_object::GameObject;
|
||||
@@ -9,6 +10,7 @@ use pong::utils::utils::Logger;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use std::cmp::{max, min};
|
||||
use std::rc::Rc;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
extern crate serde_json;
|
||||
@@ -39,7 +41,9 @@ pub struct GameObjectDTO {
|
||||
}
|
||||
|
||||
impl GameObjectDTO {
|
||||
pub fn from(obj: &Box<dyn GameObject>) -> GameObjectDTO {
|
||||
pub fn from(obj: &Rc<RefCell<Box<dyn GameObject>>>) -> GameObjectDTO {
|
||||
let obj = RefCell::borrow(obj);
|
||||
|
||||
let pos = obj.pos();
|
||||
let shape = obj.shape();
|
||||
return GameObjectDTO {
|
||||
@@ -123,9 +127,8 @@ impl FieldWrapper {
|
||||
pub fn objects(&self) -> *const GameObjectDTO {
|
||||
let mut objs = self
|
||||
.field
|
||||
.objs
|
||||
.borrow()
|
||||
.iter()
|
||||
.objs()
|
||||
.into_iter()
|
||||
.map(|o| GameObjectDTO::from(o))
|
||||
.collect::<Vec<GameObjectDTO>>();
|
||||
objs.as_ptr()
|
||||
|
||||
Reference in New Issue
Block a user