5 - Juegos Multimedia HTML5 - Eventos y Fuegos artificiales

Llegó la hora de ponerse manos a la obra con el sistema de partículas que intenta emular unos fuegos artificiales. Tras decidirse por el mejor modo de animar nuestro canvas y hacer que se ajuste a el tamaño del navegador, lo único que nos queda por ver es cómo incorporar eventos a nuestro sistema. Haremos unas pruebas iniciales con los eventos en nuestro generador de partículas particular y luego nos pondremos manos a la obra con un nuevo archivo llamado fireworks.html.



    Aquí tenéis un archivo plantilla que os va a servir para añadir el contenido que queráis a un canvas que se ajusta a la ventana del navegador
<!DOCTYPE html>
<head>
    <title>Canvas</title>
    <style>
        body {
            background-color: #000;
            overflow: hidden;
            margin: 0;
        }
        canvas {
            background-color: #000;
        }
    </style>
    <script>
        window.addEventListener("resize", resizeCanvas, false);
        window.addEventListener("DOMContentLoaded", onLoad, false);
        
        window.requestAnimationFrame = 
                    window.requestAnimationFrame       || 
                    window.webkitRequestAnimationFrame || 
                    window.mozRequestAnimationFrame    || 
                    window.oRequestAnimationFrame      || 
                    window.msRequestAnimationFrame     || 
                    function (callback) {
                        window.setTimeout(callback, 1000/60);
                    };
        
        var canvas, ctx, w, h;
        
        function onLoad() {
            canvas = document.getElementById("canvas");
            ctx = canvas.getContext("2d");
            resizeCanvas();
            
            window.requestAnimationFrame(updateWorld);
        } // fin de onLoad();
        
        function resizeCanvas() {
            if (!!canvas) {
                w = canvas.width = window.innerWidth;
                h = canvas.height = window.innerHeight;
            }
        } // fin de resizeCanvas();
        
        function updateWorld() {
            update();
            paint();
            window.requestAnimationFrame(updateWorld);
        } // fin de update();
        
        function update() {
            // SCRIPT DE ACTUALIZACIÓN AQUÍ
        } // fin de update();
        
        function paint() {
            ctx.fillStyle = "#000";
            ctx.fillRect(0, 0, w, h);
            // SCRIPT DE PINTADO AQUÍ
        } // fin de paint();
    </script>
  </head>
  <body>
      <noscript>
        No tiene habilitado JavaScript. Debería habilitarlo para poder disfrutar
        al completo de los contenidos de esta página.
      </noscript>
      <div>
          <canvas id="canvas">
              Tu navegador no soporta el elemento <code>canvas</code> de HTML5.
          </canvas>
      </div>
</body>
</html>

