Comunidad de diseño web y desarrollo en internet online

Efectos lago, rio y cascada con BitmapData de Flash 8

Estos efectos simulan el reflejo de una imagen sobre el agua. De ese modo, puedes crear cualquier imagen y se generarán las ilusiones del reflejo de un lago, del paso de un río o el estar detrás de una cascada. Está basado en la combinación de PerlinNoise con el desplazamiento de mapa de bits. De este modo podemos simular desde un tranquilo lago, hasta aguas torrenciales y cascadas.
En este ejemplo necesitamos solamente la imagen a reflejar vinculada en la biblioteca con el nombre "imagen".

En su forma simple dicho reflejo es uniforme y no presenta profundidad en la distancia. Para dotarle de relieve, hacemos una división de la imagen en tres partes de 1/6, 2/6(1/3) y 3/6(1/2) y aplicamos los desplazamientos y filtros independientemente.
Veamos estos tres ejemplos y la explicación de sus parámetros más significativos.

Efecto lago:



Código :

import flash.display.*;
import flash.geom.*;
import flash.filters.*;
img = BitmapData.loadBitmap("imagen");
w = img.width;
h = img.height;
attachBitmap(img, 1);
createEmptyMovieClip("sal", 0);
sal.attachBitmap(img, 1);
sal._y = 2*img.height;
sal._yscale = -100;
pt1 = new Point();
pt2 = new Point();
pt3 = new Point();
Mx = new Matrix();
ola1 = new BitmapData(w, h/6);
ola2 = new BitmapData(w, h/3);
ola3 = new BitmapData(w, h/2);
dM1 = new DisplacementMapFilter(ola1, new Point(0, 0), null, 4, 0, 20, "clamp");
dM2 = new DisplacementMapFilter(ola2, new Point(0, h/6), null, 4, 0, 50, "clamp");
dM3 = new DisplacementMapFilter(ola3, new Point(0, h/2), null, 4, 0, 120, "clamp");
onEnterFrame = function () {
   pt1.y -= .2;
   pt2.y -= .4;
   pt3.y -= .8;
   ola1.perlinNoise(0, 2, 1, 0, true, true, 4, true, [pt1]);
   ola2.perlinNoise(40, 4, 2, 0, true, true, 4, true, [pt2]);
   ola3.perlinNoise(80, 8, 1, 0, true, true, 4, true, [pt3]);
   sal.filters = [dM1, dM2, dM3];
};

Para ajustar a nuestras necesidades el efecto podemos variar los parámetros siguientes:
20, 50 y 120 de dM1, dM2 y dM3 para desplazar la escala Y del reflejo.
Los valores pt .y que dan la velocidad a las olas.
Los 3 primeros valores del perlinNoise para dar la agitación de las olas y el valor tercero de cada Perlin entre 1 y 5 para dotar de mayor "espejo" a cada zona al afinar por más octavas.
También podemos hacer que los tres tipos de ola se "solapen" más entre sí variando su tamaño y el punto de inclusión en el desplazamiento.
Para ondas lineales simplemente pondremos a 0 los primeros valores (x) de cada perlinNoise.

Efecto rio:



En este caso modificamos en cada frame no solo el perlin en Y sino también en X consiguiendo un movimiento lateral que simula un arroyo. Solo utilizamos un desplazamiento aunque podemos hacerlo como en el caso del lago y variar X e Y a tres velocidades para dar más sensación de profundidad si fuera necesario.

Código :

import flash.display.BitmapData;
import flash.geom.*;
import flash.filters.*;
img = BitmapData.loadBitmap("imagen");
attachBitmap(img, 1);
createEmptyMovieClip("sal", 0);
sal.attachBitmap(img, 0);
sal._y = 2*img.height;
sal._yscale = -100;
ola = new BitmapData(img.width, img.height);
pt = new Point();
dM = new DisplacementMapFilter(ola, new Point(), 1, 1, 0, 40, "ignore");
onEnterFrame = function () {
   pt.y -= .3;
   pt.x -= 1.7;
   ola.perlinNoise(20, 4, 1, 0, true, true, 1, true, [pt]);
   sal.filters = [dM];
};


Efecto cascada:



Utilizamos un código similar al usado para el lago con tres niveles pero sin hacer espejo de la imagen y ajustamos los parámetros:

Código :

import flash.display.*;
import flash.geom.*;
import flash.filters.*;
img = BitmapData.loadBitmap("imagen");
w = img.width;
h = img.height;
createEmptyMovieClip("sal", 0);
sal.attachBitmap(img, 1);
pt1 = new Point();
pt2 = new Point();
pt3 = new Point();
ola1 = new BitmapData(w, h/6);
ola2 = new BitmapData(w, 3+h/30);
ola3 = new BitmapData(w, 4*h/5);
dM1 = new DisplacementMapFilter(ola1, new Point(), null, 4, 0, 20, "clamp");
dM2 = new DisplacementMapFilter(ola2, new Point(0, h/6), null, 4, 30, 50, "clamp");
dM3 = new DisplacementMapFilter(ola3, new Point(0, h/5-3), null, 4, 0, 90, "clamp");
onEnterFrame = function () {
   pt1.y -= .4;
   pt2.y -= 2.5;
   pt3.y -= 3;
   ola1.perlinNoise(4, 2, 1, 0, false, true, 4, true, [pt1]);
   ola2.perlinNoise(8, 4, 1, 0, false, true, 4, true, [pt2]);
   ola3.perlinNoise(3, 7, 1, 0, false, true, 4, true, [pt3]);
   sal.filters = [dM3, dM2, dM1];
};

Para ampliaciones, dudas y comentarios sobre estos efectos consultar en este post:
¿Cómo lograr un efecto de agua?

Para más información del uso de estos efectos, puedes ver otros:

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate