{"id":1083,"date":"2026-01-05T16:58:23","date_gmt":"2026-01-05T16:58:23","guid":{"rendered":"https:\/\/javigomez.org\/?p=1083"},"modified":"2026-01-10T14:00:11","modified_gmt":"2026-01-10T14:00:11","slug":"juego-de-asteroides","status":"publish","type":"post","link":"https:\/\/javigomez.org\/index.php\/2026\/01\/05\/juego-de-asteroides\/","title":{"rendered":"Juego de Asteroides"},"content":{"rendered":"\n<p>El siguiente juego es un space shooter con asteroides que se deben eliminar antes que destruyan la nave. Este juego muestra im\u00e1genes y tiene efectos de sonido. Al igual que los otros juegos, no tiene puntuaci\u00f3n, ni puntuaci\u00f3n, pero tiene completa la din\u00e1mica de juego.<\/p>\n\n\n\n<p><a href=\"https:\/\/javigomez.org\/juegosJS\/Asteroides\/Asteroides.html\">https:\/\/javigomez.org\/juegosJS\/Asteroides\/Asteroides.html<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/jagode67\/juegosJS\/tree\/main\/Asteroides\">https:\/\/github.com\/jagode67\/juegosJS\/tree\/main\/Asteroides<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;!DOCTYPE html>\n&lt;html lang=\"en\">\n\n&lt;head>\n    &lt;meta charset=\"UTF-8\">\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    &lt;title>Document&lt;\/title>\n&lt;\/head>\n\n&lt;body>\n    &lt;canvas id=\"fondo\" width=\"600\" height=\"600\">&lt;\/canvas>\n    &lt;script>\n        let intervaloJuego;\n        var fps = 60;\n        var tAnterior = 0;\n        var juegoActivo = true;\n\n        window.onload = function () {\n            canvas = document.getElementById(\"fondo\");\n            ctx = canvas.getContext(\"2d\");\n            imgFondo = new Image()\n            imgFondo.src = \"images\/space.png\"\n\n            nave = new Nave(ctx);\n            ctlDisparo = new CtlDisparo(ctx);\n            ctlAsteroide = new CtlAsteroide(ctx);\n\n            \/\/intervaloJuego = setInterval(juego, 1000 \/ 60);\n            requestAnimationFrame(ctrJuego);\n        }\n        function ctrJuego(timestamp) {\n            var delta = timestamp - tAnterior;\n            if (delta >= 1000 \/ fps) {\n                juego();\n                tAnterior = timestamp;\n            }\n            if (juegoActivo) {\n                requestAnimationFrame(ctrJuego);\n            }\n        }\n        function juego() {\n            ctx.drawImage(imgFondo, 0, 0, canvas.width, canvas.height);\n            ctlDisparo.mostrar();\n            ctlAsteroide.mostrar();\n            nave.mostrar(ctx);\n            colisionador(ctlDisparo, ctlAsteroide, nave);\n        }\n\n        function colisionador(ctlDisparo, ctlAsteroide, nave) {\n            \/\/Destrucci\u00f3n de asteroides por disparo\n            for (ast of ctlAsteroide.asteroides)\n                for (dis of ctlDisparo.disparos)\n                    if (dis.x + dis.width > ast.x &amp;&amp; dis.x &lt; ast.x + ast.width &amp;&amp;\n                        dis.y + dis.height > ast.y &amp;&amp; dis.y &lt; ast.y + ast.height) {\n                        ctlAsteroide.asteroides.splice(ctlAsteroide.asteroides.indexOf(ast), 1);\n                        ctlDisparo.disparos.splice(ctlDisparo.disparos.indexOf(dis), 1);\n                        this.sonido = new Audio(\"sounds\/destroy.wav\");\n                        this.sonido.currentTime = 0;\n                        this.sonido.play();\n                    }\n            \/\/Choche entre asteroides\n            for (ene of ctlAsteroide.asteroides)\n                for (ene1 of ctlAsteroide.asteroides)\n                    if (ene1.velY != ene.velY)\n                        if (ene1.x + ene1.width > ene.x &amp;&amp; ene1.x &lt; ene.x + ene.width &amp;&amp;\n                            ene1.y + ene1.height > ene.y &amp;&amp; ene1.y &lt; ene.y + ene.height) {\n                            ctlAsteroide.asteroides.splice(ctlAsteroide.asteroides.indexOf(ene), 1);\n                            ctlAsteroide.asteroides.splice(ctlAsteroide.asteroides.indexOf(ene1), 1);\n                            this.sonido = new Audio(\"sounds\/destroy.wav\");\n                            this.sonido.currentTime = 0;\n                            this.sonido.play();\n                        }\n            \/\/Destrucci\u00f3n de nave\n            for (ene of ctlAsteroide.asteroides)\n                if (ene.x + ene.width > nave.x &amp;&amp; ene.x &lt; nave.x + nave.width &amp;&amp;\n                    ene.y + ene.height > nave.y &amp;&amp; ene.y &lt; nave.y + nave.height) {\n                    ctlAsteroide.asteroides.splice(ctlAsteroide.asteroides.indexOf(ene), 1);\n                    this.sonido = new Audio(\"sounds\/explosion.mp3\");\n                    this.sonido.currentTime = 0;\n                    this.sonido.play();\n                    nave.imagen.src = \"\";\n\n                    \/\/ Redibujar para mostrar la nave desaparecida\n                    ctx.drawImage(imgFondo, 0, 0, canvas.width, canvas.height);\n                    ctlDisparo.mostrar();\n                    ctlAsteroide.mostrar();\n\n                    \/\/ Parar el juego\n                    juegoActivo = false;\n                    clearInterval(ctlAsteroide.intervaloCreacion);\n\n                    \/\/ Mostrar mensaje despu\u00e9s de 1 segundo\n                    setTimeout(fin, 1000);\n                }\n        }\n        function fin() {\n            \/\/ Mostrar FIN\n            ctx.fillStyle = \"white\";\n            ctx.font = \"60px Arial\";\n            ctx.textAlign = \"center\";\n            ctx.fillText(\"FIN DE JUEGO\", canvas.width \/ 2, canvas.height \/ 2);\n        }\n        class Nave {\n            izq = false;\n            der = false;\n            dis = false;\n            constructor(ctx) {\n                this.x = canvas.width \/ 2;\n                this.y = canvas.height - 75;\n                this.width = 50;\n                this.height = 48;\n                this.vel = 5;\n                this.imagen = new Image();\n                this.imagen.src = \"images\/player.png\"\n                this.ctx = ctx\n\n                document.addEventListener(\"keydown\", (e) => {\n                    if (e.code == \"ArrowRight\") this.der = true;\n                    if (e.code == \"ArrowLeft\") this.izq = true;\n                    if (e.code == \"Space\") ctlDisparo.disparar(this.x + this.width \/ 2, this.y, 5, \"red\");\n                })\n                document.addEventListener(\"keyup\", (e) => {\n                    if (e.code == \"ArrowRight\") this.der = false;\n                    if (e.code == \"ArrowLeft\") this.izq = false;\n                })\n            }\n            mover() {\n                if (this.izq) this.x = Math.max(this.x -= this.vel, 0);\n                if (this.der) this.x = Math.min(this.x += this.vel, canvas.width - this.width);\n            }\n            mostrar(ctx) {\n                this.mover();\n                ctx.drawImage(this.imagen, this.x, this.y, this.width, this.height)\n            }\n        }\n\n        class CtlAsteroide {\n            asteroides = &#91;];\n            constructor(ctx) {\n                this.ctx = ctx;\n                this.intervaloCreacion = setInterval(() => this.creaAsteroide(), 500);\n            }\n            creaAsteroide() {\n                let aX = Math.floor(Math.random() * (canvas.width - 44))\n                let aVy = - (Math.random() * 10)\n                let aVx = Math.random() * 4 - 2;\n                let asteroide = new Asteroide(aX, 0, aVx, aVy)\n                this.asteroides.push(asteroide)\n            }\n            mostrar(ctx) {\n                for (let i = this.asteroides.length - 1; i >= 0; i--) {\n                    let ast = this.asteroides&#91;i];\n                    ast.x += ast.velX;\n                    ast.y -= ast.velY;\n                    if (ast.y > canvas.height) {\n                        this.asteroides.splice(i, 1);\n                    }\n                    else {\n                        this.ctx.drawImage(ast.imagen, ast.x, ast.y, ast.width, ast.height)\n                    }\n                }\n            }\n        }\n        class Asteroide {\n            constructor(x, y, velX, velY) {\n                this.x = x;\n                this.y = y;\n                this.width = 44;\n                this.height = 32;\n                this.velX = velX;\n                this.velY = velY;\n                this.imagen = new Image();\n                this.imagen.src = `images\/asteroid${Math.floor(Math.random() * 2) + 1}.png`\n            }\n        }\n\n\n        class CtlDisparo {\n            disparos = &#91;];\n            constructor(ctx) {\n                this.ctx = ctx;\n                this.sonido = new Audio(\"sounds\/shoot.wav\");\n            }\n            disparar(x, y, vel, color) {\n                let disparo = new Disparo(x, y, vel, color)\n                if (this.disparos.length &lt; 10) {\n                    this.sonido.currentTime = 0;\n                    this.sonido.play();\n                    this.disparos.push(disparo);\n                }\n            }\n            mostrar() {\n                for (let i = this.disparos.length - 1; i >= 0; i--) {\n                    let dis = this.disparos&#91;i];\n                    dis.y -= dis.vel;\n                    if (dis.y &lt; 0) {\n                        this.disparos.splice(i, 1);\n                    }\n                    else {\n                        this.ctx.fillStyle = dis.color;\n                        this.ctx.fillRect(dis.x, dis.y, dis.width, dis.height);\n                    }\n                }\n            }\n        }\n        class Disparo {\n            constructor(x, y, vel, color) {\n                this.x = x;\n                this.y = y;\n                this.width = 5;\n                this.height = 20;\n                this.vel = vel;\n                this.color = color;\n            }\n        }\n\n    &lt;\/script>\n&lt;\/body>\n\n&lt;\/html><\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>El siguiente juego es un space shooter con asteroides que se deben eliminar antes que destruyan la nave. Este juego muestra im\u00e1genes y tiene efectos &hellip; <\/p>\n","protected":false},"author":1,"featured_media":1087,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[],"class_list":["post-1083","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript"],"_links":{"self":[{"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/posts\/1083","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/comments?post=1083"}],"version-history":[{"count":4,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/posts\/1083\/revisions"}],"predecessor-version":[{"id":1099,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/posts\/1083\/revisions\/1099"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/media\/1087"}],"wp:attachment":[{"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/media?parent=1083"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/categories?post=1083"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/javigomez.org\/index.php\/wp-json\/wp\/v2\/tags?post=1083"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}