Skip to content

Instantly share code, notes, and snippets.

@misterhat
Last active January 27, 2018 08:58
Show Gist options
  • Save misterhat/028ef86ead1a8dcedcf052247b8673a4 to your computer and use it in GitHub Desktop.
Save misterhat/028ef86ead1a8dcedcf052247b8673a4 to your computer and use it in GitHub Desktop.
(function () {
var module = {};
// maps
var LOBBY = [
[ 1, 1, 1, 1, 1, 1, 1, 1 ],
[ 1, 0, 0, 0, 1, 0, 0, 1 ],
[ 1, 0, 0, 0, 1, 0, 0, 1 ],
[ 1, 0, 0, 0, 1, 0, 0, 1 ],
[ 1, 0, 0, 0, 1, 1, 0, 1 ],
[ 1, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 0, 0, 0, 0, 0, 0, 1 ],
[ 1, 1, 0, 0, 0, 0, 0, 1 ]
];
// components
function Player(o) {
o = o || {};
this.player = true;
this.x = o.x || 0;
this.y = o.y || 0;
this.dx = o.dx || 0;
this.dy = o.dy || 0;
this.speed = isNaN(+o.speed) ? 1 : +o.speed;
this.health = isNaN(+o.health) ? 10 : +o.health;
}
function Viewport(o) {
this.width = 10;
this.height = 10;
this.x = 0;
this.y = 0;
this.viewport = true;
}
function Map(o) {
var that = this,
i, j;
this.active = !!o.active;
this.width = o.map[0].length;
this.height = o.map.length;
this.map = new Uint8Array(this.width * this.height);
this.map.toJSON = function () {
var m = [],
i, j;
for (i = 0; i < that.height; i += 1) {
m.push([]);
for (j = 0; j < that.width; j += 1) {
m[m.length - 1].push(this[(i * that.width) + j]);
}
}
return JSON.stringify(m);
};
for (i = 0; i < this.height; i += 1) {
for (j = 0; j < this.width; j += 1) {
this.map[(i * this.width) + j] = o.map[i][j];
}
}
}
function Projectile(o) {
o = o || {};
this.x = o.x || 0;
this.y = o.y || 0;
this.dx = o.dx || 0;
this.dy = o.dy || 0;
this.damage = isNaN(+o.damage) ? 1 : +o.damage;
this.active = !!o.active;
}
function KeyMap() {
var map = {
38: 'up',
87: 'up',
40: 'down',
83: 'down',
37: 'left',
65: 'left',
39: 'right',
68: 'right'
},
that = this;
Object.keys(map).forEach(function (c) {
that[c] = map[c];
});
this.keyMap = true;
}
function KeyDown() {
var that = this;
[ 'up', 'down', 'left', 'right' ].forEach(function (k) {
that[k] = false;
});
this.keyDown = true;
}
// systems
function ControlSystem(game) {
var that = this;
this.keyMap = game.getEntities('keyMap')[0];
this.keyDown = game.getEntities('keyDown')[0];
console.log(this.keyMap, this.keyDown);
Object.keys(this.keyMap).forEach(function (k) {
that.keyDown[that.keyMap[k]] = false;
});
}
ControlSystem.EVENTS = {
keyup: function (e) {
var key = this.keyMap[e.which];
if (key) {
this.keyDown[key] = false;
}
e.preventDefault();
return false;
},
keydown: function (e) {
var key = this.keyMap[e.which];
if (key) {
this.keyDown[key] = true;
}
e.preventDefault();
return false;
}
};
ControlSystem.prototype.init = function () {
var that = this;
this.events = {};
Object.keys(ControlSystem.EVENTS).forEach(function (e) {
that.events[e] = ControlSystem.EVENTS[e].bind(that);
window.addEventListener(e, that.events[e], false);
});
};
ControlSystem.prototype.destroy = function () {
var that = this;
Object.keys(this.events).forEach(function (e) {
window.removeEventListener(e, that.events[e], false);
});
};
ControlSystem.prototype.loop = function () {
};
function MovementSystem(game) {
this.entities = game.getEntities('dx', 'dy');
}
MovementSystem.prototype.loop = function () {
};
// views
function FirstPersonView(game) {
this.dom = document.createElement('canvas');
this.dom.style.position = 'absolute';
this.dom.width = game.width;
this.dom.height = game.height;
this.ctx = this.dom.getContext('2d');
}
FirstPersonView.prototype.draw = function () {
};
function MinimapView(game) {
this.map = game.getEntities('map', 'active');
this.dom = document.createElement('canvas');
this.dom.style.position = 'absolute';
this.dom.style.border = '1px solid #f0f';
this.dom.width = game.width / 4;
this.dom.height = game.height / 4;
this.ctx = this.dom.getContext('2d');
}
MinimapView.prototype.draw = function () {
};
function DebugView(game) {
this.keyDown = game.getEntities('keyDown');
this.dom = document.createElement('div');
}
DebugView.prototype.draw = function () {
this.dom.innerText = JSON.stringify(this.keyDown);
};
// raycast.js
function RayCast(options) {
var that = this;
options = options || {};
this.options = options;
this.width = options.width || 640;
this.height = options.height || 480;
this.fps = options.fps || 24;
this.dom = document.createElement('div');
this.dom.className = 'raycast-wrap';
this.dom.style.position = 'relative';
this.entities = [
new Player(), new Map({ active: true, map: LOBBY }), new Projectile(),
new Viewport(), new KeyMap(), new KeyDown()
];
this.views = [ FirstPersonView, MinimapView,
DebugView ].map(function (View) {
var view = new View(that);
that.dom.appendChild(view.dom);
return view;
});
this.systems = [ ControlSystem ].map(function (System) {
return new System(that);
});
this.boundLoop = this.loop.bind(this);
}
RayCast.prototype.getEntities = function () {
var that = this,
attrs = Array.prototype.slice.call(arguments),
found = [];
this.entities.forEach(function (entity) {
var valid = true,
i;
for (i = 0; i < attrs.length; i += 1) {
if (typeof entity[attrs[i]] === 'undefined') {
return;
}
}
found.push(entity);
});
return found;
};
RayCast.prototype.loop = function () {
var i;
for (i = 0; i < this.views.length; i += 1) {
this.views[i].draw();
}
window.requestAnimationFrame(this.boundLoop);
};
RayCast.prototype.init = function () {
this.systems.forEach(function (system) {
if (typeof system.init === 'function') {
system.init();
}
});
this.loop();
};
RayCast.prototype.destroy = function () {
this.systems.forEach(function (system) {
if (typeof system.destroy === 'function') {
system.destroy();
}
});
};
var raycast = new RayCast();
document.body.innerHTML = '';
document.body.appendChild(raycast.dom);
console.log(JSON.stringify(raycast.entities));
raycast.init();
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment