Skip to content

Instantly share code, notes, and snippets.

@rafinskipg
Last active August 29, 2015 13:57
Show Gist options
  • Save rafinskipg/9887525 to your computer and use it in GitHub Desktop.
Save rafinskipg/9887525 to your computer and use it in GitHub Desktop.
Example of functional style refactor
//First version, it does the update for a lot of entities in a canvas based game.
function updateEntities(dt) {
// Update the player sprite animation
player.sprite.update(dt);
// Update all the bullets
for(var i=0; i<bullets.length; i++) {
var bullet = bullets[i];
bullets[i].sprite.update(dt);
switch(bullet.dir) {
case 'up': bullet.pos[1] -= bulletSpeed * dt; break;
case 'down': bullet.pos[1] += bulletSpeed * dt; break;
default:
bullet.pos[0] += bulletSpeed * dt;
}
// Remove the bullet if it goes offscreen
if(bullet.pos[1] < 0 || bullet.pos[1] > canvas.height ||
bullet.pos[0] > canvas.width) {
bullets.splice(i, 1);
i--;
}
}
// Update all the enemies
for(var i=0; i<enemies.length; i++) {
enemies[i].pos[0] -= enemies[i].speed * dt;
enemies[i].sprite.update(dt);
// Remove if offscreen
if(enemies[i].pos[0] + enemies[i].sprite.size[0] < 0) {
enemies.splice(i, 1);
i--;
}
}
for(var i=0; i<bombs.length; i++) {
bombs[i].sprite.update(dt);
// Remove if animation is done
if(bombs[i].sprite.done) {
bombareas.push(getEntity('bombarea',bombs[i].pos));
bombs.splice(i, 1);
i--;
playSound(SOUNDS.explosion);
}
}
for(var i = 0; i<bombareas.length; i++){
bombareas[i].sprite.update(dt);
//Remove if animation is done
if(bombareas[i].sprite.done){
bombareas.splice(i,1);
i--;
}
}
for(var i = 0; i<specials.length; i++){
specials[i].pos = [player.pos[0]+ player.width,player.pos[1]- player.height/2] ;
specials[i].sprite.update(dt);
//Remove if animation is done
if(specials[i].sprite.done){
specials.splice(i,1);
i--;
}
}
// Update all the explosions
for(var i=0; i<explosions.length; i++) {
explosions[i].sprite.update(dt);
// Remove if animation is done
if(explosions[i].sprite.done) {
explosions.splice(i, 1);
i--;
}
}
}
//The function, once is refactored
function updateEntities(dt) {
player.sprite.update(dt);
updateBullets(dt);
updateEnemies(dt);
updateBombs(dt);
updateBombAreas(dt);
updateSpecials(dt);
updateExplosions(dt);
}
/* Some helpers that can be reused*/
function moveInFrontOfPlayer(entity){
entity.pos = [player.pos[0]+ player.width,player.pos[1]- player.height/2];
return entity;
}
function updateSprite(dt){
return function(entity){
entity.sprite.update(dt);
return entity;
}
}
function moveToDirection(dt){
return function(entity){
switch(entity.dir) {
case 'up': entity.pos[1] -= entity.speed * dt; break;
case 'down': entity.pos[1] += entity.speed * dt; break;
case 'left': entity.pos[0] -= entity.speed * dt; break;
default:
entity.pos[0] += entity.speed * dt;
}
return entity;
}
}
function removeIfOutsideScreen(entity){
if(entity.pos[1] < 0 || entity.pos[1] > canvas.height ||
entity.pos[0] > canvas.width) {
return void 0;
}else{
return entity;
}
}
function pushBombIfDone(entity){
if(entity.sprite.done){
bombareas.push(getEntity('bombarea',entity.pos));
playSound(SOUNDS.explosion);
}
return entity;
}
function removeIfDone(entity){
if(!entity.sprite.done){
return entity;
}
}
function updateNormalEntities(entities, dt){
return hu.compact(
entities.map(updateSprite(dt))
.map(removeIfDone)
);
}
/* Updates */
function updateBullets(dt){
bullets = hu.compact(
bullets.map(updateSprite(dt))
.map(moveToDirection(dt))
.map(removeIfOutsideScreen)
);
}
function updateEnemies(dt){
enemies = hu.compact(
enemies.map(moveToDirection(dt))
.map(updateSprite(dt))
.map(removeIfOutsideScreen));
}
function updateBombs(dt){
bombs = hu.compact(
bombs.map(updateSprite(dt))
.map(pushBombIfDone)
.map(removeIfDone));
}
function updateBombAreas(dt){
bombareas = updateNormalEntities(bombareas,dt);
}
function updateSpecials(dt){
specials = updateNormalEntities(specials.map(moveInFrontOfPlayer), dt);
}
function updateExplosions(dt){
explosions = updateNormalEntities(explosions, dt);
}
@ajspadial
Copy link

Have you found any performance drawback?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment