Skip to content

Instantly share code, notes, and snippets.

@tlhunter
Created April 18, 2016 03:00
Show Gist options
  • Save tlhunter/9a3bce6f28d0c35e2b0c308b5dc7c275 to your computer and use it in GitHub Desktop.
Save tlhunter/9a3bce6f28d0c35e2b0c308b5dc7c275 to your computer and use it in GitHub Desktop.
'use strict';
/**
* Experimenting with building a better grid based entity management system
* Uses more efficient Map/Set calls, requiring modern browsers / Node.js
*/
const SPAWNS = [
{x: 1, y: 1},
{x: 1, y: 2},
{x: 1, y: 3},
{x: 7, y: 1},
{x: 7, y: 2},
{x: 7, y: 3}
];
const MAX_ENEMY = 100;
let enemies = []; // All enemies, incl unspawned, alive, dead
let spawn_marker = -1;
let locations = new Map();
let spawns = new Set();
// Create Enemies
for (let i = 0; i < MAX_ENEMY; i++) {
enemies.push({
id: i,
alive: null,
avatar: {
opacity: 0
},
ticks: 0,
x: -1,
y: -1
});
}
// Generated from map data
for (let i = 0; i < SPAWNS.length; i++) {
spawns.add({x: SPAWNS[i].x, y: SPAWNS[i].y});
}
function spawn(x, y, id) {
// console.log('spawn()', x, y, id);
if (locationOccupied({x, y})) {
// console.error('cannot spawn', x, y, id);
return null;
}
let enemy = enemies[id];
enemy.alive = true;
enemy.avatar.opacity = 1;
enemy.x = x;
enemy.y = y;
locationSet(enemy, enemy);
return enemy;
}
function spawnWave() {
let ceil = spawn_marker + SPAWNS.length;
for (let c of spawns) {
spawn_marker += 1;
spawn(c.x, c.y, spawn_marker);
}
}
function tick(fn) {
// Game gets slightly slower over time
for (let i = 0; i <= spawn_marker; i++) {
if (!enemies[i].alive) {
continue;
}
fn(enemies[i]); // Keep tick logic out of library
}
}
function slay(id) {
// console.log('slay()', id);
let enemy = enemies[id];
locationRemove(enemy);
enemy.alive = false; // need to skip slain enemies when iterating enemy pool
enemy.avatar.opacity = 0;
}
function move(dest, id) {
// console.log('move()', dest, id);
let enemy = enemies[id];
if (!locationOccupied(enemy)) {
// console.error(`move() enemy ${id} doesn't exist in locations`);
return false;
}
if (locationOccupied(dest)) {
// console.error("move() destination already exists", dest);
return false;
}
locationRemove(enemy);
enemy.x = dest.x;
enemy.y = dest.y;
locationSet(dest, enemy);
return true;
}
function locationOccupied(loc) {
return locations.has(`${loc.x},${loc.y}`);
}
function locationRemove(loc) {
return locations.delete(`${loc.x},${loc.y}`);
}
function locationSet(loc, item) {
return locations.set(`${loc.x},${loc.y}`, item);
}
function randomCoord() {
return {
x: Math.floor(Math.random() * 20),
y: Math.floor(Math.random() * 20)
};
}
const start = +(new Date());
spawnWave();
slay(0);
slay(1);
slay(2);
slay(3);
tick(enemy => {
enemy.ticks++;
});
// slay(4);
move(randomCoord(), 4);
// slay(5);
spawnWave();
move(randomCoord(), 6);
move(randomCoord(), 7);
move(randomCoord(), 8);
move(randomCoord(), 9);
tick(enemy => {
enemy.ticks++;
});
spawnWave();
spawnWave();
spawnWave();
spawnWave();
spawnWave();
spawnWave();
const end = +(new Date());
console.log(locations);
console.log('TIME', end-start, 'ms');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment