Algoritmo principal de un juego HTML5 y Javascript

Últimamente estoy atraído por los juegos en plataforma web y aunque ya hay documentación de frameworks y código fuente de juegos, me ha costado encontrar el primer paso.

Ahora lo recopilo y complemento, para compartir los fundamentos y líneas principales sobre un algoritmo principal de un juego HTML5 y Javascript para empezar a desarrollar juegos web.

Este ejemplo ilustra cómo visualizar un personaje y moverle con las flechas del teclado.

Vista general

 // Iniciar canvas y contexto 
var canvas = $('#elemento-juego'); 
var contexto = canvas.get(0).getContext('2d'); 
// Controles del juego: eventos 
// (Ver más adelante) 
function nuevaPartida() { 
  // Arranca 
  inicializacionObjetos(); 
  // Pinta 
  renderizarObjetos(); 
  // Actualiza 
  actualizarPartida(); 
}

Inicialización

Instrucciones a realizar una vez, al crear una nueva partida: crear personajes, mostrar fondos, etc.

function inicializacionObjetos() { 
  // Calcula la posicion donde va a aparecer inicialmente el personaje (respawn) 
 // Este ejemplo lo centra en pantalla. 
 // Consideramos que la imagen ocupa 50px de ancho y alto (mitad = 25px) 
 var coordenadasY = window.innerHeight / 2 - 25; 
 var coordenadasX = window.innerWidth / 2 - 25; 
 // Inicia el objeto que visualiza al personaje con las coordenadas 

 var spriteJugador = new Jugador('img/jugador.png', coordenadasX, coordenadasY); 
}
 
function Jugador(src, x, y) { 
  this.imagen = new Image(); 
  this.imagen.src = src; 
  this.x = x; 
  this.y = y; 
  this.arriba = false; 
  this.abajo = false; 
  this.izda = false; 
  this.dcha = false; 
}

Controles

Gestiona los input que hace el jugador: pulsaciones del teclado, movimientos del ratón, etc.

$(window).keyup(function(e){ 
  var keyCode = e.keyCode; 
  if(keyCode == 37){ 
    spriteJugador.izda = true; 
  } else if(keyCode == 38){ 
    spriteJugador.arriba = true; 
  } else if(keyCode == 39){ 
    spriteJugador.dcha = true; 
  } else if (keyCode == 40){ 
    spriteJugador.abajo = true; 
  } 
});

Lógica

Calcula las variables del juego en función de la interacción del jugador, el paso anterior

function procesarJugada() { 
  // Comprobacion de movimientos 
  // Eje Y - Vertical 
  if (spriteJugador.arriba) { 
    spriteJugador.y = spriteJugador.y + 1; 
  } else if (spriteJugador.abajo) { 
    spriteJugador.y = spriteJugador.y - 1; 
  } 
 
  // Eje X - Horizontal 
  if (spriteJugador.dcha) { 
    spriteJugador.x = spriteJugador.x + 1; 
  } else if (spriteJugador.izda) { 
    spriteJugador.x = spriteJugador.x - 1; 
  } 
  // Reseteo 
  spriteJugador.izda = false; 
  spriteJugador.arriba = false; 
  spriteJugador.dcha = false; 
  spriteJugador.abajo = false; 
}

Redibujado

Sencillamente, actualiza en pantalla cada personaje, fondo, etc.

function renderizarObjetos() { 
  // variable global contexto -> canvas asociado al objeto 
  // Elimina la imagen del personaje anterior. 
  // Si no, no se produce sensación movimiento sino que se van añadiendo fotogramas 
  contexto.clearRect(0, 0, canvas.width(), canvas.height()); 
  // Mueve la posicion del jugador 
  contexto.drawImage(spriteJugador.imagen, spriteJugador.x, spriteJugador.y); 
}

Partida

El hilo conductor de todo lo anterior

function actualizarPartida() { 
  // A partir de los eventos, actualiza las variables/objetos 
  procesarJugada(); 
  // Simplemente actualiza las posiciones de los objetos 
  renderizarObjetos(); 
  // Cada 25 ms (fps) se invoca a sí mismo para actualizar la pantalla 
  setTimeout(actualizarPartida, 25); 
}

Puedes profundizar sobre el tema y seguir aprendiendo en HTML5Rocks Canvas + Game. Si tienes dudas o preguntas, ¡comenta!