Éste es el archivo del generador de partículas, el primer ejemplo del vídeo. Para verlo funcionando pulsa aquí.
<!DOCTYPE html>
<html>
  <head>
    <title>Part&iacute;culas</title>
    <meta charset="UTF-8">
    <meta name="author" content="http://programmingheroes.blogspot.com.es">
    <style>
        body {
            background-color: #80F;
            overflow: hidden;
            margin: 0;
        }
        div {
            -moz-user-select: none;
            -webkit-user-select: none;
        }
        #fps {
            position: absolute;
            top: 10px;
            left: 10px;
            text-align: left;
            color: #FFF;
        }
    </style>
    <script>
        window.addEventListener("resize", resizeCanvas, false);
        
        var frameCount = 0, currentFPS = 0, timeFrame = new Date().getTime();
        
        var canvas, context, w, h, particles = [], xPoint, yPoint, down;
        
        var img = new Image();
        img.addEventListener("load", start, false);
        img.src = "img/rock.png";
        
        window.requestAnimationFrame = 
                    window.requestAnimationFrame       || 
                    window.webkitRequestAnimationFrame || 
                    window.mozRequestAnimationFrame    || 
                    window.oRequestAnimationFrame      || 
                    window.msRequestAnimationFrame     ||
                    function (callback) {
                        window.setTimeout(callback, 1000/60);
                    };
        
        function start() {
            canvas = document.getElementById("c");
            canvas.addEventListener("mousemove", movePoint, false);
            canvas.addEventListener("mousedown", mouseDown, false);
            canvas.addEventListener("mouseup", mouseUp, false);
            canvas.addEventListener("mouseout", mouseUp, false);
            context = canvas.getContext("2d");
            resizeCanvas();
            window.requestAnimationFrame(update);
        } // fin de start();

        function mouseDown(e) {
            down = true;
            movePoint(e);
        } // fin de moveDown(e);
        
        function mouseUp() {
            down = false;
        } // fin de mouseUp();

        function movePoint(e) {
            if (down) {
                var ie = navigator.userAgent.toLowerCase().indexOf('msie')!=-1;
                if (ie) {
                    e = window.event;
                    e.pageX = e.clientX+window.pageXOffset;
                    e.pageY = e.clientY+window.pageYOffset;
                }
                xPoint = e.pageX-canvas.offsetLeft;
                yPoint = e.pageY-canvas.offsetTop;
            }
        }
        
        function resizeCanvas() {
            if (!!canvas) {
                w = canvas.width = window.innerWidth;
                h = canvas.height = window.innerHeight;
                xPoint = w/2;
                yPoint = h/2;
            }
        } // fin de resizeCanvas();

        /*
         * Game Loop, se repite hasta que el usuario decide salir de la página.
         */
        function update() {
            updateFPS();
            if (Math.random() < 0.1) {
                var p = new Particle();
                p.x = xPoint-img.width/2;
                p.y = yPoint-img.height/2;
                particles.push(p);
            }
            moveParticles();
            paint();
            window.requestAnimationFrame(update);
        } // fin de update();

        function updateFPS() {
            var currentFrame = new Date().getTime();
            if (currentFrame-timeFrame >= 1000) {
                currentFps = frameCount;
                frameCount = 0;
                timeFrame = currentFrame;
                paintFPS();
            }
            frameCount++;
        } // fin de updateFPS();

        function paintFPS() {
            var divFps = document.getElementById("fps");
            var text = document.createTextNode("FPS: "+currentFps);
            divFps.replaceChild(text, divFps.childNodes[0]);
        } // fin de paintFPS();
        
        function moveParticles() {
            for (var i=0; i<particles.length; i++) {
                particles[i].move();
            }
        } // fin de moveParticles();
        
        function paint() {
            context.fillStyle = "rgba(0, 0, 0, 1)";
            context.fillRect(0, 0, w, h);
            for (var i=0; i<particles.length; i++) {
                /*var x = particles[i].x, y = particles[i].y;
                context.beginPath();
                context.arc(x, y, 20, 0, Math.PI*2);
                var grd = context.createRadialGradient(x, y, 0, x, y, 50);
                grd.addColorStop(0, particles[i].color);
                grd.addColorStop(1, "rgba(0,0,0,0)");
                context.fillStyle = grd;
                context.fill();*/
                context.drawImage(img, particles[i].x, particles[i].y);
            }
        } // fin de paint();
        
        function Particle() {
            this.x = 0;
            this.y = 0;
            this.vx = (Math.random()-0.5)*10;
            this.vy = (Math.random()-0.5)*10;
            /*this.color = "rgb("+(~~(Math.random()*255))+","
                +(~~(Math.random()*255))+","+(~~(Math.random()*255))+")";*/
        } // fin de Particle();
        
        Particle.prototype = {
            move: function() {
                this.x += this.vx;
                this.y += this.vy;
            },
        } // fin de Particle.prototype;
        
    </script>
  </head>
  <body>
      <noscript>
        No tiene habilitado JavaScript. Debería habilitarlo para poder disfrutar
        al completo de los contenidos de esta página.
      </noscript>
      <div>
          <canvas id="c">
              Tu navegador no soporta canvas.
          </canvas>
          <div id="fps">
              FPS: -
          </div>
      </div>
  </body>
</html>

