Usando simbolos de tipo bitmap con ActionScript 3

14 de noviembre de 2010

Libro electrónico gratis:<br>Eduardo Saavedra Estudio sobre la invasión de los árabes en España
Libro electrónico gratis:
Eduardo Saavedra
Estudio sobre la invasión de los árabes en España
Libro electrónico gratis:<br>Stendhal Rojo y Negro
Libro electrónico gratis:
Stendhal
Rojo y Negro
Libro electrónico gratis:<br>Calderón de la Barca La vida es sueño
Libro electrónico gratis:
Calderón de la Barca
La vida es sueño

En Adobe Flash una forma de utilizar símbolos (symbols) del tipo mapa de bits (bitmap) es arrastrarlos desde la biblioteca (library) hacia el escenario (stage).

Pero también se puede utilizar Action Script 3 para insertar en una animación símbolos del tipo bitmap localizados en la biblioteca.

A continuación se muestra una forma para insertar símbolos del tipo mapa de bits (bitmap) en una animacion usando Action Script 3. Los símbolos de tipo gráfico (graphic) no pueden ser insertados en una animación usando Action Script 3. Los símbolos del tipo clip de película (movieclip), botones (button), componentes(component) y sonido (sound) emplean un procedimiento diferente al aquí descrito.

Para insertar un símbolo del tipo bitmap con Action Script 3 hay que abrir la ventana de la biblioteca, esto puede hacerse desde la barra de herramientas con la opción ventana (window) y luego elegir la opción Biblioteca (Library):

En la ventana de la Biblioteca hacemos click sobre nuestro símbolo con el botón derecho del ratón y se desplegará un menú:

En el menú que aparezca se debe hacer click en la opción Vinculación (Linkage)

Se abrirá una nueva ventana mostrando las propiedades de vinculación (Linkage Properties) de nuestro símbolo:

Para poder usar nuestro símbolo con Action Script 3 debemos activar la opción Exportar para Action Script (Export for Action Script):

Se activará automáticamente la opción exportar en primer fotograma (Export in first frame):

También se activarán y se llenaran automáticamente los campos Clase (Class) y Clase Base (Base Class):

En el campo clase (class) aparecerá el "nombre" del símbolo, el cual debemos utilizar para referirnos a él en Action Script 3, en este ejemplo "simbolo_con_as3":

Para terminar es necesario presionar el botón OK / ACEPTAR:

Aparecerá una advertencia indicándonos que aún no existe una definición para esta clase pero que automáticamente se creará una. Hay que hacer click en OK / ACEPTAR:

Tras haber exportando nuestro símbolo es posible ya utilizarlo.

Para insertar el símbolo en nuestro escenario (stage) es necesario usar este código:

var simbolo_datos:BitmapData = new simbolo_con_as3(0,0);
// crea el objeto "simbolo_datos" del tipo BitmapData
// que almacena la información del bitmap a utilizar
// "simbolo_con_as3" es el nombre del simbolo en la libreria

var simbolo_en_escenario:Bitmap = new Bitmap(simbolo_datos);
// crea el objeto simbolo_en_escenario en este se guardará
// una copia de nuestro simbolo "simbolo_con_as3" (crea una instancia)

addChild(simbolo_en_escenario);
// agrega el simbolo al escenario


¿Qué es lo que se hizo? Al activar la opción Exportar para Action Script permitimos que nuestro símbolo pueda insertarse dentro de nuestra animación usando Action Script.

Al activar la opción exportar en primer fotograma se le indica a flash que el símbolo se cargará automáticamente al inicio de la animación aún si el símbolo se usa al final de la animación. Téngase esto en cuenta para considerar los tiempos de descarga. Si hay 50 símbolos exportados en el primer fotograma, los 50 símbolos tendrán que cargarse antes de que la animación comience a reproducirse.

Los campos Clase (Class) y Clase Base (Base Class) se activan y se llenan automáticamente. En el campo clase (class) aparecerá el "nombre" del símbolo el cual debemos utilizar para referirnos a él en Action Script 3:

