Tornado de Imagenes+Profundidad

TORNADO MONERRIS

Seguimos con las imágenes, de momento solo queremos ver los thumbnails, puede que en un futuro le añadamos el código necesario para poder ver las fotos en grande. De momento solo “Twister”. Otra vez me toca agradecer a sargento por ser la inspiración de este ejercicio, el cual esta medio-basado en el suyo de tornado de palabras.


Características de nuestra película:

  1. Es “dinámica”:
    • No cargamos las fotos a mano, sino desde el exterior, no desde una base de datos sino de un documento XML, esto que quiere decir… Quiere decir que en un futuro si queremos más imágenes solo tendremos que poner las imágenes en la carpeta correspondiente y actualizar el XML, no tocaremos el .swf para nada ni el .fla. Esto puede ser interesante en algunos casos, para este no es del todo necesario solo es por hacer mis “pequeños experimentos”…
  2. Nunca es igual:
    • Cada vez que recarguemos el .swf saldrá de una manera ya que utilizamos muchas veces la función random.

Primeramente diseñaremos el XML que vamos a utilizar, este no se diseña con flash sino con cualquier editor de textos, como vamos a insertar de momento seis imágenes nos quedará un XML como este:

<?xml version=»1.0″ encoding=»iso-8859-1″?>
<fotos>
<foto tipo=».jpg»>
<nombre>foto1</nombre>
</foto>
<foto tipo=».jpg»>
<nombre>foto2</nombre>
</foto>
<foto tipo=».jpg»>
<nombre>foto3</nombre>
</foto>
<foto tipo=».jpg»>
<nombre>foto4</nombre>
</foto>
<foto tipo=».jpg»>
<nombre>foto5</nombre>
</foto>
<foto tipo=».jpg»>
<nombre>foto6</nombre>
</foto>
</fotos>

 

Pasamos a explicar un poquito… el motivo de poner el tipo como atributo de foto no es otro que por si alguna vez nos haga falta, en este flash no lo vamos a utilizar. <nombre>foto3</nombre> el motivo de poner el nombre así de encerrado es que si ponemos tabulaciones, estas cuando lo leemos del flash se leen como tal y no es lo que pretendemos.

 

Ahora ya tenemos el XML, nos creamos una película flash vacía, yo he utilizado un tamaño de 500×400, hay que tener en cuenta durante el ejercicio la anchura. Bueno ahora como hicimos en el ejercicio de galería con profundidad creamos un cuadradito que sea un MovieClip le ponemos como nombre “foto”. Nos introducimos dentro de él y en el cuadradito otra vez un MovieClip esta vez lo llamamos “contenedor_foto”:

Paso1

Pero a este lo instanciamos como “bobo_mc”, esto lo hacemos para no cargar la foto en el MovieClip llamado foto, ya que Flash nos va a dar problemas si lo hacemos directo, por eso hacemos este “doble MovieClip”:

Paso

Ya lo tenemos… pues volvemos a la principal y borramos el MovieClip de la escena, y nos vamos a nuestra biblioteca (que deberá continuar ahí) y ahora le damos a propiedades y le damos un identificador de vinculación:

paso3

Y ahora ya empezamos a teclear código, continuamos en la principal y nos vamos al primer fotograma e empezamos a insertar el código necesario para poder leer el XML:

// Creamos un objeto XML
fotosXML = new XML();
// Ajustamos su propiedad para que ignore los espac. en blanco
fotosXML.ignoreWhite = true;

eje_x=250;//es el eje_x de nuestra pelicula es la mitad de 500

// Asignamos las acciones cuando cargue el documento
fotosXML.onLoad = function( listo ){
if( listo ){
//trace(fotosXML.firstChild.childNodes.length );
//almacenamos el total de fotos que tenemos en el XML
totalFotos=fotosXML.firstChild.childNodes.length;
//Introducimos tantos movieclips como fotos hay con su nombre
for(i=0; i<totalFotos; i++){

}
}
}

// Definimos el documento a cargar
fotosXML.load( ‘fotos.xml’ );

 

Con este código lo tenemos preparado para leer, almacenamos el número de fotos y luego tenemos el for para empezar a crear los MovieClips… No me voy a poner a explicar como leer desde los XML, ya que es sumamente fácil, es como si tuviéramos un array multidimensional es decir fotosXML[][][][] y cada array corresponde a una entidad del XML podemos ir probando con el trace para ver que va saliendo, os recomiendo hacer esto ya que así conseguiremos llegar hasta donde queremos, y así uno se enseña a base de probar… Bien cuando recogemos los datos del xml estos no vienen como un String sino como objetos XML así que crearemos una variable nombreMC de tipo string donde almacenaremos el nombre de la foto y que este sea el nombre de la instancia del MovieClip que vayamos a attachar, recordad que attachMovie admite como nombres Strings. Así que al principio del código declaramos la variable “var nombreMC:String;” y luego dentro del for que teníamos antes añadimos este código quedando algo como esto:

