Skip to content

Commit

Permalink
Chaning snake direction
Browse files Browse the repository at this point in the history
  • Loading branch information
radzionc committed Dec 30, 2019
1 parent 0d20950 commit ab12cef
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 8 deletions.
75 changes: 72 additions & 3 deletions src/lib.rs
Expand Up @@ -58,6 +58,15 @@ impl Vector {
pub fn normalize(&self) -> Vector {
self.scale_by(1_f64 / self.length())
}

pub fn equal_to(&self, other: &Vector) -> bool {
are_equal(self.x, other.x) && are_equal(self.y, other.y)
}

pub fn is_opposite(&self, other: &Vector) -> bool {
let sum = self.add(other);
sum.equal_to(&Vector::new(0_f64, 0_f64))
}
}

pub struct Segment<'a> {
Expand Down Expand Up @@ -107,6 +116,14 @@ fn get_food(width: i32, height: i32, snake: &[Vector]) -> Vector {
free_positions[index]
}

#[wasm_bindgen]
pub enum Movement {
TOP,
RIGHT,
DOWN,
LEFT,
}

#[wasm_bindgen]
pub struct Game {
pub width: i32,
Expand Down Expand Up @@ -141,7 +158,7 @@ impl Game {
}
}

fn process_movement(&mut self, timespan: f64) {
fn process_movement(&mut self, timespan: f64, movement: Option<Movement>) {
let distance = self.speed * timespan;
let mut tail: Vec<Vector> = Vec::new();
let mut snake_distance = distance;
Expand All @@ -162,11 +179,63 @@ impl Game {
self.snake = tail;
let old_head = self.snake.pop().unwrap();
let new_head = old_head.add(&self.direction.scale_by(distance));
if movement.is_some() {
let new_direction = match movement.unwrap() {
Movement::TOP => Vector {
x: 0_f64,
y: -1_f64,
},
Movement::RIGHT => Vector { x: 1_f64, y: 0_f64 },
Movement::DOWN => Vector { x: 0_f64, y: 1_f64 },
Movement::LEFT => Vector {
x: -1_f64,
y: 0_f64,
},
};
if !self.direction.is_opposite(&new_direction)
&& !self.direction.equal_to(&new_direction)
{
let Vector { x: old_x, y: old_y } = old_head;
let old_x_rounded = old_x.round();
let old_y_rounded = old_y.round();
let new_x_rounded = new_head.x.round();
let new_y_rounded = new_head.y.round();

let rounded_x_changed = !are_equal(old_x_rounded, new_x_rounded);
let rounded_y_changed = !are_equal(old_y_rounded, new_y_rounded);
if rounded_x_changed || rounded_y_changed {
let (old, old_rounded, new_rounded) = if rounded_x_changed {
(old_x, old_x_rounded, new_x_rounded)
} else {
(old_y, old_y_rounded, new_y_rounded)
};
let breakpoint_component = old_rounded
+ (if new_rounded > old_rounded {
0.5_f64
} else {
-0.5_f64
});
let breakpoint = if rounded_x_changed {
Vector::new(breakpoint_component, old_y)
} else {
Vector::new(old_x, breakpoint_component)
};
let vector =
new_direction.scale_by(distance - (old - breakpoint_component).abs());
let head = breakpoint.add(&vector);

self.snake.push(breakpoint);
self.snake.push(head);
self.direction = new_direction;
return;
}
}
}
self.snake.push(new_head);
}

pub fn process(&mut self, timespan: f64) {
self.process_movement(timespan);
pub fn process(&mut self, timespan: f64, movement: Option<Movement>) {
self.process_movement(timespan, movement);
}

pub fn get_snake(&self) -> Array {
Expand Down
24 changes: 24 additions & 0 deletions www/src/controller.js
@@ -0,0 +1,24 @@
import { Movement } from "wasm-snake-game";

const MOVEMENT_KEYS = {
[Movement.TOP]: [87, 38],
[Movement.RIGHT]: [68, 39],
[Movement.DOWN]: [83, 40],
[Movement.LEFT]: [65, 37]
}

const STOP_KEY = 32

export class Controller {
constructor(onStop = () => {}) {
window.addEventListener('keydown', ({ which }) => {
this.movement = Object.keys(MOVEMENT_KEYS).find(key => MOVEMENT_KEYS[key].includes(which))
})
window.addEventListener('keyup', ({ which }) => {
this.movement = undefined
if (which === STOP_KEY) {
onStop()
}
})
}
}
26 changes: 21 additions & 5 deletions www/src/game-manager.js
Expand Up @@ -2,6 +2,7 @@ import { Game, Vector } from 'wasm-snake-game'

import CONFIG from './config'
import { View } from './view'
import { Controller } from './controller'

export class GameManager {
constructor() {
Expand All @@ -11,6 +12,9 @@ export class GameManager {
this.game.height,
this.render.bind(this)
)
this.controller = new Controller(
this.onStop.bind(this)
)
}

restart() {
Expand All @@ -27,6 +31,16 @@ export class GameManager {
console.log(this.game)
}

onStop() {
const now = Date.now()
if (this.stopTime) {
this.stopTime = undefined
this.lastUpdate = this.time + now - this.lastUpdate
} else {
this.stopTime = now
}
}

render() {
this.view.render(
this.game.food,
Expand All @@ -38,12 +52,14 @@ export class GameManager {
}

tick() {
const lastUpdate = Date.now()
if (this.lastUpdate) {
this.game.process(lastUpdate - this.lastUpdate)
if (!this.stopTime) {
const lastUpdate = Date.now()
if (this.lastUpdate) {
this.game.process(lastUpdate - this.lastUpdate, this.controller.movement)
}
this.lastUpdate = lastUpdate
this.render()
}
this.lastUpdate = lastUpdate
this.render()
}

run() {
Expand Down

0 comments on commit ab12cef

Please sign in to comment.