Efecto de Nieve en ActionScript 3.0

lunes, diciembre 14, 2009
Crear un efecto de nieve usando ActionScript es bastante sencillo. A grandes rasgos consiste en establecer una zona en la cual va a caer la nieve, añadir copos de nieve en la parte superior y luego manejar el evento Enter Frame para mover los copos de nieve hacia abajo y hacia los costados.
Para hacer este efecto me he basado en un código que encontré en liquidjourney, el cual hace el efecto de la nieve cayendo, el problema es que estaba en ActionScript 2.0 así que le hice unos cambios para pasarlo a ActionScript 3.0 ya que puede haber problemas si se quiere usar este efecto en otras animaciones que usan AS3.
Sólo necesitan un símbolo para delimitar la nieve como se ve en la imagen y agregar el código que pongo más abajo


Código:

//Posiciones de fondonieve
//Fondo nieve es un símbolo que marca el cuadro donde caerá nieve
var left:Number = this.fondonieve.x;
var right:Number = left+this.fondonieve.width;
var top:Number = this.fondonieve.y;
var bottom:Number = top+this.fondonieve.height;

//Número de copos de nieve
var total:Number;
total=250;
//Variable que almacenará los copos de nieve
var miArray:Array;

//Crear el fondo, en este caso el Sprite donde va la nieve
//y la máscara para que los copos de nieve no salgan de ahí
function createBackground():void {
//Crear el Sprite para la nieve
var ele:Sprite =new Sprite();
ele.name="ele";
//Posicionarlo en el mismo lugar que fondonieve
ele.x=this.fondonieve.x;
ele.y=this.fondonieve.y;
//Agregalo
addChild(ele)

//Crear el Sprite mask2 que usaremos de máscara
var mask2:Sprite =new Sprite();
mask2.name="mask2";
//Posicionarlo en el mismo lugar que fondonieve
mask2.x=this.fondonieve.x;
mask2.y=this.fondonieve.y;
//Agregalo
addChild(mask2)
//Dibujar un rectángulo con las medidas de fondonieve
var g2:Graphics = mask2.graphics;
g2.beginFill(0x000000, 100);
g2.moveTo(0, 0);
g2.lineTo(this.fondonieve.width, 0);
g2.lineTo(this.fondonieve.width, this.fondonieve.height);
g2.lineTo(0, this.fondonieve.height);
g2.lineTo(0, 0);
g2.endFill();
//Establecer a mask2 como la máscara de ele
ele.mask=mask2;
}

//Creación los copos de nieve
function createParticles() {
//Obtener el Sprite ele del escenario
var ele:Sprite;
ele=Sprite(getChildByName("ele"));
//Instanciar el arreglo
miArray=new Array();

//Usar un for para crear los copos de nieve
for (var i:Number = 0; i //Nieve es una clase-símbolo con la imagen de un copo
var clip3:Nieve=new Nieve();
ele.addChild(clip3);
//Crear un Object con los atributos necesarios: el movieclip del copo de nieve(Sprite), posiciones x - y, velocidad de movimiento x - y, rotación, dos contadores ct y c para realizar los cambios de dirección y hasta donde deben caer fl
var obj:Object = {mc:clip3, mn:1+Math.random()*2, x:Math.random()*this.fondonieve.width, y:-100, movx:Math.random()*2-1, movy:Math.random()*3+0.5, r:Math.random()*10-5, ct:Math.ceil(Math.random()*60), c:0, fl:this.fondonieve.height-Math.random()*3};
//Unicar el copo de nieve en las posiciones establecidas
clip3.x=obj.x;
clip3.y=obj.y;
//Agregar el obj al arreglo
miArray.push(obj);
//Deformar y girar el copo de nieve para que no sean todos iguales
clip3.scaleX= 2+Math.random()*3;
clip3.scaleY= 2+Math.random()*3;
clip3.rotation=Math.random()*360;
}
}

//Funcion que se va a ejecutar en cada evento EnterFrame
function myForEachFunction (obj:Object, index:int, array:Array):void
{
//obj es cada Object que se tiene en miArray
//Recordar que obj.mc contiene el MovieClip del copo de nieve
var mc:MovieClip = obj.mc;
obj.c++;
//Verificar si hay que cambiar la dirección
//Esto es cuando el contador c pasa a ct
if (obj.c>obj.ct) {
//Cambiar la dirección y reestablecer c y ct
obj.movx = Math.random()*5-2.5;
obj.c = 0;
obj.ct = Math.floor(Math.random()*60);
}


//Hacer los cambios en obj
obj.x += obj.movx;
obj.y += obj.movy+obj.mn
//Aplicar los cambios en el movieclip del copo de nieve
mc.rotation += obj.r;
mc.y = obj.y;
mc.x = obj.x;

//Verificar si el copo de nieve ha salido de los bordes derecho o izquierdo
//De ser así reaparece por el borde contrario
if (mc.xthis.fondonieve.width+5) {
obj.x = left-2;
}


//Verificar si el copo de nieve ya cayo completamente
if (mc.y>obj.fl) {
obj.fl=this.fondonieve.height-Math.random()*3;
//Reubicar el copo de nieve arriba
obj.y -=this.fondonieve.height;
obj.movy = Math.random()*3+0.5;
}
}

//Función a realizar en cada evento Enter Frame
function onLoop(evt:Event):void {
//Ejecutar para cada elemento de miArray la función myForEachFunction
miArray.forEach(myForEachFunction)
}

//Agregar un listener al evento Enter Frame y darle la función onLoop
this.addEventListener(Event.ENTER_FRAME, onLoop, false,0, true);

//Llamadas a los métodos para crear todo
createBackground()
createParticles()

El resultado es algo así:


Pueden modificar valores como la cantidad de copos de nieve o mejor aún pueden agregarle sus propias imagenes y ver cómo cae la nieve.


Pueden descargar el archivo .fla AQUI

3 comentarios:

{ sanosiris } at: 14 de diciembre de 2009, 21:37 dijo...

Hola que tal, buen efecto el de la nieve.

Te comparto este code con el mismo objetivo, usualmente yo lo uso para ponerlo en mi blog:

http://www.sanosiris.com/index.php/topic,11.0.html

Anónimo at: 15 de diciembre de 2011, 6:37 dijo...

Hola tengo un error en la linea 56:
for (var i:Number = 0; i

Me arroja el siguiente error:
1084: Error de sintaxis: se esperaba identifier antes de assign.

Gracias por tu ayuda y felicidades por el código.

Jhon.

{ Diego } at: 15 de diciembre de 2011, 19:35 dijo...

Hola John, en la línea 56 aparecen unos símbolos que no deberían estar ahí, ="" { , el único que debería aparecer es la llabe '{', esto es por el formateador de código que usé para resaltar el código, si esto no funciona prueba descargar el código del link de abajo, ahí debería estar sin ningún problema. Saludos