fotosXML.onLoad = function( listo ){
if( listo ){
//trace(fotosXML.firstChild.childNodes.length );
//almacenamos el total de fotos que tenemos en el XML
totalFotos=fotosXML.firstChild.childNodes.length;
//Introducimos tantos movieclips como fotos hay con su nombre
for(i=0; i<totalFotos; i++){
nombreMC=(String) (fotosXML.firstChild.childNodes[i].childNodes[0].childNodes[0].nodeValue);
//le indicamos el siguiente nivel ya que sino no se crearan los movieClips
nivel = _root.getNextHighestDepth();
ref=_root.attachMovie(«fotoCarga», nombreMC, nivel);

}
}
}

Bueno recogemos el nombre de la foto desde el XML y le hacemos un cast como en C, es decir el valor recogido lo pasamos a String y lo guardamos en la variable nombreMC.
Seguidamente pasaremos a attachar movies tomando como instancia el nombreMC, acordaros que anteriormente habíamos puesto un identificador de vinculación a foto para poder attacharla, podemos ver que recojo el index de profundidad del último objeto y luego al hacer el attachMovie lo hacemos igualándolo a una variable de referencia llamada ref… no preguntéis porque estuve investigando pero la única manera de attacharmovies en un for y que en estas se carguen imágenes a la vez que se carguen hay que hacerlo así. De esta manera se cargarán tantos movieClips como imágenes haya en el XML, y fáciles de recoger ya que su nombre de instancia es el nombre que tiene en el XML…

paso2bis1

 

Ahora toca, cargar la imagen… de donde la cargamos pues la vamos a cargar desde el MovieClip foto si nos vamos a la biblioteca y hacemos dobleClick sobre él podemos estar viendo la línea de tiempo como si estuviera en nuestra película pero no lo esta, cuando salgamos se volverá a la biblioteca pero con los cambios realizados… En el primer fotograma e insertamos el siguiente código:

//BLOQUE1
//Cargar la foto en el bobo_mc que es el contenedor_foto
archivo=»thumbnails/» + this._name + «.jpg»;
bobo_mc.loadMovie(archivo);

//BLOQUE2
//Los situamos en el centro
//y le damos una y aleatoria
this._x=250;
this._y=random(300);

//BLOQUE3
x = random(10); // Posición incial en X
ampl = random(30)+150; // Amplitud de la onda
incrx = (random(10)+ 5 ) / 200; // Incremento del ángulo (radianes)
rot=random(4)+1;

onEnterFrame = function(){
//BLOQUE4
// Modificamos la posición en X haciendo uso del coseno de x
this._x = ( Math.cos( x ) * ampl ) + _root.eje_x;
this._xscale = Math.sin( x ) * 100;
this._alpha = ( Math.sin( x ) + 2 ) * 34;
//BLOQUE5
this._rotation += rot;
// Incrementamos el valor de x
x += incrx;
}

Pasamos a explicarlo por bloques:

Bloque1:
Al igual que el ejercicio de galeria de profundidad, cargamos la imagen que se encuentra en la carpeta “thumbnails” y como el nombre de la instancia es la misma que la de la foto solo falta añadirle el tipo.

Bloque2:
Lo situamos en medio, y le damos un valor aleatorio con random para colocarlo en el ejeY pero este random no es 400 sino 300 esto es para que no se nos vaya muy para arriba.

Bloque3:
Declaramos varias variables, todas ellas con random, el motivo de poner random es para que las imágenes no se muevan al unísono… de las que hay declaradas la única que no esta comentada es rot, que es el incremento de rotaciones del movieClip