En una animación NO PUEDE haber dos símbolos diferentes con el mismo "nombre", que utilicen la misma clase. Muchos errores al publicar el archivo .swf se deben al uso de dos símbolos diferentes que usan la misma clase, el mismo nombre. Este error es muy común cuando se usan paquetes (packages) externos. Es un error crear en el paquete un símbolo / objeto con el nombre "simbolox" y al mismo tiempo crear en la biblioteca un símbolo con el nombre "simbolox".

Al incurrir en este error el mismo programa alertaría sobre esta situación:

Traducción. "Por favor ingrese un nombre de clase único que no esté asociado con otro símbolo en la biblioteca."

Se puede hacer caso omiso a esta advertencia. Se puede incluso publicar el archivo .swf pese a esta advertencia. El resultado será que "algo" no funcionará en nuestra animación...

Insisto por que es muy importante y es motivo de desvelos: en una animación NO PUEDE haber dos símbolos diferentes usando la misma clase, con el mismo "nombre".

En el campo Clase Base (Base Class) aparecerá la clase a la que pertenece nuestro símbolo. La clase a la que pertenece nuestro símbolo determina los metodos y propiedades que posee. Por omisión la Clase Base de un bitmap es flash.display.BitMapData; con ello nuestro símbolo "hereda" los métodos, eventos y propiedades propias de un bitMapData.

A continuación se explica línea por línea el código anterior. En color se señala lo que NO DEBE MODIFICARSE pues son las funciones predefinidas de Action Script 3..

var simbolo_datos:BitmapData = new simbolo_con_as3(0,0);

Crea el objeto simbolo_datos que almacenará la información de nuestro bitmap. La palabra "BitmapData" después de los dos puntos : indica de que tipo es nuestro objeto. La palabra "simbolo_con_as3" después la palabra new se refiere al "nombre" (la clase) de nuestro símbolo en la biblioteca. Entre parentesis se colocan el ancho (width) y alto (height) de nuestro bitmap. Para este ejemplo funciona poner 0.

var simbolo_en_escenario:Bitmap = new Bitmap(simbolo_datos);

Crea el objeto simbolo_en_escenario que almacenará a nuestro símbolo. La palabra "Bitmap" después de los dos puntos : indica de que tipo es nuestro objeto. Con "new Bitmap(simbolo_datos)" se crea un bitmap a partir de la infomación almacenada en simbolo_datos. Esa información será almacenada en "simbolo_en_escenario".

addChild(simbolo_en_escenario);

Con el método addChild se despliega en el escenario/stage el simbolo previamente creado.

¿Para que tanta complicación para insertar un símbolo del tipo bitmap? ¿No es más fácil arrastrar el símbolo al escenario?

Usar Action Script 3 para insertar símbolos del tipo bitmap tiene ventajas. Con Action Script 3 podemos por ejemplo:

Este un ejemplo sencillo de lo que se puede hacer insertando símbolos del tipo bitmap con Action Script 3:

En el ejemplo arriba mostrado:

Este es el código utilizado:

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// CODIGO EN FRAME 1
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

var bitmap_origen:BitmapData = new simbolo_con_as3(0, 0);
// crea el objeto "simbolo_datos" del tipo BitmapData
// almacena la información del bitmap a utilizar
// "simbolo_con_as3" es el nombre del simbolo en la libreria

var rect:Rectangle = new Rectangle();
// creamos el objeto "rect" del tipo Rectangle
// nos permitira dividir en fragmentos el bitmap

rect.x=0;
// Definimos la posicion en el plano x del objeto rectangulo
// la coordenada se refiere a la coordenada RELATIVA DENTRO DEL bitmap
// en flash hay posiciones absolutas y relativas :)

rect.y=0;
// definimos la posicion en el plano y del objeto rectangulo
// en este caso la coordenada se refiere a la coordenada
// RELATIVA DENTRO DEL bitmap
// en flash hay posiciones absolutas y relativas :)

rect.width=100;
// definimos al ancho del objeto rectangulo
// este ancho sera el ancho de cada uno de los fragmentos en que se dividira el bitmap

rect.height=100;
// definimos el alto del objeto rectangulo
// este ancho sera el alto de cada uno de los fragmentos en que se dividira el bitmap

var pt:Point = new Point();
// crea un punto de referencia para definir los fragmentos en que se dividira el bitmap

