added update loop and game state.
This commit is contained in:
@@ -16,6 +16,7 @@ features = [
|
||||
"Document",
|
||||
"HtmlCanvasElement",
|
||||
"CanvasRenderingContext2d",
|
||||
"Performance",
|
||||
"console",
|
||||
]
|
||||
|
||||
|
||||
23
index.html
23
index.html
@@ -7,8 +7,27 @@
|
||||
<body style="margin:0; background:#222; display:flex; justify-content:center; align-items:center; height:100vh;">
|
||||
<canvas id="game-canvas"></canvas>
|
||||
<script type="module">
|
||||
import init from "./pkg/hyperbolic_asteroids.js";
|
||||
init();
|
||||
import init, { Game } from "./pkg/hyperbolic_asteroids.js";
|
||||
async function run() {
|
||||
await init();
|
||||
let game = new Game("game-canvas");
|
||||
let last = performance.now();
|
||||
|
||||
function loop(now) {
|
||||
const dt = (now - last);
|
||||
last = now;
|
||||
game.update(dt);
|
||||
game.draw();
|
||||
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
|
||||
//game.update(1);
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
|
||||
run();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
125
src/lib.rs
125
src/lib.rs
@@ -3,7 +3,7 @@ use std::f64;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement};
|
||||
//use web_sys::console;
|
||||
use web_sys::console;
|
||||
|
||||
mod cga;
|
||||
use cga::CGA;
|
||||
@@ -58,9 +58,9 @@ const E2: usize = 2;
|
||||
//const E12345: usize = 31;
|
||||
|
||||
struct Ship {
|
||||
_pos: CGA,
|
||||
_vel: CGA,
|
||||
_orientation: CGA,
|
||||
pos: CGA,
|
||||
//_vel: CGA,
|
||||
//_orientation: CGA,
|
||||
}
|
||||
|
||||
enum Geometry {
|
||||
@@ -97,7 +97,8 @@ fn point_to_screen_space(x: f64, y: f64) -> (f64, f64) {
|
||||
|
||||
fn draw_point(context: &CanvasRenderingContext2d, point: &CGA) {
|
||||
//Naively assume we are given a valid point
|
||||
let (x,y) = point_to_screen_space(point[E1], point[E2]);
|
||||
let (x,y) = get_point(point);
|
||||
let (x,y) = point_to_screen_space(x, y);
|
||||
|
||||
context.begin_path();
|
||||
context.set_fill_style_str(RED);
|
||||
@@ -105,6 +106,18 @@ fn draw_point(context: &CanvasRenderingContext2d, point: &CGA) {
|
||||
context.fill();
|
||||
}
|
||||
|
||||
//TODO Integrate into get geometry
|
||||
fn get_point(point: &CGA) -> (f64, f64) {
|
||||
let e_vec = CGA::e4();
|
||||
let e_bar = CGA::e5();
|
||||
let n_vec = &e_vec + &e_bar; //Null vector for the point at infinity.
|
||||
|
||||
let normalization = -(point | &n_vec)[SCALAR];
|
||||
let x = point[E1] / normalization;
|
||||
let y = point[E2] / normalization;
|
||||
(x,y)
|
||||
}
|
||||
|
||||
fn get_geometry(circle: &CGA) -> Geometry {
|
||||
//Naively assume we are given a valid line/circle
|
||||
let n_bar = CGA::e4() - CGA::e5();
|
||||
@@ -159,11 +172,103 @@ fn draw_line(context: &CanvasRenderingContext2d, line: &CGA) {
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
fn get_hyperbolic_translation(vec: &CGA) -> CGA {
|
||||
let vec_sqr = (vec * vec)[SCALAR];
|
||||
if vec_sqr >= 1. {
|
||||
panic!("Translation Vector Out of Bounds");
|
||||
}
|
||||
let message = format!("Get TX\nvec {} \nvecvec {}\nvec_sqr {}", vec, vec*vec, vec_sqr);
|
||||
console::log_1(&message.into());
|
||||
let t = 1.0 / ( 1. - vec_sqr).sqrt() * ( CGA::new(1., SCALAR) + CGA::e5()*vec);
|
||||
t
|
||||
}
|
||||
|
||||
fn get_hyperbolic_point(vec: &CGA) -> CGA {
|
||||
let vec_sqr = (vec * vec)[SCALAR];
|
||||
if vec_sqr >= 1. {
|
||||
panic!("Vector out of bounds");
|
||||
}
|
||||
|
||||
let p = 1. / (1. - vec_sqr)*(CGA::new(vec_sqr, SCALAR) + 2.*vec - (CGA::e4() - CGA::e5()));
|
||||
p
|
||||
}
|
||||
|
||||
struct Asteroid {
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Game {
|
||||
context: CanvasRenderingContext2d,
|
||||
ship: Ship,
|
||||
//asteroids: Vec::<Asteroid>,
|
||||
point: (f64, f64),
|
||||
//keys: HashSet<String>,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Game {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(canvas_id: &str) -> Self {
|
||||
let window = web_sys::window().unwrap();
|
||||
let document = window.document().unwrap();
|
||||
let canvas = document
|
||||
.get_element_by_id(canvas_id)
|
||||
.ok_or_else( || JsValue::from_str("Canvas not found")).unwrap()
|
||||
.dyn_into::<HtmlCanvasElement>().unwrap();
|
||||
canvas.set_width(WIDTH as u32);
|
||||
canvas.set_height(HEIGHT as u32);
|
||||
let context = canvas
|
||||
.get_context("2d").unwrap()
|
||||
.ok_or_else( || JsValue::from_str("Failed to get context")).unwrap()
|
||||
.dyn_into::<CanvasRenderingContext2d>().unwrap();
|
||||
|
||||
let ship = Ship { pos: get_hyperbolic_point(&CGA::zero()) };
|
||||
Game { context: context, point: (0.,0.), ship }
|
||||
}
|
||||
|
||||
pub fn draw(&self) {
|
||||
self.context.begin_path();
|
||||
self.context.set_fill_style_str(BACKGROUND);
|
||||
self.context.fill_rect(0.0, 0.0, WIDTH, HEIGHT);
|
||||
self.context.fill();
|
||||
self.context.set_stroke_style_str(BLACK);
|
||||
self.context.arc(CENTER_X, CENTER_Y, RADIUS, 0., TWO_PI).unwrap();
|
||||
self.context.stroke();
|
||||
|
||||
let x = self.point.0;
|
||||
let y = self.point.1;
|
||||
draw_point(&self.context, &self.ship.pos);
|
||||
|
||||
//self.context.begin_path();
|
||||
//self.context.set_fill_style_str(GREEN);
|
||||
//self.context.arc(x, y, 20., 0., TWO_PI).unwrap();
|
||||
//self.context.fill();
|
||||
|
||||
}
|
||||
|
||||
pub fn update(&mut self, dt: f64) { //dt in milliseconds
|
||||
let theta:f64 = 0.1;
|
||||
let vel:f64 = 1.*dt/1000.;
|
||||
let dir = theta.cos()*CGA::e1() + theta.sin()*CGA::e2();
|
||||
let vec = vel* &dir;
|
||||
|
||||
let tx = get_hyperbolic_translation(&vec);
|
||||
let txr = tx.Reverse();
|
||||
self.ship.pos = &tx * &self.ship.pos * &txr;
|
||||
|
||||
let norm = (&self.ship.pos | CGA::e4() )[SCALAR];
|
||||
self.ship.pos = &self.ship.pos * (1.0 / norm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Start entry point
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn start() -> Result<(), JsValue> {
|
||||
let _ship = Ship { _pos: point_to_cga(0.,0.), _vel: CGA::zero(), _orientation: CGA::zero() };
|
||||
// let _ship = Ship { _pos: point_to_cga(0.,0.), _vel: CGA::zero(), _orientation: CGA::zero() };
|
||||
|
||||
/*
|
||||
// Grab document and canvas
|
||||
let window = web_sys::window().unwrap();
|
||||
let document = window.document().unwrap();
|
||||
@@ -178,7 +283,7 @@ pub fn start() -> Result<(), JsValue> {
|
||||
let context = canvas
|
||||
.get_context("2d")?
|
||||
.unwrap()
|
||||
.dyn_into::<CanvasRenderingContext2d>()?;
|
||||
.dyn_into::<CanvasRenderingContext2d>().unwrap();
|
||||
|
||||
//Set up play area.
|
||||
context.begin_path();
|
||||
@@ -188,8 +293,8 @@ pub fn start() -> Result<(), JsValue> {
|
||||
context.set_stroke_style_str(BLACK);
|
||||
context.arc(CENTER_X, CENTER_Y, RADIUS, 0., TWO_PI).unwrap();
|
||||
context.stroke();
|
||||
|
||||
//Testing example lines and circles.
|
||||
*/
|
||||
/* //Testing example lines and circles.
|
||||
let point = point_to_cga(0.,0.);
|
||||
draw_point(&context, &point);
|
||||
|
||||
@@ -232,7 +337,7 @@ pub fn start() -> Result<(), JsValue> {
|
||||
let p2 = point_to_cga(0.9, -0.1);
|
||||
draw_point(&context, &p2);
|
||||
let circle = &p1 ^ &p2 ^ &CGA::e5() ^ &CGA::e3(); //Orthogonal to the line at infinity
|
||||
draw_line(&context, &circle);
|
||||
draw_line(&context, &circle);*/
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user