January 8, 2026

Juego de Asteroides

El siguiente juego es un space shooter con asteroides que se deben eliminar antes que destruyan la nave. Este juego muestra imágenes y tiene efectos de sonido. Al igual que los otros juegos, no tiene puntuación, ni puntuación, pero tiene completa la dinámica de juego.

https://javigomez.org/juegosJS/Asteroides/Asteroides.html

https://github.com/jagode67/juegosJS/tree/main/Asteroides

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Asteroides</title>
</head>

<body>
    <canvas id="fondo" width="600" height="600"></canvas>
    <script>
        let intervaloJuego;

        window.onload = function () {
            canvas = document.getElementById("fondo");
            ctx = canvas.getContext("2d");
            imgFondo = new Image()
            imgFondo.src = "images/space.png"

            nave = new Nave(ctx);
            ctlDisparo = new CtlDisparo(ctx);
            ctlAsteroide = new CtlAsteroide(ctx);

            intervaloJuego = setInterval(juego, 1000 / 60);
        }
        function juego() {
            ctx.drawImage(imgFondo, 0, 0, canvas.width, canvas.height);
            ctlDisparo.mostrar();
            ctlAsteroide.mostrar();
            nave.mostrar(ctx);
            colisionador(ctlDisparo, ctlAsteroide, nave);
        }

        function colisionador(ctlDisparo, ctlAsteroide, nave) {
            //Destrucción de asteroides por disparo
            for (ast of ctlAsteroide.asteroides)
                for (dis of ctlDisparo.disparos)
                        if (dis.x + dis.width > ast.x && dis.x < ast.x + ast.width &&
                            dis.y + dis.height > ast.y && dis.y < ast.y + ast.height) {
                            ctlAsteroide.asteroides.splice(ctlAsteroide.asteroides.indexOf(ast), 1);
                            ctlDisparo.disparos.splice(ctlDisparo.disparos.indexOf(dis), 1);
                            this.sonido = new Audio("sounds/destroy.wav");
                            this.sonido.currentTime = 0;
                            this.sonido.play();
                        }
            //Choche entre asteroides
            for (ene of ctlAsteroide.asteroides)
                for (ene1 of ctlAsteroide.asteroides)
                    if (ene1.velY != ene.velY)
                        if (ene1.x + ene1.width > ene.x && ene1.x < ene.x + ene.width &&
                            ene1.y + ene1.height > ene.y && ene1.y < ene.y + ene.height) {
                            ctlAsteroide.asteroides.splice(ctlAsteroide.asteroides.indexOf(ene), 1);
                            ctlAsteroide.asteroides.splice(ctlAsteroide.asteroides.indexOf(ene1), 1);
                            this.sonido = new Audio("sounds/destroy.wav");
                            this.sonido.currentTime = 0;
                            this.sonido.play();
                        }
            //Destrucción de nave
            for (ene of ctlAsteroide.asteroides)
                if (ene.x + ene.width > nave.x && ene.x < nave.x + nave.width &&
                    ene.y + ene.height > nave.y && ene.y < nave.y + nave.height) {
                    ctlAsteroide.asteroides.splice(ctlAsteroide.asteroides.indexOf(ene), 1);
                    this.sonido = new Audio("sounds/explosion.mp3");
                    this.sonido.currentTime = 0;
                    this.sonido.play();
                    nave.imagen.src = "";
                    setTimeout(fin, 1000);
                }
        }
        function fin(){
                    // Parar el juego
                    clearInterval(intervaloJuego);
                    clearInterval(ctlAsteroide.intervaloCreacion);
                    
                    // Mostrar FIN
                    ctx.fillStyle = "white";
                    ctx.font = "60px Arial";
                    ctx.textAlign = "center";
                    ctx.fillText("FIN DE JUEGO", canvas.width/2, canvas.height/2);
        }
        class Nave {
            izq = false;
            der = false;
            dis = false;
            constructor(ctx) {
                this.x = canvas.width / 2;
                this.y = canvas.height - 75;
                this.width = 50;
                this.height = 48;
                this.vel = 5;
                this.imagen = new Image();
                this.imagen.src = "images/player.png"
                this.ctx = ctx

                document.addEventListener("keydown", (e) => {
                    if (e.code == "ArrowRight") this.der = true;
                    if (e.code == "ArrowLeft") this.izq = true;
                    if (e.code == "Space") ctlDisparo.disparar(this.x + this.width / 2, this.y, 5, "red");
                })
                document.addEventListener("keyup", (e) => {
                    if (e.code == "ArrowRight") this.der = false;
                    if (e.code == "ArrowLeft") this.izq = false;
                })
            }
            mover() {
                if (this.izq) this.x = Math.max(this.x -= this.vel, 0);
                if (this.der) this.x = Math.min(this.x += this.vel, canvas.width - this.width);
            }
            mostrar(ctx) {
                this.mover();
                ctx.drawImage(this.imagen, this.x, this.y, this.width, this.height)
            }
        }

        class CtlAsteroide {
            asteroides = [];
            constructor(ctx) {
                this.ctx = ctx;
                this.intervaloCreacion = setInterval(() => this.creaAsteroide(), 500);
            }
            creaAsteroide() {
                let aX = Math.floor(Math.random() * (canvas.width - 44))
                let aVy = - (Math.random() * 10)
                let aVx = Math.random() * 4 - 2;
                let asteroide = new Asteroide(aX, 0, aVx, aVy)
                this.asteroides.push(asteroide)
            }
            mostrar(ctx) {
                for (let i = this.asteroides.length - 1; i >= 0; i--) {
                    let ast = this.asteroides[i];
                    ast.x += ast.velX;
                    ast.y -= ast.velY;
                    if (ast.y > canvas.height) {
                        this.asteroides.splice(i, 1);
                    }
                    else {
                        this.ctx.drawImage(ast.imagen, ast.x, ast.y, ast.width, ast.height)
                    }
                }
            }
        }
        class Asteroide {
            constructor(x, y, velX, velY) {
                this.x = x;
                this.y = y;
                this.width = 44;
                this.height = 32;
                this.velX = velX;
                this.velY = velY;
                this.imagen = new Image();
                this.imagen.src = `images/asteroid${Math.floor(Math.random() * 2) + 1}.png`
            }
        }


        class CtlDisparo {
            disparos = [];
            constructor(ctx) {
                this.ctx = ctx;
                this.sonido = new Audio("sounds/shoot.wav");
            }
            disparar(x, y, vel, color) {
                let disparo = new Disparo(x, y, vel, color)
                if (this.disparos.length < 10) {
                    this.sonido.currentTime = 0;
                    this.sonido.play();
                    this.disparos.push(disparo);
                }
            }
            mostrar() {
                for (let i = this.disparos.length - 1; i >= 0; i--) {
                    let dis = this.disparos[i];
                    dis.y -= dis.vel;
                    if (dis.y < 0) {
                        this.disparos.splice(i, 1);
                    }
                    else {
                        this.ctx.fillStyle = dis.color;
                        this.ctx.fillRect(dis.x, dis.y, dis.width, dis.height);
                    }
                }
            }
        }
        class Disparo {
            constructor(x, y, vel, color) {
                this.x = x;
                this.y = y;
                this.width = 5;
                this.height = 20;
                this.vel = vel;
                this.color = color;
            }
        }

    </script>
</body>

</html>

Leave a Reply

Your email address will not be published. Required fields are marked *