pt.x =0;
// posicion en x del punto de referencia

pt.y =0;
// posicion en y del punto de referencia

var xpos:int=600;
// definimos la posicion en x dentro del escenario (stage) para comenzar
// a colocar los fragmentos del bitmap

var ypos:int=0;
// definimos la posicion en y dentro del escenario (stage) para comenzar
// a colocar los fragmentos del bitmap

var orden_reproduccion:Array = new Array;
// crea un array para almacenar el nombre de los fragmentos en que
// se dividira el bitmap
// nos permitira modificar el orden en que se muestran los fragmentos
// en que se dividira el bitmap

for(var i:int=1; i<13; i++)
// con ayuda del loop for dividimos en 12 fragmentos el bitmap
// cada fragmento tiene un tamaño de 100 pixeles de ancho por 100 pixeles de alto
//se usa un bitmap con un tamaño de 400 pixeles de alto por 300 pixeles de alto
{

var bit_map_copiado:BitmapData = new BitmapData(100, 100, false, 0x0000CC44);
// crea el objeto bit_map_copiado de un tipo BitmapData
// los parámetros / propiedades de ese objeto se señalan entre paréntesis (ancho, alto, transparencia, color_de_fondo);
// bit_map_copiado servirá como "lienzo" donde copiaremos parte del bitmap
// el ancho y alto corresponde al tamaño de cada una de los fragmentos en que dividiremos nuestro bitmap

bit_map_copiado.copyPixels(bitmap_origen, rect, pt);
// utiliza la funcion copyPixels para copiar los pixeles del bitmap original y los almacena en bit_map_copiado
// los parametros de la funcion copyPixels (bitmap_origen, area_a_copiar, coordenadas_a_coopiar)
// bitmap_origen es el objeto que almacena la informacion de nuestro bitmap original
// rect es una variable que define el area a copiar (esta variable se definio lineas arriba)
// pt es una variable que define el punto de referencia para colocar el area copiar (esta variable se definio lineas arriba)

var bitmap_escenario:Bitmap = new Bitmap(bit_map_copiado);
// crea el objeto bit_map_stage del tipo Bitmap
// utiliza la iformacion gurdada en el objeto bit_map_copiado
// que contiene un fragmento del bitmap original

var mc_contenedora:mc_empty=new mc_empty();
// crea un movieclip vacio
// Dentro de ese movieclip se almacenara el bitmap recien creado.
// El bitmap creado se alamacena dentro de un clip de pelicula(movieclip)
// para tener disponibles las propiedades, metodos y eventos propios de un movieclip

addChild(mc_contenedora);
// inserta el movieclip vacio en el escenario (stage)

mc_contenedora.addChild(bitmap_escenario);
// inserta el fragmento del bitmap dentro del movieclip vacio

mc_contenedora.x=xpos;
// define la posicion en x del movieclip

mc_contenedora.y=ypos;
// define la posicion en y del movieclip

mc_contenedora.alpha=0;
// define la transparencia del movieclip
// el movieclip sera primero transparente y poco a poco se hara visible

mc_contenedora.name = "mc" + i;
// asignamos un nombre al movieclip para poder controlarlo

mc_contenedora.xfinal = xpos;
// define la posicion final donde colocaremos al movieclip
// el movieclip aparecera a la izquierda y poco a poco ocupara su posicion final

xpos += 100;
// tras haber creado un fragmento del bitmap el siguiente fragmento estara 100 pixeles a la derecha

rect.x +=100;
// tras haber creado un fragmento del bitmap la siguiente area a copiar del bitmap original estara 100 pixeles a la derecha

orden_reproduccion.push(mc_contenedora.name);
// agregamos a nuestro array el movieclip recien creado

if(i%4==0)
// en este ejemplo se usa un bitmap con un tamaño de 400 pixeles de alto por 300 pixeles de alto
// cuando se han colocado 4 fragmentos de 100 pixeles de ancho es necesario crear una nueva fila con fragmentos
{

ypos += 100;
// crea una nueva fila de fragmentos
// el siguiente fragmento estara 100 pixeles hacia abajo

rect.y += 100;
// el area a copiar se desplaza hacia abajo
// la siguiente area a copiar del bitmap original estara 100 pixeles hacia abajo

xpos = 600;
// definimos la posicion en el plano de "x" dentro del escenario (stage) para comenzar a colocar la nueva fila de fragmentos

rect.x = 0;
// tras crear una fila definimos una nueva posicion en el plano "x" del objeto rectangulo
// en este caso la coordenada se refiere a la coordenada RELATIVA DENTRO DEL bitmap
// en flash hay posiciones absolutas y relativas :)

}

}

