Este juego es un clásico en 2D de "desplazamiento lateral" (o side-scroller en inglés): eso significa que lo estamos viendo de lado, y el personaje solo se mueve hacia adelante o hacia atrás. Sin embargo, siempre queremos a nuestro personaje en el centro de la pantalla, así que en realidad simulamos el movimiento aparente del personaje al mover el fondo detrás del personaje. Es un truco, ¡pero funciona!
Para empezar, solo vamos a dibujar la partes que no van a tener ningún movimiento, el cielo azul y el piso café:
draw = function() {
    background(227, 254, 255);
    fill(130, 79, 43);
    rect(0, height*0.90, width, height*0.10);
    // ...
}
Ahora, para crear esta apariencia de desplazamiento lateral, vamos a agregar pasto, con la imagen de pasto de la biblioteca de imágenes. Una manera de crear este ambiente en movimiento es pretender que nuestro lienzo es de 3000 pixeles de largo y que así de largo es nuestro nivel, y dibujar tantos bloques de pasto como sean necesarios para cubrir esos 3000 pixeles, moviéndolos en cada instante. Sin embargo, eso no es muy eficiente, y al programar juegos debemos preocuparnos mucho en la eficiencia. En cambio, vamos a usar las imágenes de pasto como "mosaicos" y a "serpentearlas". Solamente dibujaremos tantas como necesitemos para cubrir la pantalla de 400 pixeles y después cuando una caiga del lado izquierdo de la pantalla derecha, inmediatamente la pegaremos del lado derecho de la pantalla y continuaremos haciendo eso para siempre.
Para hacer eso, empezaremos por inicializar un arreglo de nuestras posiciones iniciales para los bloques de pasto:
var grassXs = [];
for (var i = 0; i < 25; i++) {
    grassXs.push(i*20);
}
Luego, dentro de nuestro bucle de draw, dibujaremos cada uno de ellos:
for (var i = 0; i < grassXs.length; i++) {
   image(getImage("cute/GrassBlock"), grassXs[i], height*0.85, 20, 20);
}
Eso se ve bien para una escena estática, ¡pero necesitamos que esto se mueva! Así que simplemente podemos restar uno de la posición de cada pasto a la vez, moviéndolos a la izquierda 1 pixel.
for (var i = 0; i < grassXs.length; i++) {
   image(getImage("cute/GrassBlock"), grassXs[i], height*0.85, 20, 20);
    grassXs[i] -= 1;
}
Ahora el pasto se estará moviendo, pero eventualmente desaparecerá, a medida que los valores de x se vuelvan más y más negativos. Recuerda, queremos "serpentear" los mosaicos: queremos repetirlos del lado derecho del lienzo una vez que desaparezcan por el lado izquierdo. Para hacer eso, verificamos si estamos suficientemente fuera de la pantalla (recuerda que nuestras imágenes están dibujadas desde la esquina superior izquierda) y, en caso afirmativo, hacemos el valor x igual al ancho del lienzo:
for (var i = 0; i < grassXs.length; i++) {
   image(getImage("cute/GrassBlock"), grassXs[i], height*0.85, 20, 20);
    grassXs[i] -= 1;
    if (grassXs[i] <= -20) {
        grassXs[i] = width;
    }
}
Juntándolo todo, ahora tenemos un castor que se ve como que se está moviendo mientras está brincando. ¡Magia!
Bien, tenemos un castor brincando a través de un ambiente que se desplaza lateralmente. ¡Pero el castor no tiene nada qué hacer ahí! Necesitamos agregar unos palos para que el castor brinque y los recoja.
Pensemos un poco acerca de nuestros palos, ya que necesitamos decidir cómo programarlos:
  • Cada palo tiene una posición x y y. Probablemente queramos las posiciones x distribuidas cada cierto valor (posiblemente constante o aleatorio dentro de un rango) y queramos las posiciones y aleatorizadas dentro de un rango, de modo que el usuario tenga que controlar los brincos y caídas del castor.
  • Los palos deben tener el mismo movimiento aparente que el pasto, pero no deben serpentear. Una vez que un palo esté fuera de la pantalla, desaparece para siempre.
  • Debe haber alguna cantidad fija de palos por nivel. En algún punto, debe de dejar de haber palos.
Hay muchas maneras en que podríamos programar nuestros palos, pero parecen suficientemente complejas, así que los modelaremos con un objeto, como modelamos a nuestro personaje de castor:
var Stick = function(x, y) {
    this.x = x;
    this.y = y;
};

Stick.prototype.draw = function() {
    fill(89, 71, 0);
    rect(this.x, this.y, 5, 40);
};
Entonces, antes de que nuestro juego comience a correr (como después de que inicialicemos a nuestro castor), vamos a crear un arreglo de 40 palos, con un desplazamiento constante y una y aleatoria:
var sticks = [];
for (var i = 0; i < 40; i++) {  
    sticks.push(new Stick(i * 40 + 300, random(20, 260)));
}
Ahora podemos dibujar los palos, de manera similar a como dibujamos el pasto, solo que sin envolverlos alrededor de la pantalla:
for (var i = 0; i < sticks.length; i++) {
    sticks[i].draw();
    sticks[i].x -= 1;
}
Aquí está, con los palos dibujados con ese código. ¡Trata de brincar por ellos! ¿Qué sucede? ¡Nada! Vamos a arreglar eso pronto...
Cargando