Obstáculos del juego
Presiona los botones para mover el cuadrado rojo:
Añadir algunos obstáculos
Ahora queremos agregar algunos obstáculos a nuestro juego.
Agregue un nuevo componente al área de juego. Hágalo verde, 10 px de ancho, 200 px de alto, y colóquelo 300 px a la derecha y 120 px hacia abajo.
También actualice el componente de obstáculos en cada cuadro:
Ejemplo
var myGamePiece;
var myObstacle;
function startGame() {
myGamePiece = new component(30, 30, "red", 10, 120);
myObstacle = new component(10, 200, "green", 300, 120);
myGameArea.start();
}
function updateGameArea() {
myGameArea.clear();
myObstacle.update();
myGamePiece.newPos();
myGamePiece.update();
}
Golpea el obstáculo = fin del juego
En el ejemplo anterior, no sucede nada cuando golpeas el obstáculo. En un juego, eso no es muy satisfactorio.
¿Cómo sabemos si nuestro cuadrado rojo golpea el obstáculo?
Cree un nuevo método en el constructor del componente, que verifique si el componente falla con otro componente. Este método debe llamarse cada vez que se actualicen los marcos, 50 veces por segundo.
También agregue un stop()
método al myGameArea
objeto, que borra el intervalo de 20 milisegundos.
Ejemplo
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 480;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.interval = setInterval(updateGameArea, 20);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
stop : function() {
clearInterval(this.interval);
}
}
function component(width, height, color, x, y) {
this.width = width;
this.height = height;
this.speedX = 0;
this.speedY = 0;
this.x = x;
this.y = y;
this.update = function() {
ctx = myGameArea.context;
ctx.fillStyle = color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
this.newPos = function() {
this.x += this.speedX;
this.y += this.speedY;
}
this.crashWith = function(otherobj) {
var myleft = this.x;
var myright = this.x + (this.width);
var mytop = this.y;
var mybottom = this.y + (this.height);
var otherleft = otherobj.x;
var otherright = otherobj.x + (otherobj.width);
var othertop = otherobj.y;
var otherbottom = otherobj.y + (otherobj.height);
var crash = true;
if ((mybottom < othertop) ||
(mytop > otherbottom) ||
(myright < otherleft) ||
(myleft > otherright)) {
crash = false;
}
return crash;
}
}
function updateGameArea() {
if (myGamePiece.crashWith(myObstacle)) {
myGameArea.stop();
} else {
myGameArea.clear();
myObstacle.update();
myGamePiece.newPos();
myGamePiece.update();
}
}
Obstáculo en movimiento
El obstáculo no representa ningún peligro cuando está estático, por lo que queremos que se mueva.
Cambie el valor de la propiedad de myObstacle.x
en cada actualización:
Ejemplo
function updateGameArea() {
if (myGamePiece.crashWith(myObstacle)) {
myGameArea.stop();
} else {
myGameArea.clear();
myObstacle.x += -1;
myObstacle.update();
myGamePiece.newPos();
myGamePiece.update();
}
}
Múltiples Obstáculos
¿Qué hay de agregar múltiples obstáculos?
Para eso necesitamos una propiedad para contar fotogramas y un método para ejecutar algo a una velocidad de fotogramas dada.
Ejemplo
var myGameArea = {
canvas : document.createElement("canvas"),
start : function() {
this.canvas.width = 480;
this.canvas.height = 270;
this.context = this.canvas.getContext("2d");
document.body.insertBefore(this.canvas, document.body.childNodes[0]);
this.frameNo = 0;
this.interval = setInterval(updateGameArea, 20);
},
clear : function() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
},
stop : function() {
clearInterval(this.interval);
}
}
function everyinterval(n) {
if ((myGameArea.frameNo / n) % 1 == 0) {return true;}
return false;
}
La función everyinterval devuelve verdadero si el número de cuadro actual se corresponde con el intervalo dado.
Para definir varios obstáculos, primero declare la variable de obstáculo como una matriz.
En segundo lugar, necesitamos hacer algunos cambios en la función updateGameArea.
Ejemplo
var myGamePiece;
var myObstacles = [];
function updateGameArea() {
var x, y;
for (i = 0; i < myObstacles.length; i += 1) {
if (myGamePiece.crashWith(myObstacles[i])) {
myGameArea.stop();
return;
}
}
myGameArea.clear();
myGameArea.frameNo += 1;
if (myGameArea.frameNo == 1 || everyinterval(150)) {
x = myGameArea.canvas.width;
y = myGameArea.canvas.height - 200
myObstacles.push(new component(10, 200, "green", x, y));
}
for (i = 0; i < myObstacles.length; i += 1) {
myObstacles[i].x += -1;
myObstacles[i].update();
}
myGamePiece.newPos();
myGamePiece.update();
}
En la updateGameArea
función, debemos atravesar todos los obstáculos para ver si hay un choque. Si hay un bloqueo, la updateGameArea
función se detendrá y no se realizarán más dibujos.
La updateGameArea
función cuenta fotogramas y añade un obstáculo por cada 150 fotogramas.
Obstáculos de tamaño aleatorio
Para hacer el juego un poco más difícil y divertido, enviaremos obstáculos de tamaños aleatorios, de modo que el cuadrado rojo deba moverse hacia arriba y hacia abajo para no chocar.
Ejemplo
function updateGameArea() {
var x, height, gap, minHeight, maxHeight, minGap, maxGap;
for (i = 0; i < myObstacles.length; i += 1) {
if (myGamePiece.crashWith(myObstacles[i])) {
myGameArea.stop();
return;
}
}
myGameArea.clear();
myGameArea.frameNo += 1;
if (myGameArea.frameNo == 1 || everyinterval(150)) {
x = myGameArea.canvas.width;
minHeight = 20;
maxHeight = 200;
height = Math.floor(Math.random()*(maxHeight-minHeight+1)+minHeight);
minGap = 50;
maxGap = 200;
gap = Math.floor(Math.random()*(maxGap-minGap+1)+minGap);
myObstacles.push(new component(10, height, "green", x, 0));
myObstacles.push(new component(10, x - height - gap, "green", x, height + gap));
}
for (i = 0; i < myObstacles.length; i += 1) {
myObstacles[i].x += -1;
myObstacles[i].update();
}
myGamePiece.newPos();
myGamePiece.update();
}