🕹️Brick Breaker en javascript (2D)

Dar vidas al jugador

 

Dar vidas es bastante sencillo. Primero, añade una variable para guardar el número de vidas que tiene en cada momento. Ponla después de las que ya tienes:

var lives = 3;

Mostrar por pantalla el número de vidas es prácticamente lo mismo que mostrar el contador de puntos. Añade la función siguiente detrás de la función drawScore():

function drawLives() {
  ctx.font = "16px Arial";
  ctx.fillStyle = "#0095DD";
  ctx.fillText("Lives: " + lives, canvas.width - 65, 20);
}

En lugar de terminar el juego inmediatamente, restaremos una vida hasta que ya no quede ninguna. También podemos colocar la bola y la paleta en la posición inicial cuando el jugador empiece con la vida siguiente. En la función draw() cambia las dos líneas siguientes…

lives--;
if (!lives) {
  alert("GAME OVER");
  document.location.reload();
} else {
  x = canvas.width / 2;
  y = canvas.height - 30;
  dx = 2;
  dy = -2;
  paddleX = (canvas.width - paddleWidth) / 2;
}

Ahora, cuando la bola toca el fondo, restamos una vida. Si no queda ninguna, el jugador pierde y termina la partida. Si queda alguna, entonces colocamos la bola y la paleta en el centro, y hacemos que la bola vaya en la nueva dirección correcta y a la velocidad inicial.

Sacar por pantalla el contador de vidas

Tienes que añadir una llamada a drawLives() dentro de draw() debajo de la llamada a drawScore():

drawLives();

Mejorar el refresco con requestAnimationFrame()

Ahora vamos a ocuparnos de algo que no es particular de este juego, sino de la forma en la que se muestran las imágenes en pantalla.

requestAnimationFrame ayuda al navegador a refrescar la imagen mejor que con el método setInterval() que estamos utilizando. Cambia la línea siguiente…

setInterval(draw, 10);

…por esta otra:

draw();

Y, ahora, al final de la función draw(), justo antes de la llave que la cierra, añade la línea siguiente, que hará que la función draw() se llame a sí misma una y otra vez:

requestAnimationFrame(draw);

Ahora draw() se ejecuta una y otra vez con un bucle requestAnimationFrame() pero, en lugar de hacerlo cada 10 milisegundos, dejamos que sea el navegadro quien decida cada cuánto tiempo. El navegador sincronizará el refresco, es decir, el número de fotogramas por segundo, a lo que sea capaz la máquina que está ejecutando el juego. De este modo la animación será más eficiente y más suave que el viejo método setInterval().

Compara tu código

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 10;
var x = canvas.width/2;
var y = canvas.height-30;
var dx = 2;
var dy = -2;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width-paddleWidth)/2;
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 5;
var brickColumnCount = 3;
var brickWidth = 75;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
var lives = 3;

var bricks = [];
for(c=0; c<brickColumnCount; c++) {
    bricks[c] = [];
    for(r=0; r<brickRowCount; r++) {
        bricks[c][r] = { x: 0, y: 0, status: 1 };
    }
}

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, false);

function keyDownHandler(e) {
    if(e.keyCode == 39) {
        rightPressed = true;
    }
    else if(e.keyCode == 37) {
        leftPressed = true;
    }
}
function keyUpHandler(e) {
    if(e.keyCode == 39) {
        rightPressed = false;
    }
    else if(e.keyCode == 37) {
        leftPressed = false;
    }
}
function mouseMoveHandler(e) {
    var relativeX = e.clientX - canvas.offsetLeft;
    if(relativeX > 0 && relativeX < canvas.width) {
        paddleX = relativeX - paddleWidth/2;
    }
}
function collisionDetection() {
    for(c=0; c<brickColumnCount; c++) {
        for(r=0; r<brickRowCount; r++) {
            var b = bricks[c][r];
            if(b.status == 1) {
                if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) {
                    dy = -dy;
                    b.status = 0;
                    score++;
                    if(score == brickRowCount*brickColumnCount) {
                        alert("YOU WIN, CONGRATS!");
                        document.location.reload();
                    }
                }
            }
        }
    }
}

function drawBall() {
    ctx.beginPath();
    ctx.arc(x, y, ballRadius, 0, Math.PI*2);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    ctx.closePath();
}
function drawPaddle() {
    ctx.beginPath();
    ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);
    ctx.fillStyle = "#0095DD";
    ctx.fill();
    ctx.closePath();
}
function drawBricks() {
    for(c=0; c<brickColumnCount; c++) {
        for(r=0; r<brickRowCount; r++) {
            if(bricks[c][r].status == 1) {
                var brickX = (r*(brickWidth+brickPadding))+brickOffsetLeft;
                var brickY = (c*(brickHeight+brickPadding))+brickOffsetTop;
                bricks[c][r].x = brickX;
                bricks[c][r].y = brickY;
                ctx.beginPath();
                ctx.rect(brickX, brickY, brickWidth, brickHeight);
                ctx.fillStyle = "#0095DD";
                ctx.fill();
                ctx.closePath();
            }
        }
    }
}
function drawScore() {
    ctx.font = "16px Arial";
    ctx.fillStyle = "#0095DD";
    ctx.fillText("Score: "+score, 8, 20);
}
function drawLives() {
    ctx.font = "16px Arial";
    ctx.fillStyle = "#0095DD";
    ctx.fillText("Lives: "+lives, canvas.width-65, 20);
}

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawBricks();
    drawBall();
    drawPaddle();
    drawScore();
    drawLives();
    collisionDetection();
    
    if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
        dx = -dx;
    }
    if(y + dy < ballRadius) {
        dy = -dy;
    }
    else if(y + dy > canvas.height-ballRadius) {
        if(x > paddleX && x < paddleX + paddleWidth) {
            dy = -dy;
        }
        else {
            lives--;
            if(!lives) {
                alert("GAME OVER");
                document.location.reload();
            }
            else {
                x = canvas.width/2;
                y = canvas.height-30;
                dx = 3;
                dy = -3;
                paddleX = (canvas.width-paddleWidth)/2;
            }
        }
    }
    
    if(rightPressed && paddleX < canvas.width-paddleWidth) {
        paddleX += 7;
    }
    else if(leftPressed && paddleX > 0) {
        paddleX -= 7;
    }
    
    x += dx;
    y += dy;
    requestAnimationFrame(draw);
}

draw();

¿Te ha resultado útil??

1 / 0

Deja una respuesta 0

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.