mirror of
https://github.com/thilo-behnke/wasm-pong.git
synced 2026-07-11 02:29:25 +00:00
using refcells?
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
pub mod collision {
|
||||
use std::alloc::handle_alloc_error;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
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::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub struct CollisionDetector {}
|
||||
|
||||
@@ -12,18 +13,21 @@ pub mod collision {
|
||||
CollisionDetector {}
|
||||
}
|
||||
|
||||
pub fn detect_collisions(&self, objs: &Vec<&Box<dyn GameObject>>) -> Box<dyn CollisionRegistry> {
|
||||
pub fn detect_collisions(
|
||||
&self,
|
||||
objs: Vec<&RefCell<Box<dyn GameObject>>>,
|
||||
) -> Box<dyn CollisionRegistry> {
|
||||
if objs.is_empty() {
|
||||
return Box::new(Collisions::new(vec![]));
|
||||
}
|
||||
let mut collisions: Vec<Collision> = vec![];
|
||||
let mut i = 0;
|
||||
loop {
|
||||
let obj = objs[i];
|
||||
let obj = objs[i].borrow();
|
||||
i += 1;
|
||||
|
||||
let rest = &objs[i..];
|
||||
for other in rest.iter() {
|
||||
for other in rest.iter().map(|o| o.borrow()) {
|
||||
let has_collision = obj.bounding_box().overlaps(&other.bounding_box());
|
||||
if !has_collision {
|
||||
continue;
|
||||
@@ -39,7 +43,7 @@ pub mod collision {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait CollisionRegistry : Debug {
|
||||
pub trait CollisionRegistry: Debug {
|
||||
fn get_collisions(&self) -> Vec<&Collision>;
|
||||
fn get_collisions_by_id(&self, id: u16) -> Vec<&Collision>;
|
||||
}
|
||||
@@ -70,18 +74,23 @@ pub mod collision {
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub struct Collision(pub u16, pub u16);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CollisionHandler {
|
||||
handlers: HashMap<(String, String), fn(&mut Box<dyn GameObject>, &mut Box<dyn GameObject>)>
|
||||
handlers: HashMap<(String, String), fn(&mut Box<dyn GameObject>, &mut Box<dyn GameObject>)>,
|
||||
}
|
||||
|
||||
impl CollisionHandler {
|
||||
pub fn new() -> CollisionHandler {
|
||||
CollisionHandler {
|
||||
handlers: HashMap::new()
|
||||
handlers: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn register(&mut self, mapping: (String, String), callback: fn(&mut Box<dyn GameObject>, &mut Box<dyn GameObject>)) {
|
||||
pub fn register(
|
||||
&mut self,
|
||||
mapping: (String, String),
|
||||
callback: fn(&mut Box<dyn GameObject>, &mut Box<dyn GameObject>),
|
||||
) {
|
||||
self.handlers.insert(mapping, callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
use crate::collision::collision::{Collision, CollisionDetector, CollisionHandler, CollisionRegistry, Collisions};
|
||||
use std::borrow::{Borrow, BorrowMut};
|
||||
use crate::collision::collision::{
|
||||
Collision, CollisionDetector, CollisionHandler, CollisionRegistry, Collisions,
|
||||
};
|
||||
use crate::game_object::components::{DefaultGeomComp, DefaultPhysicsComp};
|
||||
use crate::game_object::game_object::{DefaultGameObject, GameObject};
|
||||
use crate::geom::geom::Vector;
|
||||
use crate::geom::shape::{Shape, ShapeType};
|
||||
use crate::utils::utils::{Logger, NoopLogger};
|
||||
use std::cell::{Cell, RefCell, RefMut};
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum InputType {
|
||||
@@ -21,11 +27,9 @@ pub struct Field {
|
||||
pub logger: Box<dyn Logger>,
|
||||
pub width: u16,
|
||||
pub height: u16,
|
||||
pub players: Vec<Player>,
|
||||
pub balls: Vec<Ball>,
|
||||
pub bounds: Bounds,
|
||||
pub objs: HashMap<u16, RefCell<Box<dyn GameObject>>>,
|
||||
pub collisions: Box<dyn CollisionRegistry>,
|
||||
collision_handler: CollisionHandler
|
||||
collision_handler: CollisionHandler,
|
||||
}
|
||||
|
||||
impl Field {
|
||||
@@ -37,36 +41,40 @@ impl Field {
|
||||
logger,
|
||||
width,
|
||||
height,
|
||||
players: vec![],
|
||||
balls: vec![],
|
||||
bounds: Bounds::new(width, height),
|
||||
objs: DefaultGameObject::bounds(width, height),
|
||||
collisions: Box::new(Collisions::new(vec![])),
|
||||
collision_handler: CollisionHandler::new()
|
||||
collision_handler: CollisionHandler::new(),
|
||||
};
|
||||
|
||||
field.add_player(0, 0 + width / 20, height / 2);
|
||||
field.add_player(1, width - width / 20, height / 2);
|
||||
field.add_ball(2, width / 2, height / 2);
|
||||
|
||||
field.collision_handler.register((String::from("ball"), String::from("player")), |ball, player| {
|
||||
// reflect
|
||||
ball.vel_mut().reflect(&player.orientation());
|
||||
// use vel of player obj
|
||||
if *player.vel() != Vector::zero() {
|
||||
let mut adjusted = player.vel().clone();
|
||||
adjusted.normalize();
|
||||
ball.vel_mut().add(&adjusted);
|
||||
}
|
||||
// move out of collision
|
||||
let mut b_to_a = ball.pos().clone();
|
||||
b_to_a.sub(&player.pos());
|
||||
b_to_a.normalize();
|
||||
ball.pos_mut().add(&b_to_a);
|
||||
});
|
||||
field.collision_handler.register(
|
||||
(String::from("ball"), String::from("player")),
|
||||
|ball, player| {
|
||||
// reflect
|
||||
ball.vel_mut().reflect(&player.orientation());
|
||||
// use vel of player obj
|
||||
if *player.vel() != Vector::zero() {
|
||||
let mut adjusted = player.vel().clone();
|
||||
adjusted.normalize();
|
||||
ball.vel_mut().add(&adjusted);
|
||||
}
|
||||
// move out of collision
|
||||
let mut b_to_a = ball.pos().clone();
|
||||
b_to_a.sub(&player.pos());
|
||||
b_to_a.normalize();
|
||||
ball.pos_mut().add(&b_to_a);
|
||||
},
|
||||
);
|
||||
|
||||
field.collision_handler.register((String::from("ball"), String::from("bound")), |ball, bound| {
|
||||
ball.vel_mut().reflect(&bound.orientation());
|
||||
});
|
||||
field.collision_handler.register(
|
||||
(String::from("ball"), String::from("bound")),
|
||||
|ball, bound| {
|
||||
ball.vel_mut().reflect(&bound.orientation());
|
||||
},
|
||||
);
|
||||
|
||||
return field;
|
||||
}
|
||||
@@ -76,64 +84,77 @@ impl Field {
|
||||
logger: Box::new(NoopLogger {}),
|
||||
width,
|
||||
height,
|
||||
players: vec![],
|
||||
balls: vec![],
|
||||
bounds: Bounds::new(width, height),
|
||||
objs: DefaultGameObject::bounds(width, height),
|
||||
collisions: Box::new(Collisions::new(vec![])),
|
||||
collision_handler: CollisionHandler::new()
|
||||
collision_handler: CollisionHandler::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_player(&mut self, id: u16, x: u16, y: u16) {
|
||||
self.players.push(Player::new(id, x, y, &self));
|
||||
let player = DefaultGameObject::player(id, x, y, &self);
|
||||
self.objs.insert(player.id(), RefCell::new(player));
|
||||
}
|
||||
|
||||
pub fn add_ball(&mut self, id: u16, x: u16, y: u16) {
|
||||
let ball = Ball::new(id, x, y, &self);
|
||||
self.balls.push(ball);
|
||||
let ball = DefaultGameObject::ball(id, x, y, &self);
|
||||
self.objs.insert(ball.id(), RefCell::new(ball));
|
||||
}
|
||||
|
||||
pub fn tick(&mut self, inputs: Vec<Input>) {
|
||||
for ball in self.balls.iter_mut() {
|
||||
if *ball.obj.vel() == Vector::zero() {
|
||||
ball.obj.vel_mut().add(&Vector::new(-2.0, 0.))
|
||||
{
|
||||
for (_, obj) in self.objs.iter() {
|
||||
let mut obj_mut = obj.borrow_mut();
|
||||
if obj_mut.obj_type() != "ball" {
|
||||
continue;
|
||||
}
|
||||
if *obj_mut.vel() == Vector::zero() {
|
||||
obj_mut.vel_mut().add(&Vector::new(-2.0, 0.))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for player in self.players.iter_mut() {
|
||||
let input_opt = inputs.iter().find(|input| player.obj.id() == input.obj_id);
|
||||
if let None = input_opt {
|
||||
player.obj.vel_mut().y = 0.;
|
||||
continue;
|
||||
{
|
||||
for (_, obj) in self.objs.iter() {
|
||||
let mut obj_mut = obj.borrow_mut();
|
||||
if obj_mut.obj_type() != "player" {
|
||||
continue;
|
||||
}
|
||||
let input_opt = inputs.iter().find(|i| i.obj_id == obj_mut.id());
|
||||
if let None = input_opt {
|
||||
obj_mut.vel_mut().y = 0.;
|
||||
continue;
|
||||
}
|
||||
let input = input_opt.unwrap();
|
||||
match input.input {
|
||||
InputType::UP => {
|
||||
let updated_vel_y = (obj_mut.vel().y + 1.).min(5.);
|
||||
obj_mut.vel_mut().y = updated_vel_y;
|
||||
}
|
||||
InputType::DOWN => {
|
||||
let updated_vel_y = (obj_mut.vel().y - 1.).max(-5.);
|
||||
obj_mut.vel_mut().y = updated_vel_y;
|
||||
}
|
||||
};
|
||||
}
|
||||
let input = input_opt.unwrap();
|
||||
match input.input {
|
||||
InputType::UP => {
|
||||
let updated_vel_y = (player.obj.vel().y + 1.).min(5.);
|
||||
player.obj.vel_mut().y = updated_vel_y;
|
||||
}
|
||||
InputType::DOWN => {
|
||||
let updated_vel_y = (player.obj.vel().y - 1.).max(-5.);
|
||||
player.obj.vel_mut().y = updated_vel_y;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
for player in self.players.iter_mut() {
|
||||
player.obj.update_pos()
|
||||
}
|
||||
for ball in self.balls.iter_mut() {
|
||||
ball.obj.update_pos()
|
||||
{
|
||||
for (_, obj) in self.objs.iter() {
|
||||
let mut obj_mut = obj.borrow_mut();
|
||||
obj_mut.update_pos();
|
||||
}
|
||||
}
|
||||
|
||||
let collisions = self.get_collisions();
|
||||
|
||||
let collision_handler = self.collision_handler.clone();
|
||||
for collision in collisions.get_collisions().iter() {
|
||||
// self.handle_collision(c);
|
||||
let objs_mut = self.objs_mut();
|
||||
let obj_a = objs_mut.iter().find(|o| o.id() == collision.0).unwrap();
|
||||
let obj_b = objs_mut.iter().find(|o| o.id() == collision.1).unwrap();
|
||||
self.collision_handler.handle(*obj_a, *obj_b)
|
||||
// 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)
|
||||
}
|
||||
//
|
||||
// for ball in self.balls.iter_mut() {
|
||||
@@ -160,165 +181,117 @@ impl Field {
|
||||
}
|
||||
|
||||
fn get_collisions(&self) -> Box<dyn CollisionRegistry> {
|
||||
let objs = self.objs();
|
||||
let objs = self.objs.iter().map(|(_, o)| o).collect();
|
||||
let collision_detector = CollisionDetector::new();
|
||||
collision_detector.detect_collisions(&objs)
|
||||
collision_detector.detect_collisions(objs)
|
||||
}
|
||||
|
||||
fn handle_collision(&mut self, collision: &Collision) {
|
||||
let objs_mut = self.objs_mut();
|
||||
let obj_a = objs_mut.iter().find(|o| o.id() == collision.0).unwrap();
|
||||
let obj_b = objs_mut.iter().find(|o| o.id() == collision.1).unwrap();
|
||||
self.collision_handler.handle(*obj_a, *obj_b)
|
||||
}
|
||||
|
||||
pub fn players(&self) -> Vec<&Player> {
|
||||
self.players.iter().collect()
|
||||
}
|
||||
|
||||
pub fn balls(&self) -> Vec<&Ball> {
|
||||
self.balls.iter().collect()
|
||||
}
|
||||
|
||||
fn objs(&self) -> Vec<&Box<dyn GameObject>> {
|
||||
let mut objs: Vec<&Box<dyn GameObject>> = vec![];
|
||||
objs.extend(
|
||||
self.players
|
||||
.iter()
|
||||
.map(|p| &p.obj)
|
||||
.collect::<Vec<&Box<dyn GameObject>>>(),
|
||||
);
|
||||
objs.extend(
|
||||
self.balls
|
||||
.iter()
|
||||
.map(|b| &b.obj)
|
||||
.collect::<Vec<&Box<dyn GameObject>>>(),
|
||||
);
|
||||
objs.extend(
|
||||
self.bounds.objs
|
||||
.iter()
|
||||
.collect::<Vec<&Box<dyn GameObject>>>()
|
||||
);
|
||||
objs
|
||||
}
|
||||
|
||||
fn objs_mut(&mut self) -> Vec<&mut Box<dyn GameObject>> {
|
||||
let mut objs: Vec<&mut Box<dyn GameObject>> = vec![];
|
||||
objs.extend(
|
||||
self.players
|
||||
.iter_mut()
|
||||
.map(|p| &mut p.obj)
|
||||
.collect::<Vec<&mut Box<dyn GameObject>>>(),
|
||||
);
|
||||
objs.extend(
|
||||
self.balls
|
||||
.iter_mut()
|
||||
.map(|b| &mut b.obj)
|
||||
.collect::<Vec<&mut Box<dyn GameObject>>>(),
|
||||
);
|
||||
objs.extend(
|
||||
self.bounds.objs
|
||||
.iter_mut()
|
||||
.collect::<Vec<&mut Box<dyn GameObject>>>()
|
||||
);
|
||||
objs
|
||||
fn get_obj<'a>(&self, id: u16, mut objs: &'a RefMut<Vec<Box<dyn GameObject>>>) -> &'a mut Box<dyn GameObject> {
|
||||
objs.iter_mut().find(|o| o.id() == id).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
// #[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Debug)]
|
||||
pub struct Player {
|
||||
pub obj: Box<dyn GameObject>,
|
||||
}
|
||||
|
||||
impl Player {
|
||||
pub fn new(id: u16, x: u16, y: u16, field: &Field) -> Player {
|
||||
Player {
|
||||
obj: Box::new(DefaultGameObject::new(
|
||||
impl DefaultGameObject {
|
||||
pub fn player(id: u16, x: u16, y: u16, field: &Field) -> Box<dyn GameObject> {
|
||||
Box::new(DefaultGameObject::new(
|
||||
id,
|
||||
"player".to_string(),
|
||||
Box::new(DefaultGeomComp::new(
|
||||
Shape::rect(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
|
||||
))
|
||||
))
|
||||
}
|
||||
Box::new(DefaultGeomComp::new(Shape::rect(
|
||||
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)]
|
||||
#[derive(Debug)]
|
||||
pub struct Ball {
|
||||
pub obj: Box<dyn GameObject>,
|
||||
}
|
||||
|
||||
impl Ball {
|
||||
pub fn new(id: u16, x: u16, y: u16, field: &Field) -> Ball {
|
||||
Ball {
|
||||
obj: Box::new(DefaultGameObject::new(
|
||||
impl DefaultGameObject {
|
||||
pub fn ball(id: u16, x: u16, y: u16, field: &Field) -> Box<dyn GameObject> {
|
||||
Box::new(DefaultGameObject::new(
|
||||
id,
|
||||
"ball".to_string(),
|
||||
Box::new(DefaultGeomComp::new(
|
||||
Shape::circle(Vector { x: x as f64, y: y as f64 }, Vector::zero(), (field.width as f64) / 80.)
|
||||
)),
|
||||
Box::new(DefaultPhysicsComp::new(
|
||||
Box::new(DefaultGeomComp::new(Shape::circle(
|
||||
Vector {
|
||||
x: x as f64,
|
||||
y: y as f64,
|
||||
},
|
||||
Vector::zero(),
|
||||
false
|
||||
))
|
||||
))
|
||||
}
|
||||
(field.width as f64) / 80.,
|
||||
))),
|
||||
Box::new(DefaultPhysicsComp::new(Vector::zero(), false)),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Bounds {
|
||||
pub objs: Vec<Box<dyn GameObject>>,
|
||||
}
|
||||
|
||||
impl Bounds {
|
||||
pub fn new(width: u16, height: u16) -> Bounds {
|
||||
Bounds {
|
||||
objs: vec![
|
||||
// top
|
||||
Box::new(DefaultGameObject::new(
|
||||
90,
|
||||
"bound".to_string(),
|
||||
Box::new(DefaultGeomComp::new(
|
||||
Shape::rect(Vector {x: (width / 2) as f64, y: 0 as f64}, Vector::new(1., 0.), width as f64, 2.)
|
||||
)),
|
||||
Box::new(DefaultPhysicsComp::new_static())
|
||||
)),
|
||||
// bottom
|
||||
Box::new(DefaultGameObject::new(
|
||||
91,
|
||||
"bound".to_string(),
|
||||
Box::new(DefaultGeomComp::new(
|
||||
Shape::rect(Vector {x: (width / 2) as f64, y: height as f64}, Vector::new(-1., 0.), width as f64, 2.)
|
||||
)),
|
||||
Box::new(DefaultPhysicsComp::new_static())
|
||||
)),
|
||||
// left
|
||||
Box::new(DefaultGameObject::new(
|
||||
92,
|
||||
"bound".to_string(),
|
||||
Box::new(DefaultGeomComp::new(
|
||||
Shape::rect(Vector {x: 0 as f64, y: (height / 2) as f64}, Vector::new(0., 1.), 2., height as f64)
|
||||
)),
|
||||
Box::new(DefaultPhysicsComp::new_static())
|
||||
)),
|
||||
// right
|
||||
Box::new(DefaultGameObject::new(
|
||||
93,
|
||||
"bound".to_string(),
|
||||
Box::new(DefaultGeomComp::new(
|
||||
Shape::rect(Vector {x: width as f64, y: (height / 2) as f64}, Vector::new(0., -1.), 2., height as f64)
|
||||
)),
|
||||
Box::new(DefaultPhysicsComp::new_static())
|
||||
))
|
||||
],
|
||||
}
|
||||
impl DefaultGameObject {
|
||||
pub fn bounds(width: u16, height: u16) -> HashMap<u16, RefCell<Box<dyn GameObject>>> {
|
||||
let bounds = vec![
|
||||
// top
|
||||
Box::new(DefaultGameObject::new(
|
||||
90,
|
||||
"bound".to_string(),
|
||||
Box::new(DefaultGeomComp::new(Shape::rect(
|
||||
Vector {
|
||||
x: (width / 2) as f64,
|
||||
y: 0 as f64,
|
||||
},
|
||||
Vector::new(1., 0.),
|
||||
width as f64,
|
||||
2.,
|
||||
))),
|
||||
Box::new(DefaultPhysicsComp::new_static()),
|
||||
)),
|
||||
// bottom
|
||||
Box::new(DefaultGameObject::new(
|
||||
91,
|
||||
"bound".to_string(),
|
||||
Box::new(DefaultGeomComp::new(Shape::rect(
|
||||
Vector {
|
||||
x: (width / 2) as f64,
|
||||
y: height as f64,
|
||||
},
|
||||
Vector::new(-1., 0.),
|
||||
width as f64,
|
||||
2.,
|
||||
))),
|
||||
Box::new(DefaultPhysicsComp::new_static()),
|
||||
)),
|
||||
// left
|
||||
Box::new(DefaultGameObject::new(
|
||||
92,
|
||||
"bound".to_string(),
|
||||
Box::new(DefaultGeomComp::new(Shape::rect(
|
||||
Vector {
|
||||
x: 0 as f64,
|
||||
y: (height / 2) as f64,
|
||||
},
|
||||
Vector::new(0., 1.),
|
||||
2.,
|
||||
height as f64,
|
||||
))),
|
||||
Box::new(DefaultPhysicsComp::new_static()),
|
||||
)),
|
||||
// right
|
||||
Box::new(DefaultGameObject::new(
|
||||
93,
|
||||
"bound".to_string(),
|
||||
Box::new(DefaultGeomComp::new(Shape::rect(
|
||||
Vector {
|
||||
x: width as f64,
|
||||
y: (height / 2) as f64,
|
||||
},
|
||||
Vector::new(0., -1.),
|
||||
2.,
|
||||
height as f64,
|
||||
))),
|
||||
Box::new(DefaultPhysicsComp::new_static()),
|
||||
)),
|
||||
];
|
||||
bounds.iter().map(|o| (o.id, RefCell::new(o))).collect()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
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::{Shape, ShapeType};
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub trait GameObject : Debug {
|
||||
pub trait GameObject: Debug {
|
||||
fn id(&self) -> u16;
|
||||
fn obj_type(&self) -> &str;
|
||||
fn shape(&self) -> &ShapeType;
|
||||
@@ -24,12 +24,22 @@ pub mod game_object {
|
||||
pub id: u16,
|
||||
pub obj_type: String,
|
||||
geom: Box<dyn GeomComp>,
|
||||
physics: Box<dyn PhysicsComp>
|
||||
physics: Box<dyn PhysicsComp>,
|
||||
}
|
||||
|
||||
impl DefaultGameObject {
|
||||
pub fn new(id: u16, obj_type: String, geom: Box<dyn GeomComp>, physics: Box<dyn PhysicsComp>) -> DefaultGameObject {
|
||||
DefaultGameObject {id, obj_type, geom, physics}
|
||||
pub fn new(
|
||||
id: u16,
|
||||
obj_type: String,
|
||||
geom: Box<dyn GeomComp>,
|
||||
physics: Box<dyn PhysicsComp>,
|
||||
) -> DefaultGameObject {
|
||||
DefaultGameObject {
|
||||
id,
|
||||
obj_type,
|
||||
geom,
|
||||
physics,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,11 +102,14 @@ pub mod game_object {
|
||||
}
|
||||
|
||||
pub mod components {
|
||||
use std::fmt::Debug;
|
||||
use crate::geom::geom::{BoundingBox, Vector};
|
||||
use crate::geom::shape::{get_bounding_box, get_center, get_center_mut, get_orientation, get_orientation_mut, Shape, ShapeType};
|
||||
use crate::geom::shape::{
|
||||
get_bounding_box, get_center, get_center_mut, get_orientation, get_orientation_mut, Shape,
|
||||
ShapeType,
|
||||
};
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub trait GeomComp : Debug {
|
||||
pub trait GeomComp: Debug {
|
||||
fn shape(&self) -> &ShapeType;
|
||||
fn orientation(&self) -> &Vector;
|
||||
fn orientation_mut(&mut self) -> &mut Vector;
|
||||
@@ -107,12 +120,12 @@ pub mod components {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DefaultGeomComp {
|
||||
shape: ShapeType
|
||||
shape: ShapeType,
|
||||
}
|
||||
|
||||
impl DefaultGeomComp {
|
||||
pub fn new(shape: ShapeType) -> DefaultGeomComp {
|
||||
DefaultGeomComp {shape}
|
||||
DefaultGeomComp { shape }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +155,7 @@ pub mod components {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PhysicsComp : Debug {
|
||||
pub trait PhysicsComp: Debug {
|
||||
fn vel(&self) -> &Vector;
|
||||
fn vel_mut(&mut self) -> &mut Vector;
|
||||
fn is_static(&self) -> bool;
|
||||
@@ -151,18 +164,15 @@ pub mod components {
|
||||
#[derive(Debug)]
|
||||
pub struct DefaultPhysicsComp {
|
||||
vel: Vector,
|
||||
is_static: bool
|
||||
is_static: bool,
|
||||
}
|
||||
impl DefaultPhysicsComp {
|
||||
pub fn new(vel: Vector, is_static: bool) -> DefaultPhysicsComp {
|
||||
DefaultPhysicsComp {vel, is_static}
|
||||
DefaultPhysicsComp { vel, is_static }
|
||||
}
|
||||
|
||||
pub fn new_static() -> DefaultPhysicsComp {
|
||||
DefaultPhysicsComp::new(
|
||||
Vector::zero(),
|
||||
true
|
||||
)
|
||||
DefaultPhysicsComp::new(Vector::zero(), true)
|
||||
}
|
||||
}
|
||||
impl PhysicsComp for DefaultPhysicsComp {
|
||||
|
||||
@@ -17,9 +17,7 @@ pub mod geom {
|
||||
}
|
||||
|
||||
pub fn new(x: f64, y: f64) -> Vector {
|
||||
Vector {
|
||||
x, y
|
||||
}
|
||||
Vector { x, y }
|
||||
}
|
||||
|
||||
pub fn normalize(&mut self) {
|
||||
@@ -68,7 +66,7 @@ pub mod geom {
|
||||
}
|
||||
|
||||
pub fn dot(&self, other: &Vector) -> f64 {
|
||||
return self.x * other.x + self.y * other.y
|
||||
return self.x * other.x + self.y * other.y;
|
||||
}
|
||||
|
||||
pub fn angle(&self, other: &Vector) -> f64 {
|
||||
@@ -130,8 +128,8 @@ pub mod geom {
|
||||
|
||||
impl PartialEq for Vector {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
(self.x * 1000.).round() == (other.x * 1000.).round() &&
|
||||
(self.y * 1000.).round() == (other.y * 1000.).round()
|
||||
(self.x * 1000.).round() == (other.x * 1000.).round()
|
||||
&& (self.y * 1000.).round() == (other.y * 1000.).round()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,13 +206,9 @@ pub mod geom {
|
||||
impl Range {
|
||||
pub fn new(a: f64, b: f64) -> Range {
|
||||
if a <= b {
|
||||
return Range {
|
||||
min: a, max: b
|
||||
}
|
||||
}
|
||||
return Range {
|
||||
min: b, max: a
|
||||
return Range { min: a, max: b };
|
||||
}
|
||||
return Range { min: b, max: a };
|
||||
}
|
||||
|
||||
pub fn overlaps(&self, other: &Range) -> bool {
|
||||
@@ -240,8 +234,8 @@ pub mod geom {
|
||||
}
|
||||
|
||||
pub mod shape {
|
||||
use std::fmt::Debug;
|
||||
use crate::geom::geom::{BoundingBox, Vector};
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum ShapeType {
|
||||
@@ -252,20 +246,29 @@ pub mod shape {
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Shape {
|
||||
center: Vector,
|
||||
orientation: Vector
|
||||
orientation: Vector,
|
||||
}
|
||||
|
||||
impl Shape {
|
||||
pub fn rect(center: Vector, orientation: Vector, width: f64, height: f64) -> ShapeType {
|
||||
ShapeType::Rect(Shape {
|
||||
center, orientation
|
||||
}, width, height)
|
||||
ShapeType::Rect(
|
||||
Shape {
|
||||
center,
|
||||
orientation,
|
||||
},
|
||||
width,
|
||||
height,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn circle(center: Vector, orientation: Vector, radius: f64) -> ShapeType {
|
||||
ShapeType::Circle(Shape {
|
||||
center, orientation
|
||||
}, radius)
|
||||
ShapeType::Circle(
|
||||
Shape {
|
||||
center,
|
||||
orientation,
|
||||
},
|
||||
radius,
|
||||
)
|
||||
}
|
||||
|
||||
fn center(&self) -> &Vector {
|
||||
@@ -288,35 +291,37 @@ pub mod shape {
|
||||
pub fn get_center(shape: &ShapeType) -> &Vector {
|
||||
match shape {
|
||||
ShapeType::Rect(ref s, _, _) => &s.center,
|
||||
ShapeType::Circle(ref s, _) => &s.center
|
||||
ShapeType::Circle(ref s, _) => &s.center,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_center_mut(shape: &mut ShapeType) -> &mut Vector {
|
||||
match shape {
|
||||
ShapeType::Rect(ref mut s, _, _) => &mut s.center,
|
||||
ShapeType::Circle(ref mut s, _) => &mut s.center
|
||||
ShapeType::Circle(ref mut s, _) => &mut s.center,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_orientation(shape: &ShapeType) -> &Vector {
|
||||
match shape {
|
||||
ShapeType::Rect(s, _, _) => &s.orientation,
|
||||
ShapeType::Circle(s, _) => &s.orientation
|
||||
ShapeType::Circle(s, _) => &s.orientation,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_orientation_mut(shape: &mut ShapeType) -> &mut Vector {
|
||||
match shape {
|
||||
ShapeType::Rect(ref mut s, _, _) => &mut s.orientation,
|
||||
ShapeType::Circle(ref mut s, _) => &mut s.orientation
|
||||
ShapeType::Circle(ref mut s, _) => &mut s.orientation,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_bounding_box(shape: &ShapeType) -> BoundingBox {
|
||||
match shape {
|
||||
ShapeType::Rect(s, width, height) => BoundingBox::create(&s.center, *width, *height),
|
||||
ShapeType::Circle(s, radius) => BoundingBox::create(&s.center, *radius * 2., *radius * 2.)
|
||||
ShapeType::Circle(s, radius) => {
|
||||
BoundingBox::create(&s.center, *radius * 2., *radius * 2.)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
pub mod collision;
|
||||
pub mod game_field;
|
||||
pub mod game_object;
|
||||
pub mod geom;
|
||||
pub mod game_field;
|
||||
pub mod utils;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
pub mod utils {
|
||||
pub trait Logger {
|
||||
fn log(&self, msg: &str);
|
||||
@@ -6,7 +5,6 @@ pub mod utils {
|
||||
|
||||
pub struct NoopLogger {}
|
||||
impl Logger for NoopLogger {
|
||||
fn log(&self, msg: &str) {
|
||||
}
|
||||
fn log(&self, msg: &str) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use rstest::rstest;
|
||||
use pong::geom::geom::{BoundingBox, Vector};
|
||||
use rstest::rstest;
|
||||
|
||||
#[rstest]
|
||||
#[case(BoundingBox::create(&Vector::new(10., 10.), 5., 5.), Vector::new(10., 10.), true)]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use rstest::rstest;
|
||||
use pong::collision::collision::CollisionHandler;
|
||||
use pong::game_object::components::{DefaultGeomComp, DefaultPhysicsComp};
|
||||
use pong::game_object::game_object::{DefaultGameObject, GameObject};
|
||||
use pong::geom::geom::Vector;
|
||||
use pong::geom::shape::Shape;
|
||||
use rstest::rstest;
|
||||
|
||||
#[rstest]
|
||||
#[case(
|
||||
@@ -76,15 +76,21 @@ pub fn should_handle_collision(
|
||||
assert_eq!(obj_b.vel(), expected_b.vel());
|
||||
}
|
||||
|
||||
fn create_game_obj(id: u16, vel: Vector, orientation: Vector, is_static: bool) -> Box<dyn GameObject> {
|
||||
fn create_game_obj(
|
||||
id: u16,
|
||||
vel: Vector,
|
||||
orientation: Vector,
|
||||
is_static: bool,
|
||||
) -> Box<dyn GameObject> {
|
||||
Box::new(DefaultGameObject::new(
|
||||
id,
|
||||
"obj".to_string(),
|
||||
Box::new(DefaultGeomComp::new(
|
||||
Shape::rect(Vector::zero(), orientation, 20., 20.)
|
||||
)),
|
||||
Box::new(DefaultPhysicsComp::new(
|
||||
vel, is_static
|
||||
))
|
||||
"obj".to_string(),
|
||||
Box::new(DefaultGeomComp::new(Shape::rect(
|
||||
Vector::zero(),
|
||||
orientation,
|
||||
20.,
|
||||
20.,
|
||||
))),
|
||||
Box::new(DefaultPhysicsComp::new(vel, is_static)),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -1,46 +1,46 @@
|
||||
use rstest::rstest;
|
||||
use std::cell::{Ref, RefCell};
|
||||
use pong::collision::collision::{Collision, CollisionDetector};
|
||||
use pong::game_object::game_object::GameObject;
|
||||
use pong::geom::geom::{BoundingBox, Vector};
|
||||
use pong::geom::shape::ShapeType;
|
||||
|
||||
use rstest::rstest;
|
||||
|
||||
#[rstest]
|
||||
#[case(vec![], vec![])]
|
||||
#[case(RefCell::new(vec![]), vec![])]
|
||||
#[case(
|
||||
vec![
|
||||
RefCell::new(vec![
|
||||
MockGameObject::new(1, BoundingBox::create(&Vector{x: 50., y: 50.}, 20., 20.)),
|
||||
MockGameObject::new(2, BoundingBox::create(&Vector{x: 50., y: 50.}, 20., 20.))
|
||||
],
|
||||
]),
|
||||
vec![Collision(1, 2)]
|
||||
)]
|
||||
#[case(
|
||||
vec![
|
||||
RefCell::new(vec![
|
||||
MockGameObject::new(1, BoundingBox::create(&Vector{x: 60., y: 65.}, 20., 20.)),
|
||||
MockGameObject::new(2, BoundingBox::create(&Vector{x: 50., y: 50.}, 20., 20.)),
|
||||
],
|
||||
]),
|
||||
vec![Collision(1, 2)]
|
||||
)]
|
||||
#[case(
|
||||
vec![
|
||||
RefCell::new(vec![
|
||||
MockGameObject::new(1, BoundingBox::create(&Vector{x: 50., y: 50.}, 20., 20.)),
|
||||
MockGameObject::new(2, BoundingBox::create(&Vector{x: 80., y: 80.}, 20., 20.)),
|
||||
],
|
||||
]),
|
||||
vec![]
|
||||
)]
|
||||
#[case(
|
||||
vec![
|
||||
RefCell::new(vec![
|
||||
MockGameObject::new(1, BoundingBox::create(&Vector{x: 50., y: 50.}, 50., 50.)),
|
||||
MockGameObject::new(2, BoundingBox::create(&Vector{x: 500., y: 50.}, 50., 50.)),
|
||||
],
|
||||
]),
|
||||
vec![]
|
||||
)]
|
||||
pub fn should_detect_collisions(
|
||||
#[case] objs: Vec<Box<dyn GameObject>>,
|
||||
#[case] objs: RefCell<Vec<Box<dyn GameObject>>>,
|
||||
#[case] expected_collisions: Vec<Collision>,
|
||||
) {
|
||||
let detector = CollisionDetector::new();
|
||||
let res = detector.detect_collisions(&objs.iter().collect());
|
||||
let res = detector.detect_collisions(objs.borrow());
|
||||
assert_eq!(
|
||||
res.get_collisions(),
|
||||
expected_collisions.iter().collect::<Vec<&Collision>>()
|
||||
@@ -51,16 +51,16 @@ pub fn should_detect_collisions(
|
||||
pub struct MockGameObject {
|
||||
id: u16,
|
||||
bounding_box: BoundingBox,
|
||||
zero_vec: Vector
|
||||
zero_vec: Vector,
|
||||
}
|
||||
|
||||
impl MockGameObject {
|
||||
pub fn new(id: u16, bounding_box: BoundingBox) -> Box<dyn GameObject> {
|
||||
Box::new(
|
||||
MockGameObject {
|
||||
id, bounding_box, zero_vec: Vector::zero()
|
||||
}
|
||||
)
|
||||
Box::new(MockGameObject {
|
||||
id,
|
||||
bounding_box,
|
||||
zero_vec: Vector::zero(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,6 @@ impl GameObject for MockGameObject {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
||||
fn shape(&self) -> &ShapeType {
|
||||
todo!()
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ mod game_field_tests {
|
||||
obj_id: 1,
|
||||
}];
|
||||
field.tick(inputs);
|
||||
let players = field.players();
|
||||
let player = players.first().unwrap();
|
||||
assert_eq!(player.obj.pos().y, height as f64 / 2. + 1.);
|
||||
let objs = field.objs.borrow();
|
||||
let player = objs.iter().find(|o| o.obj_type() == "player").unwrap();
|
||||
assert_eq!(player.pos().y, height as f64 / 2. + 1.);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -27,9 +27,9 @@ mod game_field_tests {
|
||||
obj_id: 1,
|
||||
}];
|
||||
field.tick(inputs);
|
||||
let players = field.players();
|
||||
let player = players.first().unwrap();
|
||||
assert_eq!(player.obj.pos().y, height as f64 / 2. - 1.);
|
||||
let objs = field.objs.borrow();
|
||||
let player = objs.iter().find(|o| o.obj_type() == "player").unwrap();
|
||||
assert_eq!(player.pos().y, height as f64 / 2. - 1.);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -42,9 +42,9 @@ mod game_field_tests {
|
||||
obj_id: 1,
|
||||
}];
|
||||
field.tick(inputs);
|
||||
let players = field.players();
|
||||
let player = players.first().unwrap();
|
||||
assert_eq!(player.obj.pos().y, height as f64 - height as f64 / 5. / 2.);
|
||||
let objs = field.objs.borrow();
|
||||
let player = objs.iter().find(|o| o.obj_type() == "player").unwrap();
|
||||
assert_eq!(player.pos().y, height as f64 - height as f64 / 5. / 2.);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -57,8 +57,8 @@ mod game_field_tests {
|
||||
obj_id: 1,
|
||||
}];
|
||||
field.tick(inputs);
|
||||
let players = field.players();
|
||||
let player = players.first().unwrap();
|
||||
assert_eq!(player.obj.pos().y, height as f64 / 5. / 2.);
|
||||
let objs = field.objs.borrow();
|
||||
let player = objs.iter().find(|o| o.obj_type() == "player").unwrap();
|
||||
assert_eq!(player.pos().y, height as f64 / 5. / 2.);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,26 @@
|
||||
use rstest::rstest;
|
||||
use pong::game_object::components::{DefaultGeomComp, DefaultPhysicsComp};
|
||||
use pong::game_object::game_object::{DefaultGameObject, GameObject};
|
||||
use pong::geom::geom::{Vector};
|
||||
use pong::geom::geom::Vector;
|
||||
use pong::geom::shape::Shape;
|
||||
use rstest::rstest;
|
||||
|
||||
#[rstest]
|
||||
#[case(Vector::new(100., 100.), Vector::new(-1., 1.), Vector::new(99., 101.))]
|
||||
pub fn should_update_pos(#[case] start_pos: Vector, #[case] vel: Vector, #[case] expected_pos: Vector) {
|
||||
pub fn should_update_pos(
|
||||
#[case] start_pos: Vector,
|
||||
#[case] vel: Vector,
|
||||
#[case] expected_pos: Vector,
|
||||
) {
|
||||
let mut obj = DefaultGameObject::new(
|
||||
1,
|
||||
"obj".to_string(),
|
||||
Box::new(DefaultGeomComp::new(
|
||||
Shape::rect(Vector::new(start_pos.x as f64, start_pos.y as f64), Vector::new(1., 0.), 0., 0.)
|
||||
)),
|
||||
Box::new(DefaultPhysicsComp::new(
|
||||
vel, false
|
||||
))
|
||||
Box::new(DefaultGeomComp::new(Shape::rect(
|
||||
Vector::new(start_pos.x as f64, start_pos.y as f64),
|
||||
Vector::new(1., 0.),
|
||||
0.,
|
||||
0.,
|
||||
))),
|
||||
Box::new(DefaultPhysicsComp::new(vel, false)),
|
||||
);
|
||||
obj.update_pos();
|
||||
assert_eq!(*obj.pos(), expected_pos);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use rstest::rstest;
|
||||
use pong::geom::geom::Vector;
|
||||
use std::f64::consts::PI;
|
||||
use rstest::rstest;
|
||||
use std::f64::consts::FRAC_PI_2;
|
||||
use std::f64::consts::FRAC_PI_4;
|
||||
use std::f64::consts::PI;
|
||||
|
||||
#[rstest]
|
||||
#[case(1., 0., 1.)]
|
||||
@@ -39,7 +39,7 @@ pub fn should_normalize_correctly(
|
||||
pub fn should_calculate_angle_correctly(
|
||||
#[case] vector_a: Vector,
|
||||
#[case] vector_b: Vector,
|
||||
#[case] expected_angle: f64
|
||||
#[case] expected_angle: f64,
|
||||
) {
|
||||
let res = vector_a.angle(&vector_b);
|
||||
assert_eq!(res, expected_angle);
|
||||
@@ -49,10 +49,7 @@ pub fn should_calculate_angle_correctly(
|
||||
#[case(Vector::new(1., 0.), Vector::new(0., -1.))]
|
||||
#[case(Vector::new(0., 1.), Vector::new(1., 0.))]
|
||||
#[case(Vector::new(7., 7.), Vector::new(7., -7.))]
|
||||
pub fn should_get_orthogonal_clockwise(
|
||||
#[case] mut vector: Vector,
|
||||
#[case] expected: Vector
|
||||
) {
|
||||
pub fn should_get_orthogonal_clockwise(#[case] mut vector: Vector, #[case] expected: Vector) {
|
||||
vector.orthogonal_clockwise();
|
||||
assert_eq!(vector, expected);
|
||||
}
|
||||
@@ -63,7 +60,7 @@ pub fn should_get_orthogonal_clockwise(
|
||||
#[case(Vector::new(7., 7.), Vector::new(-7., 7.))]
|
||||
pub fn should_get_orthogonal_counter_clockwise(
|
||||
#[case] mut vector: Vector,
|
||||
#[case] expected: Vector
|
||||
#[case] expected: Vector,
|
||||
) {
|
||||
vector.orthogonal_counter_clockwise();
|
||||
assert_eq!(vector, expected);
|
||||
@@ -74,7 +71,7 @@ pub fn should_get_orthogonal_counter_clockwise(
|
||||
pub fn should_correctly_rotate(
|
||||
#[case] mut vector: Vector,
|
||||
#[case] radians: f64,
|
||||
#[case] expected: Vector
|
||||
#[case] expected: Vector,
|
||||
) {
|
||||
vector.rotate(radians);
|
||||
assert_eq!(vector, expected);
|
||||
@@ -87,8 +84,7 @@ pub fn should_correctly_rotate(
|
||||
pub fn should_calculate_dot_product(
|
||||
#[case] mut vector: Vector,
|
||||
#[case] mut other: Vector,
|
||||
#[case] expected: f64
|
||||
|
||||
#[case] expected: f64,
|
||||
) {
|
||||
let dot = vector.dot(&other);
|
||||
assert_eq!(dot, expected);
|
||||
@@ -134,4 +130,3 @@ pub fn should_reflect_vector(
|
||||
vector.reflect(&onto);
|
||||
assert_eq!(vector, expected);
|
||||
}
|
||||
|
||||
|
||||
54
src/lib.rs
54
src/lib.rs
@@ -1,15 +1,15 @@
|
||||
mod utils;
|
||||
|
||||
use pong::collision::collision::{Collision, CollisionDetector};
|
||||
use pong::game_field::{Field, Input, InputType};
|
||||
use pong::game_object::game_object::GameObject;
|
||||
use pong::geom::geom::Vector;
|
||||
use pong::geom::shape::ShapeType;
|
||||
use pong::utils::utils::Logger;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use std::cmp::{max, min};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use pong::collision::collision::{Collision, CollisionDetector};
|
||||
use pong::game_field::{Field, Input, InputType};
|
||||
use pong::game_object::game_object::{GameObject};
|
||||
use pong::geom::geom::Vector;
|
||||
use pong::geom::shape::ShapeType;
|
||||
use pong::utils::utils::Logger;
|
||||
|
||||
extern crate serde_json;
|
||||
extern crate web_sys;
|
||||
@@ -48,11 +48,11 @@ impl GameObjectDTO {
|
||||
y: pos.y as u16,
|
||||
shape_param_1: match shape {
|
||||
ShapeType::Rect(_, width, _) => *width as u16,
|
||||
ShapeType::Circle(_, radius) => *radius as u16
|
||||
ShapeType::Circle(_, radius) => *radius as u16,
|
||||
},
|
||||
shape_param_2: match shape {
|
||||
ShapeType::Rect(_, _, height) => *height as u16,
|
||||
ShapeType::Circle(_, _) => 0
|
||||
ShapeType::Circle(_, _) => 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -69,7 +69,7 @@ impl InputTypeDTO {
|
||||
pub fn to_input_type(&self) -> InputType {
|
||||
match self {
|
||||
InputTypeDTO::UP => InputType::UP,
|
||||
InputTypeDTO::DOWN => InputType::DOWN
|
||||
InputTypeDTO::DOWN => InputType::DOWN,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,22 +86,20 @@ impl InputDTO {
|
||||
return Input {
|
||||
input: self.input.to_input_type(),
|
||||
obj_id: self.obj_id,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct FieldWrapper {
|
||||
field: Field
|
||||
field: Field,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl FieldWrapper {
|
||||
pub fn new() -> FieldWrapper {
|
||||
let field = Field::new(Box::new(WasmLogger {}));
|
||||
FieldWrapper {
|
||||
field
|
||||
}
|
||||
FieldWrapper { field }
|
||||
}
|
||||
|
||||
pub fn width(&self) -> u16 {
|
||||
@@ -114,34 +112,16 @@ impl FieldWrapper {
|
||||
|
||||
pub fn tick(&mut self, inputs_js: &JsValue) {
|
||||
let input_dtos: Vec<InputDTO> = inputs_js.into_serde().unwrap();
|
||||
let inputs = input_dtos.into_iter().map(|i| i.to_input()).collect::<Vec<Input>>();
|
||||
let inputs = input_dtos
|
||||
.into_iter()
|
||||
.map(|i| i.to_input())
|
||||
.collect::<Vec<Input>>();
|
||||
self.field.tick(inputs);
|
||||
log!("{:?}", self.field.collisions);
|
||||
}
|
||||
|
||||
pub fn objects(&self) -> *const GameObjectDTO {
|
||||
let mut objs = vec![];
|
||||
objs.append(
|
||||
&mut self.field
|
||||
.balls
|
||||
.iter()
|
||||
.map(|ball| GameObjectDTO::from(&ball.obj))
|
||||
.collect::<Vec<GameObjectDTO>>(),
|
||||
);
|
||||
objs.append(
|
||||
&mut self.field
|
||||
.players
|
||||
.iter()
|
||||
.map(|player| GameObjectDTO::from(&player.obj))
|
||||
.collect::<Vec<GameObjectDTO>>(),
|
||||
);
|
||||
objs.append(
|
||||
&mut self.field
|
||||
.bounds.objs
|
||||
.iter()
|
||||
.map(|bound| GameObjectDTO::from(&bound))
|
||||
.collect::<Vec<GameObjectDTO>>()
|
||||
);
|
||||
let mut objs = self.field.objs.borrow().iter().map(|o| GameObjectDTO::from(o)).collect::<Vec<GameObjectDTO>>();
|
||||
objs.as_ptr()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user