Obstáculos do jogo
Aperte os botões para mover o quadrado vermelho:
Adicione alguns obstáculos
Agora queremos adicionar alguns obstáculos ao nosso jogo.
Adicione um novo componente à área de jogo. Torne-o verde, 10px de largura, 200px de altura e coloque-o 300px à direita e 120px para baixo.
Atualize também o componente de obstáculo em cada quadro:
Exemplo
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();
}
Acerte o Obstáculo = Fim de Jogo
No exemplo acima, nada acontece quando você atinge o obstáculo. Em um jogo, isso não é muito satisfatório.
Como sabemos se nosso quadrado vermelho atinge o obstáculo?
Crie um novo método no construtor do componente, que verifica se o componente falha com outro componente. Este método deve ser chamado toda vez que os quadros forem atualizados, 50 vezes por segundo.
Adicione também um stop()
método ao myGameArea
objeto, que limpa o intervalo de 20 milissegundos.
Exemplo
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 em Movimento
O obstáculo não tem perigo quando está estático, então queremos que ele se mova.
Altere o valor da propriedade de myObstacle.x
a cada atualização:
Exemplo
function updateGameArea() {
if (myGamePiece.crashWith(myObstacle)) {
myGameArea.stop();
} else {
myGameArea.clear();
myObstacle.x += -1;
myObstacle.update();
myGamePiece.newPos();
myGamePiece.update();
}
}
Vários obstáculos
Que tal adicionar vários obstáculos?
Para isso, precisamos de uma propriedade para contar quadros e de um método para executar algo em uma determinada taxa de quadros.
Exemplo
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;
}
A função everyinterval retorna true se o número do quadro atual corresponder ao intervalo fornecido.
Para definir vários obstáculos, primeiro declare a variável de obstáculo como uma matriz.
Segundo, precisamos fazer algumas mudanças na função updateGameArea.
Exemplo
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();
}
Na updateGameArea
função, devemos percorrer todos os obstáculos para ver se há uma falha. Se houver uma falha, a updateGameArea
função será interrompida e nenhum desenho será feito.
A updateGameArea
função conta quadros e adiciona um obstáculo a cada 150 quadros.
Obstáculos de tamanho aleatório
Para tornar o jogo um pouco mais difícil e divertido, enviaremos obstáculos de tamanhos aleatórios, para que o quadrado vermelho se mova para cima e para baixo para não bater.
Exemplo
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();
}