var pelis_total:int = orden_reproduccion.length ;
// contamos cuantos elementos tiene nuestro array
// contamos cuantas peliculas se crearon

var pelis_play:int=0;
// define el primer fragmento a reproducir
// en un array el 0 es el primer elemento
// se puede randomizar el orden del array para desplegar los fragmentos al azar

function mover(ev:Event):void
// funcion que movera cada fragmento
{

if(ev.target.x < ev.target.xfinal)
// cada fragmento tiene una posición inicial y una posición final
// si el fragmento aún no alcanza su posción final se moverá hacia ella

{

ev.target.x += 50;
// el fragmento se desplaza 50 pixeles hacia la derecha

ev.target.alpha += .2;
// el fragmento aumenta su transparencia en .2

}
else
{

ev.target.removeEventListener(Event.ENTER_FRAME, mover);
// si el fragmento llega a su posición final se remueve el método / evento que lo mueve

}

}

function randomizaArray(arr:Array):Array
// función para randomizar un array
{
var len:int = arr.length;
var temp:*;
var i:int = len;
while (i--) {
var rand:int = Math.floor(Math.random() * len);
temp = arr[i];
arr[i] = arr[rand];
arr[rand] = temp;
}
return arr;
}

randomizaArray(orden_reproduccion);
// randomizo el array orde_reproduccion
// se randomiza para que el orden de los fragmentos sea diferente cada vez

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// CODIGO EN FRAME 2
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

MovieClip(getChildByName(orden_reproduccion[pelis_play])).x -= 500;
// elige un fragmento y lo mueve 500 pixeles a la izquierda
// se hace referencia al fragmento por su nombre, el nombre se obtiene con orden_reproduccion[pelis_play]
// orden_reproduccion es el nombre del array que almacena los fragmentos existentes
// pelis_play es el elemento a elegir en el array orden_reproduccion
// getChildByName es una función predefinida de flash que nos permite elegir un movieclip por su nombre
// con MovieClip() se le indica a flash que se está trabajando con un movieclip

 

MovieClip(getChildByName(orden_reproduccion[pelis_play])).addEventListener(Event.ENTER_FRAME, mover);
// al fragmento elegido se le asigna la función / método mover
// la función se activa con el evento ENTER_FRAME

pelis_play++;
// aumentamos en uno el valor de pelis_play
// con ello se eligirá el siguiente elemento del array orden_reproduccion

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// CODIGO EN FRAME 3
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

if(pelis_play < pelis_total)
// sin hay fragmentos que no se muestran regresa al frame anterior para mostrarlos
{

gotoAndPlay(2);

}

Están disponibles los archivos .fla de este ejercicio para un análisis más detallado.

Sitios de interés:

Creando animaciones con canvas, javascript y HTML5

Swiffy, una herramienta para crear animaciones canvas a partir de animaciones Flash

Mostrando contenido alternativo a flash

¿HTML5 como alternativa a Adobe Flash?

Usando clases (class) y objetos en ActionScript 3

Usando símbolos del tipo bitmap con ActionScript 3

Usando símbolos con ActionScript 3

Cargando un archivo .swf dentro de otro con ActionScript 3


Comenta y opina este texto     Lee mi libro de visitas
© 1997-2024 Alain García
albegago@hotmail.com
Twitter: Youtube @feesgo
YouTube Youtube
El vínculo a este documento es:

Compartir en facebook Compartir en twitter Compartir en whatsapp Rss

Puedes apoyar a este sitio invitándome a comer...

Este sitio utiliza cookies propias y de terceros para mejorar sus servicios. Si continua navegando, entendemos que acepta su uso. Política de Privacidad