Bloque4:
Dentro del EnterFrame viene el meollo del asunto… vamos a situar el objeto según el coseno de x, este va cambiando durante toda su vida, entonces si lo multiplicamos por su amplitud máxima y le sumamos el eje_x declarado en el _root conseguiremos un movimiento de izquierda a derecha. Y sabiendo la posición en el ejeX tambien vamos a escalar para conseguir el efecto de que da la vuelta, cuando el objeto se acerce algún extremos con el seno modificaremos su escala. Con esto ya da la vuelta el objeto y se pone del reves cuando esta detrás. Ahora solo queda el alpha que según sargento “Conociendo los valores de seno, si los multiplicamos por 100 (Math.sin( x ) * 100) para la transparencia, los valores de _alpha fluctuarían entre -100 y 100, eso no nos interesa, no queremos que el objeto sea completamente transparente en ningún momento. Veamos con la fórmula que se utilizó en el código: cuando se encuentre en los extremos (seno=0), el resultado será 2*34 = 68, cuando seno = 1 resultará 3*34 = 102 que será interpretado como 100, y cuando seno sea igual a -1, el resultado será 1*34 = 34. Entonces los valores de la opacidad variarán entre 34 y 100 por ciento” … logico… Para más información visitar este enlace, es donde lo entendí y lo pude aplicar, aqui

 

Bloque5:
Hacemos que de vueltas, e incrementamos la variable x para que no valga siempre lo mismo y así conseguir movimiento con cosenos.

 

Para conseguir un efecto más Twister vamos a hacer que las imágenes tengan diferentes escalas, volvemos a la principal y añadimos en el for luego de hacer el attachMovie las siguientes líneas donde a base de random modificamos sus esacalas. Quedando así:

fotosXML.onLoad = function( listo ){
if( listo ){
//trace(fotosXML.firstChild.childNodes.length );
//almacenamos el total de fotos que tenemos en el XML
totalFotos=fotosXML.firstChild.childNodes.length;
//Introducimos tantos movieclips como fotos hay con su nombre
for(i=0; i<totalFotos; i++){
nombreMC=(String) (fotosXML.firstChild.childNodes[i].childNodes[0].childNodes[0].nodeValue);
//le indicamos el siguiente nivel ya que sino no se crearan los movieClips
nivel = _root.getNextHighestDepth();
ref=_root.attachMovie(«fotoCarga», nombreMC, nivel);
reduccion=0.60+(random(50)/100);
ref.bobo_mc._xscale=ref._xscale * reduccion;
ref.bobo_mc._yscale=ref._yscale * reduccion;

}
}
}

 

Hacemos lo de reducción de esta manera, para que las imágenes no se escalen a una escala menor que el 60% y lo hacemos desde la principal ya que si lo realizamos dentro del movieClip tendríamos que poner _root y como son creadas desde la principal dinámicamente es más coherente hacerlo desde la principal después de attachar

Ahora solo queda la clásica imagen mía en el ejeX, insertar un movieClip con nombre pedro que tiene instanciado el nombre de pedro_mc y este es una imagen mía. Lo colocamos más o menos en medio de la escena:

paso4

Y le añadimos una profundidad de 100 al principio del código de la principal:

pedro_mc.swapDepths(100);

Pero que ocurre si lo ejecutamos que las imágenes pasan todas por delante del MovieClip para conseguir que pasen por detrás aprovechando que con seno le dábamos la vuelta a la escala, cuando esta sea negativa significa que esta detrás y si es positiva es que esta delante axial que con unos simples if’s en el enterFrame de foto conseguiremos el efecto deseado para ello introducimos los if’s siguientes:

onEnterFrame = function(){
//BLOQUE4
// Modificamos la posición en X haciendo uso del coseno de x
this._x = ( Math.cos( x ) * ampl ) + _root.eje_x;
this._xscale = Math.sin( x ) * 100;
this._alpha = ( Math.sin( x ) + 2 ) * 34;
if((Math.sin( x ) * 100) < 0){
profundidad=random(100);
this.swapDepths(profundidad);
}else{
profundidad=random(100)+200;
this.swapDepths(profundidad);
}

//BLOQUE5
this._rotation += rot;
// Incrementamos el valor de x
x += incrx;
}

 

Si esta detrás de pedro_mc le damos profundidad=random(100) ya que esta ira desde 0 a 99 nunca a 100 que es la de pedro_mc y al contrario es que esta delante a esto le sumamos 200 y siempre andará delante de pedro_mc.

paso5

Señores y señoras ya lo tenemos… lo hemos conseguido mirad la imagen y si queréis comprobarlo mirad en el enlace de resultado final.

RESULTADO FINAL

Existe un pequeño bug, que es cuando dos imagenes pasan por delante de pedro_mc estas empiezan a parpadear por el tema de profundidad, yo se como solucionarlo… y como no tengo comentarios dejo este bug en el aire a ver si alguien lo sabe solucionar…

Continúara…?

Deja un comentario