wip - created geom & physics comp

This commit is contained in:
Thilo Behnke
2022-04-24 18:32:22 +02:00
parent 7426559b34
commit 86b1ac6052
7 changed files with 189 additions and 56 deletions

View File

@@ -1,6 +1,5 @@
use std::f64::consts::{FRAC_PI_2, FRAC_PI_4};
use crate::collision::collision::{Collision, CollisionDetector, CollisionHandler, CollisionRegistry, Collisions};
use crate::game_object::game_object::{GameObject, Shape};
use crate::game_object::game_object::{GameObject, ShapeType};
use crate::geom::geom::Vector;
use crate::utils::utils::{Logger, NoopLogger};
@@ -71,7 +70,7 @@ impl Field {
pub fn tick(&mut self, inputs: Vec<Input>) {
for ball in self.balls.iter_mut() {
if ball.obj.vel == Vector::zero() {
if ball.obj.physics.vel() == Vector::zero() {
ball.obj.set_vel_x(-2.)
}
}
@@ -85,10 +84,12 @@ impl Field {
let input = input_opt.unwrap();
match input.input {
InputType::UP => {
player.obj.vel.y = (player.obj.vel.y + 1.).min(5.);
let updated_vel_y = (player.obj.vel.y + 1.).min(5.);
player.obj.set_vel_y(updated_vel_y);
}
InputType::DOWN => {
player.obj.vel.y = (player.obj.vel.y - 1.).max(-5.);
let updated_vel_y = (player.obj.vel.y - 1.).max(-5.);
player.obj.set_vel_y(updated_vel_y);
}
};
}
@@ -170,7 +171,7 @@ impl Player {
id,
pos: Vector {x: x as f64, y: y as f64},
orientation: Vector::new(0., 1.),
shape: Shape::Rect,
shape: ShapeType::Rect,
shape_params: vec![field.width / 25, field.height / 5],
vel: Vector::zero(),
is_static: true,
@@ -191,7 +192,7 @@ impl Ball {
id,
pos: Vector {x: x as f64, y: y as f64},
orientation: Vector::zero(),
shape: Shape::Circle,
shape: ShapeType::Circle,
shape_params: vec![field.width / 80],
vel: Vector::zero(),
is_static: false,
@@ -214,7 +215,7 @@ impl Bounds {
id: 90,
pos: Vector {x: (width / 2) as f64, y: 0 as f64},
orientation: Vector::new(1., 0.),
shape: Shape::Rect,
shape: ShapeType::Rect,
shape_params: vec![width, 2],
is_static: true,
vel: Vector::zero(),
@@ -224,7 +225,7 @@ impl Bounds {
id: 91,
pos: Vector {x: (width / 2) as f64, y: height as f64},
orientation: Vector::new(-1., 0.),
shape: Shape::Rect,
shape: ShapeType::Rect,
shape_params: vec![width, 2],
is_static: true,
vel: Vector::zero(),
@@ -234,7 +235,7 @@ impl Bounds {
id: 92,
pos: Vector {x: 0 as f64, y: (height / 2) as f64},
orientation: Vector::new(0., 1.),
shape: Shape::Rect,
shape: ShapeType::Rect,
shape_params: vec![2, height],
is_static: true,
vel: Vector::zero(),
@@ -244,7 +245,7 @@ impl Bounds {
id: 93,
pos: Vector {x: width as f64, y: (height / 2) as f64},
orientation: Vector::new(0., -1.),
shape: Shape::Rect,
shape: ShapeType::Rect,
shape_params: vec![2, height],
is_static: true,
vel: Vector::zero(),

View File

@@ -1,53 +1,108 @@
pub mod game_object {
use crate::game_object::components::{GeomComp, PhysicsComp};
use crate::geom::geom::{BoundingBox, Vector};
#[derive(Clone, Debug, PartialEq)]
pub enum Shape {
Rect = 0,
Circle = 1,
}
use crate::geom::shape::ShapeType;
#[derive(Clone, Debug, PartialEq)]
pub struct GameObject {
pub id: u16,
pub pos: Vector,
pub orientation: Vector,
pub shape: Shape,
pub shape_params: Vec<u16>,
pub vel: Vector,
pub is_static: bool,
pub geom: Box<dyn GeomComp>,
pub physics: Box<dyn PhysicsComp>
}
impl GameObject {
pub fn update_pos(&mut self) {
self.pos.add(&self.vel);
let center = self.geom.center_mut();
center.add(&self.vel);
// Keep last orientation if vel is now zero.
if self.vel == Vector::zero() {
let vel = self.physics.vel();
if vel == Vector::zero() {
return;
}
let mut orientation = self.vel.clone();
let mut orientation = vel.clone();
orientation.normalize();
self.orientation = orientation;
}
pub fn set_vel_x(&mut self, x: f64) {
self.vel.x = x
let vel = self.physics.vel_mut();
vel.x = x;
}
pub fn set_vel_y(&mut self, y: f64) {
self.vel.y = y
let vel = self.physics.vel_mut();
vel.y = y;
}
pub fn bounding_box(&self) -> BoundingBox {
match self.shape {
Shape::Rect => {
BoundingBox::create(&self.pos, self.shape_params[0], self.shape_params[1])
}
Shape::Circle => {
BoundingBox::create(&self.pos, self.shape_params[0] * 2, self.shape_params[0] * 2)
}
}
self.geom.shape().bounding_box()
}
}
}
pub mod components {
use crate::geom::geom::Vector;
use crate::geom::shape::Shape;
pub trait GeomComp {
fn orientation(&self) -> &Vector;
fn orientation_mut(&mut self) -> &mut Vector;
fn center(&self) -> &Vector;
fn center_mut(&mut self) -> &mut Vector;
}
pub struct DefaultGeomComp {
shape: Box<dyn Shape>
}
impl DefaultGeomComp {
pub fn new(shape: Box<dyn Shape>) -> DefaultGeomComp {
DefaultGeomComp {shape}
}
}
impl GeomComp for DefaultGeomComp {
fn orientation(&self) -> &Vector {
&self.shape.orientation()
}
fn orientation_mut(&mut self) -> &mut Vector {
&mut self.shape.orientation()
}
fn center(&self) -> &Vector {
&self.shape.center()
}
fn center_mut(&mut self) -> &mut Vector {
&mut self.shape.center()
}
}
pub trait PhysicsComp {
fn vel(&self) -> &Vector;
fn vel_mut(&mut self) -> &mut Vector;
fn is_static(&self) -> bool;
}
pub struct DefaultPhysicsComp {
vel: Vector,
is_static: bool
}
impl DefaultPhysicsComp {
pub fn new(vel: Vector, is_static: bool) -> DefaultPhysicsComp {
DefaultPhysicsComp {vel, is_static}
}
}
impl PhysicsComp for DefaultPhysicsComp {
fn vel(&self) -> &Vector {
&self.vel
}
fn vel_mut(&mut self) -> &mut Vector {
&mut self.vel
}
fn is_static(&self) -> bool {
self.is_static
}
}
}

View File

@@ -143,29 +143,24 @@ pub mod geom {
}
impl BoundingBox {
pub fn create_from_coords(x: f64, y: f64, width: u16, height: u16) -> BoundingBox {
let center = Vector::new(x, y);
return BoundingBox::create(&center, width, height)
}
pub fn create(center: &Vector, width: u16, height: u16) -> BoundingBox {
pub fn create(center: &Vector, width: f64, height: f64) -> BoundingBox {
let center_x = center.x;
let center_y = center.y;
let top_left = Vector {
x: center_x - (width as f64 / 2.),
y: center_y + (height as f64 / 2.),
x: center_x - width / 2.,
y: center_y + height / 2.,
};
let top_right = Vector {
x: center_x + (width as f64 / 2.),
y: center_y + (height as f64 / 2.),
x: center_x + width / 2.,
y: center_y + height / 2.,
};
let bottom_left = Vector {
x: center_x - (width as f64 / 2.),
y: center_y - (height as f64 / 2.),
x: center_x - width / 2.,
y: center_y - height / 2.,
};
let bottom_right = Vector {
x: center_x + (width as f64 / 2.),
y: center_y - (height as f64 / 2.),
x: center_x + width / 2.,
y: center_y - height / 2.,
};
BoundingBox {
top_left,
@@ -242,3 +237,85 @@ pub mod geom {
}
}
}
pub mod shape {
use crate::geom::geom::{BoundingBox, Vector};
#[derive(Clone, Debug, PartialEq)]
pub enum ShapeType {
Rect = 0,
Circle = 1,
}
pub trait Shape {
fn center(&self) -> &Vector;
fn orientation(&self) -> &Vector;
fn shape_type(&self) -> ShapeType;
fn bounding_box(&self) -> BoundingBox;
}
pub struct Rect {
pub width: f64,
pub height: f64,
center: Vector,
orientation: Vector
}
impl Rect {
pub fn new(center: Vector, orientation: Vector, width: f64, height: f64) -> Rect {
Rect {
center, orientation, width, height
}
}
}
impl Shape for Rect {
fn center(&self) -> &Vector {
&self.center
}
fn orientation(&self) -> &Vector {
&self.orientation
}
fn shape_type(&self) -> ShapeType {
ShapeType::Rect
}
fn bounding_box(&self) -> BoundingBox {
BoundingBox::create(self.center(), self.width, self.height)
}
}
pub struct Circle {
pub radius: f64,
center: Vector,
orientation: Vector,
}
impl Circle {
pub fn new(center: Vector, orientation: Vector, radius: f64) -> Circle {
Circle {
center, orientation, radius
}
}
}
impl Shape for Circle {
fn center(&self) -> &Vector {
&self.center
}
fn orientation(&self) -> &Vector {
&self.orientation
}
fn shape_type(&self) -> ShapeType {
ShapeType::Circle
}
fn bounding_box(&self) -> BoundingBox {
BoundingBox::create(&self.center(), self.radius * 2, self.radius * 2)
}
}
}

View File

@@ -1,6 +1,6 @@
use rstest::rstest;
use pong::collision::collision::CollisionHandler;
use pong::game_object::game_object::{GameObject, Shape};
use pong::game_object::game_object::{GameObject, ShapeType};
use pong::geom::geom::Vector;
#[rstest]

View File

@@ -1,6 +1,6 @@
use rstest::rstest;
use pong::collision::collision::{Collision, CollisionDetector};
use pong::game_object::game_object::{GameObject, Shape};
use pong::game_object::game_object::{GameObject, ShapeType};
use pong::geom::geom::{Vector};
#[rstest]

View File

@@ -1,5 +1,5 @@
use rstest::rstest;
use pong::game_object::game_object::{GameObject, Shape};
use pong::game_object::game_object::{GameObject, ShapeType};
use pong::geom::geom::{Vector};
#[rstest]
@@ -9,7 +9,7 @@ pub fn should_update_pos(#[case] start_pos: Vector, #[case] vel: Vector, #[case]
id: 1,
pos: Vector::new(start_pos.x as f64, start_pos.y as f64),
vel,
shape: Shape::Rect,
shape: ShapeType::Rect,
shape_params: vec![],
is_static: false,
orientation: Vector::new(1., 0.)

View File

@@ -6,7 +6,7 @@ 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, Shape};
use pong::game_object::game_object::{GameObject, ShapeType};
use pong::geom::geom::Vector;
use pong::utils::utils::Logger;