Los fuegos artificiales multicolores contenidos en el archivo fireworks.html. La página funcionando se encuentra aquí. También podréis ver en ella un título que aprenderemos a hacer en la sexta entrega del curso ;)
<!DOCTYPE html>
<html>
  <head>
    <title>Canvas</title>
    <meta charset="UTF-8">
    <meta name="author" content="http://programmingheroes.blogspot.com.es">
    <style>
        body {
            background-color: #000;
            overflow: hidden;
            margin: 0;
        }
        canvas {
            background-color: #000;
        }
    </style>
    <script>
        window.addEventListener("resize", resizeCanvas, false);
        window.addEventListener("DOMContentLoaded", onLoad, false);
        
        window.requestAnimationFrame = 
            window.requestAnimationFrame       || 
            window.webkitRequestAnimationFrame || 
            window.mozRequestAnimationFrame    || 
            window.oRequestAnimationFrame      || 
            window.msRequestAnimationFrame     || 
            function (callback) {
                window.setTimeout(callback, 1000/60);
            };
        
        var canvas, ctx, w, h, particles = [], probability = 0.04,
            xPoint, yPoint;
        
        
        var img = new Image();
        img.src = "img/fire.png";
        
        
        function onLoad() {
            canvas = document.getElementById("canvas");
            ctx = canvas.getContext("2d");
            resizeCanvas();
            
            window.requestAnimationFrame(updateWorld);
        } // fin de onLoad();
        
        function resizeCanvas() {
            if (!!canvas) {
                w = canvas.width = window.innerWidth;
                h = canvas.height = window.innerHeight;
            }
        } // fin de resizeCanvas();
        
        function updateWorld() {
            update();
            paint();
            window.requestAnimationFrame(updateWorld);
        } // fin de update();
        
        function update() {
            if (particles.length < 500 && Math.random() < probability) {
                createFirework();
            }
            var alive = [];
            for (var i=0; i<particles.length; i++) {
                if (particles[i].move()) {
                    alive.push(particles[i]);
                }
            }
            particles = alive;
        } // fin de update();
        
        function paint() {
            ctx.globalCompositeOperation = 'source-over';
            ctx.fillStyle = "rgba(0,0,0,0.2)";
            ctx.fillRect(0, 0, w, h);
            ctx.globalCompositeOperation = 'lighter';
            for (var i=0; i<particles.length; i++) {
                particles[i].draw(ctx);
            }
        } // fin de paint();
        
        function createFirework() {
            xPoint = Math.random()*(w-200)+100;
            yPoint = Math.random()*(h-200)+100;
            var nFire = Math.random()*50+100;
            var c = "rgb("+(~~(Math.random()*200+55))+","
                 +(~~(Math.random()*200+55))+","+(~~(Math.random()*200+55))+")";
            for (var i=0; i<nFire; i++) {
                var particle = new Particle();
                particle.color = c;
                var vy = Math.sqrt(25-particle.vx*particle.vx);
                if (Math.abs(particle.vy) > vy) {
                    particle.vy = particle.vy>0 ? vy: -vy;
                }
                particles.push(particle);
            }
        } // fin de createParticles();
        
        function Particle() {
            this.w = this.h = Math.random()*4+1;
            // Position
            this.x = xPoint-this.w/2;
            this.y = yPoint-this.h/2;
            // Velocidades x e y entre -5 y +5
            this.vx = (Math.random()-0.5)*10;
            this.vy = (Math.random()-0.5)*10;
            // Tiempo de vida
            this.alpha = Math.random()*.5+.5;
            // color
            this.color;
        } // fin de Particle();
        
        Particle.prototype = {
            gravity: 0.05,
            move: function () {
                this.x += this.vx;
                this.vy += this.gravity;
                this.y += this.vy;
                this.alpha -= 0.01;
                if (this.x <= -this.w || this.x >= screen.width ||
                    this.y >= screen.height ||
                    this.alpha <= 0) {
                        return false;
                }
                return true;
            },
            draw: function (c) {
                c.save();
                c.beginPath();
                
                c.translate(this.x+this.w/2, this.y+this.h/2);
                c.arc(0, 0, this.w, 0, Math.PI*2);
                c.fillStyle = this.color;
                c.globalAlpha = this.alpha;
                
                c.closePath();
                c.fill();
                c.restore();
            }
        } // fin de Particle.prototype;
    </script>
  </head>
  <body>
      <noscript>
        No tiene habilitado JavaScript. Debería habilitarlo para poder disfrutar
        al completo de los contenidos de esta página.
      </noscript>
      <div>
          <canvas id="canvas">
              Tu navegador no soporta el elemento <code>canvas</code> de HTML5.
          </canvas>
      </div>
  </body>
</html>


Índice del curso

2 comentarios :

  1. hey men como quito el fondo negro y que sea vea asi con la pagina de fondo tu me entenderas sin el fondo y que nomas se vean los aritificiales

    ResponderEliminar
  2. Hola se que es algo tonta la pregunta pero donde puedo conseguir las imágenes que usas para estos ejemplos.

    ResponderEliminar