Skip to content

Commit

Permalink
Moved Bitmap, Controls, and GameLoop over to Reason
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy Morrell committed Jul 17, 2017
1 parent d88b237 commit 994c1cf
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 65 deletions.
12 changes: 12 additions & 0 deletions src/Bitmap.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

type t = {
image: Image.t,
width: int,
height: int,
};

let make src width height => {
let image = Image.make width height;
Image.setSrc image src;
[%bs.obj { image, width, height }];
};
79 changes: 79 additions & 0 deletions src/Controls.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@

open Bs_webapi.Dom;

/* Magic event translation functions */
external eventToKeyboardEvent : Dom.event => KeyboardEvent.t = "%identity";
external eventToTouchEvent : Dom.event => TouchEvent.t = "%identity";

type states = {
left: bool,
right: bool,
forward: bool,
backward: bool,
};

type t = ref states;

type direction = Left | Right | Forward | Backward;

let empty = { left: false, right: false, forward: false, backward: false };

let getCode keyCode => {
switch (keyCode) {
| "ArrowUp" => Some Forward
| "ArrowLeft" => Some Left
| "ArrowRight" => Some Right
| "ArrowDown" => Some Backward
| _ => None
};
};

let updateState controls value direction => {
switch (direction) {
| Some Left => controls := {...(!controls), left: value }
| Some Forward => controls := {...(!controls), forward: value }
| Some Backward => controls := {...(!controls), backward: value }
| Some Right => controls := {...(!controls), right: value }
| None => ()
};
};

let onKey controls value e => {
Event.preventDefault e;
Event.stopPropagation e;
let direction = e |> eventToKeyboardEvent |> KeyboardEvent.code |> getCode;
updateState controls value direction;
};

let onTouch controls e => {
controls := empty;
Event.preventDefault e;
Event.stopPropagation e;
/* TODO: Bs_webapi doesn't have support for getting touch event info yet */
let _touches = TouchEvent.touches (eventToTouchEvent e);
};

let onTouchEnd controls e => {
controls := empty;
Event.preventDefault e;
Event.stopPropagation e;
};

let make _ => {
let controls = ref empty;
Document.addEventListener "keydown" (onKey controls true) document;
Document.addEventListener "keyup" (onKey controls false) document;
Document.addEventListener "touchstart" (onTouch controls) document;
Document.addEventListener "touchmove" (onTouch controls) document;
Document.addEventListener "touchend" (onTouchEnd controls) document;
controls;
};

let getStates controls => {
[%bs.obj {
left: (!controls).left,
right: (!controls).right,
forward: (!controls).forward,
backward: (!controls).backward,
} ];
};
23 changes: 23 additions & 0 deletions src/GameLoop.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

open Bs_webapi;

type t = {
lastTime: float,
callback: (float => unit),
};

let make lastTime callback => { lastTime, callback };

let rec frame loop time => {
let seconds = (time -. loop.lastTime) /. 1000.;
if (seconds < 0.2) {
loop.callback seconds;
};
let newLoop = make time loop.callback;
requestAnimationFrame (frame newLoop);
};

let start callback => {
let loop = make 0. callback;
requestAnimationFrame (frame loop);
};
4 changes: 4 additions & 0 deletions src/Image.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
type t;

external make: int => int => t = "Image" [@@bs.new];
external setSrc : t => string => unit = "src" [@@bs.set];
72 changes: 9 additions & 63 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,50 +1,15 @@
var CIRCLE = Math.PI * 2;
var MOBILE = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)

function Controls() {
this.codes = { 37: 'left', 39: 'right', 38: 'forward', 40: 'backward' };
this.states = { 'left': false, 'right': false, 'forward': false, 'backward': false };
document.addEventListener('keydown', this.onKey.bind(this, true), false);
document.addEventListener('keyup', this.onKey.bind(this, false), false);
document.addEventListener('touchstart', this.onTouch.bind(this), false);
document.addEventListener('touchmove', this.onTouch.bind(this), false);
document.addEventListener('touchend', this.onTouchEnd.bind(this), false);
}

Controls.prototype.onTouch = function(e) {
var t = e.touches[0];
this.onTouchEnd(e);
if (t.pageY < window.innerHeight * 0.5) this.onKey(true, { keyCode: 38 });
else if (t.pageX < window.innerWidth * 0.5) this.onKey(true, { keyCode: 37 });
else if (t.pageY > window.innerWidth * 0.5) this.onKey(true, { keyCode: 39 });
};

Controls.prototype.onTouchEnd = function(e) {
this.states = { 'left': false, 'right': false, 'forward': false, 'backward': false };
e.preventDefault();
e.stopPropagation();
};

Controls.prototype.onKey = function(val, e) {
var state = this.codes[e.keyCode];
if (typeof state === 'undefined') return;
this.states[state] = val;
e.preventDefault && e.preventDefault();
e.stopPropagation && e.stopPropagation();
};

function Bitmap(src, width, height) {
this.image = new Image();
this.image.src = src;
this.width = width;
this.height = height;
}
const Bitmap = require('./Bitmap.re');
const GameLoop = require('./GameLoop.re');
const Controls = require('./Controls.re');

function Player(x, y, direction) {
this.x = x;
this.y = y;
this.direction = direction;
this.weapon = new Bitmap('assets/knife_hand.png', 319, 320);
this.weapon = Bitmap.make('assets/knife_hand.png', 319, 320);
this.paces = 0;
}

Expand All @@ -70,8 +35,8 @@ Player.prototype.update = function(controls, map, seconds) {
function GameMap(size) {
this.size = size;
this.wallGrid = new Uint8Array(size * size);
this.skybox = new Bitmap('assets/deathvalley_panorama.jpg', 2000, 750);
this.wallTexture = new Bitmap('assets/wall_texture.jpg', 1024, 1024);
this.skybox = Bitmap.make('assets/deathvalley_panorama.jpg', 2000, 750);
this.wallTexture = Bitmap.make('assets/wall_texture.jpg', 1024, 1024);
this.light = 0;
}

Expand Down Expand Up @@ -224,34 +189,15 @@ Camera.prototype.project = function(height, angle, distance) {
};
};

function GameLoop() {
this.frame = this.frame.bind(this);
this.lastTime = 0;
this.callback = function() {};
}

GameLoop.prototype.start = function(callback) {
this.callback = callback;
requestAnimationFrame(this.frame);
};

GameLoop.prototype.frame = function(time) {
var seconds = (time - this.lastTime) / 1000;
this.lastTime = time;
if (seconds < 0.2) this.callback(seconds);
requestAnimationFrame(this.frame);
};

var display = document.getElementById('display');
var player = new Player(15.3, -1.2, Math.PI * 0.3);
var map = new GameMap(32);
var controls = new Controls();
var controls = Controls.make();
var camera = new Camera(display, MOBILE ? 160 : 320, 0.8);
var loop = new GameLoop();
map.randomize();

loop.start(function frame(seconds) {
GameLoop.start(function frame(seconds) {
map.update(seconds);
player.update(controls.states, map, seconds);
player.update(Controls.getStates(controls), map, seconds);
camera.render(player, map);
});
2 changes: 0 additions & 2 deletions src/index.re
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
[%bs.raw {|require('./app.js')|}];

/* Let's do this! */

0 comments on commit 994c1cf

Please sign in to comment.