Implemented basic asteroid, moved ship drawing and updating into impl Ship block.
This commit is contained in:
163
src/lib.rs
163
src/lib.rs
@@ -87,6 +87,70 @@ struct Ship {
|
|||||||
orientation: CGA,
|
orientation: CGA,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Ship {
|
||||||
|
fn update(&mut self, dt_s: f64, keys: &HashSet<String>) {
|
||||||
|
let vel = self.vel.clone(); //Velocity at beginning of frame
|
||||||
|
let mut vel_2 = self.vel.clone();
|
||||||
|
|
||||||
|
let mut a_vec = - DRAG * &vel_2;
|
||||||
|
|
||||||
|
if keys.contains("w") {
|
||||||
|
let orient = &self.orientation; //Transforms body frame to local frame
|
||||||
|
let pos = &self.com_rotor; //Transforms local frame to world frame
|
||||||
|
let accel_body = ACCEL_STR * CGA::e15(); //The acceleration in the body frame.
|
||||||
|
let accel_local = orient * accel_body * orient.Reverse(); //The acceleration in the local frame.
|
||||||
|
let accel_world = pos * accel_local * pos.Reverse(); //The acceleration in the world frame.
|
||||||
|
a_vec = a_vec - accel_world; //Sum of drag and thrust.
|
||||||
|
}
|
||||||
|
|
||||||
|
if keys.contains("q") {
|
||||||
|
self.orientation = bivector_exponential(&(dt_s * CGA::e12())) * &self.orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if keys.contains("e") {
|
||||||
|
self.orientation = bivector_exponential(&(-dt_s * CGA::e12())) * &self.orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vel_2 = vel_2 + a_vec*dt_s; //Velocity at end of frame
|
||||||
|
let vel_3 = 0.5*(vel+&vel_2);
|
||||||
|
let delta = vel_3 * dt_s;
|
||||||
|
let pos = bivector_exponential(&delta)*&self.com_rotor; //Update position.
|
||||||
|
self.vel = vel_2;
|
||||||
|
self.com_rotor = pos;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&self, context: &CanvasRenderingContext2d) {
|
||||||
|
let origin = gen_hyperbolic_point(&CGA::zero()); //Origin in the body frame.
|
||||||
|
let orient_rotor = &self.orientation; //Transforms body frame to local frame.
|
||||||
|
let com = &self.com_rotor; //Transforms local frame to world frame.
|
||||||
|
let v0_rotor = com*orient_rotor*bivector_exponential(&self.verts.0); //Combined transformation to locate a vertex of the ship in the world frame.
|
||||||
|
let v1_rotor = com*orient_rotor*bivector_exponential(&self.verts.1); //Combined transformation ...
|
||||||
|
let v2_rotor = com*orient_rotor*bivector_exponential(&self.verts.2); //Combined transformation ...
|
||||||
|
let p0 = &v0_rotor*&origin*&v0_rotor.Reverse(); //Produce a vertex of the ship in the world frame.
|
||||||
|
let p1 = &v1_rotor*&origin*&v1_rotor.Reverse(); //...
|
||||||
|
let p2 = &v2_rotor*&origin*&v2_rotor.Reverse(); //...
|
||||||
|
|
||||||
|
draw_point(context, &(com*&origin*com.Reverse()));
|
||||||
|
draw_point(context, &p0);
|
||||||
|
draw_point(context, &p1);
|
||||||
|
draw_point(context, &p2);
|
||||||
|
draw_line_between(context, &p0, &p1);
|
||||||
|
draw_line_between(context, &p1, &p2);
|
||||||
|
draw_line_between(context, &p2, &p0);
|
||||||
|
|
||||||
|
//Construct and draw line pointing straight ahead, to help orient the player.
|
||||||
|
let com_p = com * gen_hyperbolic_point(&CGA::zero()) * com.Reverse();
|
||||||
|
let delta_gen = com * orient_rotor * CGA::e14() * &orient_rotor.Reverse() * com.Reverse();
|
||||||
|
let dot = delta_gen | &com_p;
|
||||||
|
let line = CGA::e4() ^ com_p ^ dot ^ CGA::e3();
|
||||||
|
draw_line(context, &line);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum Geometry {
|
enum Geometry {
|
||||||
Circle(f64, f64, f64), //x,y,r
|
Circle(f64, f64, f64), //x,y,r
|
||||||
Line(f64, f64, f64), //x,r,theta
|
Line(f64, f64, f64), //x,r,theta
|
||||||
@@ -94,7 +158,7 @@ enum Geometry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Translation of a Euclidean Point. Need to use hyperbolic*/
|
/* Translation of a Euclidean Point. Need to use hyperbolic*/
|
||||||
fn _point_to_cga(x: f64, y: f64) -> CGA {
|
fn point_to_cga(x: f64, y: f64) -> CGA {
|
||||||
let x_vec = CGA::e1();
|
let x_vec = CGA::e1();
|
||||||
let y_vec = CGA::e2();
|
let y_vec = CGA::e2();
|
||||||
let _z_vec =CGA::e3(); //This game assumes everything takes place in the plane.
|
let _z_vec =CGA::e3(); //This game assumes everything takes place in the plane.
|
||||||
@@ -327,14 +391,48 @@ fn bivector_exponential(bivector: &CGA) -> CGA {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _Asteroid {
|
struct Asteroid {
|
||||||
|
circle: CGA,
|
||||||
|
vel: CGA,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Asteroid {
|
||||||
|
fn new() -> Asteroid {
|
||||||
|
let v = 0.1;
|
||||||
|
let (v_x, v_y) = (v * 1.0_f64.cos(), v*1.0_f64.sin());
|
||||||
|
let vel = v_x*CGA::e15() + v_y*CGA::e25();
|
||||||
|
Self::new_from_coords(0.0_f64, 0.0_f64, 0.1_f64, vel)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_from_coords(x: f64, y: f64, r: f64, vel: CGA) -> Asteroid {
|
||||||
|
let (a_x, a_y) = (x + r * 0.0_f64.cos(), y + r * 0.0_f64.sin());
|
||||||
|
let (b_x, b_y) = (x + r * 1.0_f64.cos(), y + r * 1.0_f64.sin());
|
||||||
|
let (c_x, c_y) = (x + r * 2.0_f64.cos(), y + r * 2.0_f64.sin());
|
||||||
|
let a = point_to_cga(a_x, a_y);
|
||||||
|
let b = point_to_cga(b_x, b_y);
|
||||||
|
let c = point_to_cga(c_x, c_y);
|
||||||
|
let circle = a^b^c^CGA::e3();
|
||||||
|
Asteroid { circle, vel }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, dt_s: f64) {
|
||||||
|
let vel = &self.vel;
|
||||||
|
let delta = vel * dt_s;
|
||||||
|
let vel_rotor = bivector_exponential(&delta);
|
||||||
|
let circle = &vel_rotor*&self.circle*&vel_rotor.Reverse();
|
||||||
|
self.circle = circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&self, context: &CanvasRenderingContext2d) {
|
||||||
|
draw_line(context, &self.circle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
context: CanvasRenderingContext2d,
|
context: CanvasRenderingContext2d,
|
||||||
ship: Ship,
|
ship: Ship,
|
||||||
//asteroids: Vec::<Asteroid>,
|
asteroids: Vec::<Asteroid>,
|
||||||
keys: HashSet<String>,
|
keys: HashSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,6 +466,7 @@ impl Game {
|
|||||||
Game {
|
Game {
|
||||||
context: context,
|
context: context,
|
||||||
ship,
|
ship,
|
||||||
|
asteroids: vec![Asteroid::new()],
|
||||||
keys: HashSet::new(),
|
keys: HashSet::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -380,31 +479,10 @@ impl Game {
|
|||||||
self.context.set_stroke_style_str(BLACK);
|
self.context.set_stroke_style_str(BLACK);
|
||||||
self.context.arc(CENTER_X, CENTER_Y, RADIUS, 0., TWO_PI).unwrap();
|
self.context.arc(CENTER_X, CENTER_Y, RADIUS, 0., TWO_PI).unwrap();
|
||||||
self.context.stroke();
|
self.context.stroke();
|
||||||
|
self.ship.draw(&self.context);
|
||||||
let origin = gen_hyperbolic_point(&CGA::zero()); //Origin in the body frame.
|
for asteroid in &self.asteroids {
|
||||||
let orient_rotor = &self.ship.orientation; //Transforms body frame to local frame.
|
asteroid.draw(&self.context);
|
||||||
let com = &self.ship.com_rotor; //Transforms local frame to world frame.
|
}
|
||||||
let v0_rotor = com*orient_rotor*bivector_exponential(&self.ship.verts.0); //Combined transformation to locate a vertex of the ship in the world frame.
|
|
||||||
let v1_rotor = com*orient_rotor*bivector_exponential(&self.ship.verts.1); //Combined transformation ...
|
|
||||||
let v2_rotor = com*orient_rotor*bivector_exponential(&self.ship.verts.2); //Combined transformation ...
|
|
||||||
let p0 = &v0_rotor*&origin*&v0_rotor.Reverse(); //Produce a vertex of the ship in the world frame.
|
|
||||||
let p1 = &v1_rotor*&origin*&v1_rotor.Reverse(); //...
|
|
||||||
let p2 = &v2_rotor*&origin*&v2_rotor.Reverse(); //...
|
|
||||||
|
|
||||||
draw_point(&self.context, &(com*&origin*com.Reverse()));
|
|
||||||
draw_point(&self.context, &p0);
|
|
||||||
draw_point(&self.context, &p1);
|
|
||||||
draw_point(&self.context, &p2);
|
|
||||||
draw_line_between(&self.context, &p0, &p1);
|
|
||||||
draw_line_between(&self.context, &p1, &p2);
|
|
||||||
draw_line_between(&self.context, &p2, &p0);
|
|
||||||
|
|
||||||
//Construct and draw line pointing straight ahead, to help orient the player.
|
|
||||||
let com_p = com * gen_hyperbolic_point(&CGA::zero()) * com.Reverse();
|
|
||||||
let delta_gen = com * orient_rotor * CGA::e14() * &orient_rotor.Reverse() * com.Reverse();
|
|
||||||
let dot = delta_gen | &com_p;
|
|
||||||
let line = CGA::e4() ^ com_p ^ dot ^ CGA::e3();
|
|
||||||
draw_line(&self.context, &line);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, dt_m: f64) {
|
pub fn update(&mut self, dt_m: f64) {
|
||||||
@@ -413,35 +491,12 @@ impl Game {
|
|||||||
} else {
|
} else {
|
||||||
dt_m / 1000.
|
dt_m / 1000.
|
||||||
};
|
};
|
||||||
let vel = self.ship.vel.clone(); //Velocity at beginning of frame
|
|
||||||
let mut vel_2 = self.ship.vel.clone();
|
|
||||||
|
|
||||||
let mut a_vec = - DRAG * &vel_2;
|
for asteroid in &mut self.asteroids {
|
||||||
|
asteroid.update(dt_s);
|
||||||
if self.keys.contains("w") {
|
|
||||||
let orient = &self.ship.orientation; //Transforms body frame to local frame
|
|
||||||
let pos = &self.ship.com_rotor; //Transforms local frame to world frame
|
|
||||||
let accel_body = ACCEL_STR * CGA::e15(); //The acceleration in the body frame.
|
|
||||||
let accel_local = orient * accel_body * orient.Reverse(); //The acceleration in the local frame.
|
|
||||||
let accel_world = pos * accel_local * pos.Reverse(); //The acceleration in the world frame.
|
|
||||||
a_vec = a_vec - accel_world; //Sum of drag and thrust.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.keys.contains("q") {
|
self.ship.update(dt_s, &self.keys);
|
||||||
self.ship.orientation = bivector_exponential(&(dt_s * CGA::e12())) * &self.ship.orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.keys.contains("e") {
|
|
||||||
self.ship.orientation = bivector_exponential(&(-dt_s * CGA::e12())) * &self.ship.orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vel_2 = vel_2 + a_vec*dt_s; //Velocity at end of frame
|
|
||||||
let vel_3 = 0.5*(vel+&vel_2);
|
|
||||||
let delta = vel_3 * dt_s;
|
|
||||||
let pos = bivector_exponential(&delta)*&self.ship.com_rotor; //Update position.
|
|
||||||
self.ship.vel = vel_2;
|
|
||||||
self.ship.com_rotor = pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn key_down(&mut self, key: String) {
|
pub fn key_down(&mut self, key: String) {
|
||||||
|
|||||||
Reference in New Issue
Block a user