Contenido principal
Curso: Programación de computadoras > Unidad 4
Lección 4: Hacer un juego de desplazamiento lateral: Castor SaltarínEl ambiente del bosque
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...
¿Quieres unirte a la conversación?
- No me gusta :( me encantaría que fuera en guías paso a paso con audio:( así no entiendo nada..... Soy muy bruta(12 votos)
- si me gusta mas con audio y en realidad no leo nada :v(3 votos)
- no entendí muy bien lo de como se mueve el pasto y los palos(5 votos)
- Básicamente el tema está aquí (Es el ciclo for el que hace toda la magia analízalo):
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;
}
}(1 voto)
- Desafio: PONG
PASO 1 MORROS
//Control Player 1
if(keyIsPressed && keyCode){
if (keyCode === UP){
movePlayerUp();
}
else if (keyCode === DOWN) {
movePlayerDown();
}
}
PASO 2
//Constrain the player movement
player1Y = constrain(player1Y, 0, 400);(5 votos) - Hola!, tengo un problema con mi funcion random, en vez de crear mi función en el mismo lado, mi código dibuja la función una y otra vez, sin necesidad de darle al Restart(1 voto)
- hola,
¿por que seria infinito el bucle si en un momento i sera 26 y no se podra ejecutar el codigo dentro del bucle?
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;
}
}
gracias.(1 voto)- no es infinito, mas bien los llegan a -20 pixeles como se transporta a 400 pixeles(1 voto)
- Hola soy Ángel i como podemos cambiar de paisaje?(1 voto)
- hola! vas al código donde dice:
image(getImage("cute/GrassBlock"), grassXs[i], height*0.85, 20, 20);
grassXs[i] -= 1;
if (grassXs[i] <= -20) {
grassXs[i] = width;
}
y cambias la imagen del fondo.(0 votos)
- Hola. no entiendo muy bien esta parte del código, alguien podría explicarme?
if (grassXs[i] <= -20) {
grassXs[i] = width;
}
}(0 votos)- Esta parte hace el castor parecer que está moviendo. El código chequea si el valor x del bloque de césped está menor o igual a viente negativo. Si es, el valor x está asignado 400.(1 voto)