Comparando imágenes en Actionscript 3.0 con compare() |
Etiquetas: BitmapData draw Bitmap compare |
Esta prueba se me ha ocurrido hoy en el metro. Es algo muy sencillo, hacer una captura de un video, y compararla con la anterior para sacar los pixels diferentes y mostrar esta diferencia. La comparación se puede hacer con la función compare de BitmapData:
Hay que tener "cuidado" con esta función, ya que no siempre devuelve un objeto BitmapData. Según la ayuda de Flash: Si los objetos BitmapData son equivalentes (con la misma anchura y altura e idénticos valores de píxeles), el método devolverá el número 0. Si la anchura de los objetos BitmapData no es la misma pero la altura sí, el método devolverá el número -3. Si la altura de los objetos BitmapData no es la misma pero la anchura sí, el método devolverá el número -4. El video que he utilizado para la prueba es D.A.N.C.E., del grupo francés Justice. |
Actionscript 2.0: Problemas al pasar de texto a número |
Etiquetas: String Number parseInt |
Esta "trampa" de Flash, la descubrí la semana pasada en uno de los foros de Cristalab. Uno de los usuarios tenia problemas al pasar Strings a números en Actionscript 2.0, siempre que los Strings tuvieran algún cero por la izquierda. Por ejemplo, si en Actionscript 2.0 hacemos:
El trace devuelve...27. Como ya pensaba que era alguna especie de bug maligno de Flash, de esos que surgen en los momentos de crisis y con los que pierdes una tarde tranquilamente, se me ocurrió solucionarlo eliminando los ceros iniciales con un while:
Devuelve 33. Al mismo tiempo, Zguillez y Anduril encontraron la respuesta "lógica" a la maldad de Flash: En Actionscript 2.0, si creas un número con un 0 como cifra inicial, Flash lo toma como número octal. Por eso "033" daba 27 al pasar a número: 033 = 3x8 + 3x1 = 27 Sabiendo esto, podemos convertir la cadena a entero en base 10, mediante la función parseInt, que recibe como parámetros la cadena y la base a la que queremos convertir el número:
Devuelve 33. Por último, comentar que esto solo ocurre en Actionscript 2.0. Según la ayuda de Flash: |
Actionscript 3.0: Ejemplo básico para cargar imágenes |
Etiquetas: Loader URLRequest contentLoaderInfo addEventListener |
Uno de los primeros post que escribí, fue
Lo primero que tenemos que hacer es crear un objeto tipo Loader. Los Loader son los encargados de cargar imágenes (JPG, PNG o GIF) y SWFs en Flash. Esto lo hacemos así:
Ahora que tenemos un "cargador", hay que pedirle que informe de los eventos de la carga. Hay muchos eventos, pero los principales son tres: -Error al cargar la imagen (no se encuentra el archivo) -Progreso de la imagen (nos informa del progreso de la carga) -Imagen cargada (la imagen ya se ha cargado y podemos trabajar con ella). Para que el Loader nos informe de estos eventos, tenemos que asociar cada uno a una función. Es decir, debemos decirle: "si la carga falla, ejecuta esta función, y si se carga, ejecuta esta". Esta charla, traducida a Actionscript 3.0 es:
Lo que hemos hecho es "añadir listener de los eventos". Como se puede ver, cada evento vá asociado a una función. El evento Event.COMPLETE, por ejemplo, está asociado a la función "imagenCargada". Estas funciones suelen tener esta apariencia:
Como se puede ver, cada función recibe un parámetro (al que hemos llamado "e", en este caso) que no servirá para obtener información del evento. Por ejemplo, cuando pongamos a cargar la foto, se comenzará a ejecutar periódicamente la función imagenProgreso hasta que termine la carga. Cada vez que Flash ejecute esa función, pasará como parámetro un "e distinto", que contendrá información sobre el progreso de carga en los atributos bytesLoaded y bytesTotal del evento. Una vez que tenemos añadidos los eventos, tenemos que cargar la imagen mediante la función load:
Y listo. El loader que hemos creado se encargará de ejecutar las funciones asignadas a los eventos que le hemos asociado. El evento más importante es Event.COMPLETE, que ejecuta la función imagenCargada cuando el archivo termina de cargarse. Podemos acceder al archivo dentro del parámetro e.target.content den evento. El código completo, sería el siguiente: |
Actionscript 3.0: Aplicar estilos CSS a campos de texto |
Etiquetas: StyleSheet parseCSS styleSheet htmlText |
![]() |
Los campos de texto en flash pueden contener texto simple o texto en formato HTML. El texto en formato HTML se almacena en la propiedad htmlText. Sobre los campos con texto HTML podemos aplicar hojas de estilo CSS, creadas en el código de la aplicación o cargadas en tiempo de ejecución. En este ejemplo vamos a ver como cargar un archivo css, y aplicar estos CSS a un TextField que contiene un teto HTML. La hoja de estilos que vamos a utilizar, es esta:
Lo primero que tenemos que hacer, es cargar la hoja de estilos. Para ello, utilizamos una instancia de Loader:
Una vez cargado el archivo, salta el evento COMPLETE, y creamos una instancia de StyleSheet, parseamos el CSS cargado, y se lo aplicamos al campo de texto. Después de aplicar el CSS al campo de texto, podemos rellenar el campo con el texto HTML que queramos:
El código completo, y el ejemplo en Flash, tras el salto. |
Papervision GreatWhite: crear un plano con dos caras |
Etiquetas: Plane DisplayObject3D Viewport3D BasicRenderEngine |
![]() |
Existen dos maneras de crear una plano con dos caras en Papervision3D: -Crear un cubo con una profundidad de 1pixel, y utilizar las caras delantera y trasera como caras del plano. -Crear un contenedor DisplayObject3D, y meter dentro dos planos. El plano "b" debe tener una profundidad de 1 y una rotatión de -180º. El segundo método es el que me parece más cómodo, ya que gestionar los materiales con un cubo es más engorroso que con un plano. Un ejemplo de plano con dos caras podrías ser: |
Actionscript 2.0: Como dibujar un círculo |
Etiquetas: lineTo lineStyle beginFill |
![]() |
En la API de dibujo de Actionscript 2.0 no existe ninguna función para dibujar directamente un círculo (en Actionscript 3.0 tenemos drawCircle()). Sin embargo, podemos dibujar círculos con dos métodos diferentes. El primero es el más intuitivo. Se trata de unir diversos puntos con lineTo() para formar el círculo. Por ejemplo podemos utilizar una función como esta para crear un círculo:
Como se puede ver en la función son matemáticas básicas. Unimos 360 puntos, calculando las coordenadas con seno y coseno, y forman un círculo. En realidad es un polígono de 360 lados, pero los lados no se ven planos porque son muy pequeños. Para figuras muy grandes, se podría mejorar la función utilizando curveTo() en lugar de lineTo():
La función es la misma, pero en vez de unir los puntos por rectas, los unimos por curvas. La tercera opción que conozco para dibujar un círculo, es la más rápida e ingeniosa. Se trata de dibujar una linea muy pequeña, pero con un grosor igual al diametro que buscamos. Sería como "dibujar un punto muy gordo". El resultado es el más exacto de los 3, además del más eficiente.
|
Actionscript 3.0: optimizaciones (II) |
Continuación del artículo de |
Actionscript 3.0: optimizaciones (I) |
Etiquetas: Math.floor Math.abs |
Este artículo recoge algunos test de rendimiento para diversas operaciones en Actionscript 3.0. Este es un tema que me interesa bastante, asi que espero hacer mas test e ir ampliando información en el futuro. Los test se han realizado en un Core2 6420 2,13Ghz, con 3GB de RAM y Windows Vista Home Premium de 32 bits. La versión de Flash Player es la 10,0,2,54.
Recorrer elementos de un Array (de 1 millón de elementos)
Resultado: 130 ms
Si sustituimos el tipo de i de Number a uint:
Resultado: 95 ms
Si almacenamos matriz.length en una variable:
Resultado: 23 ms
En definitiva, solo con poner uint (entero positivo) como tipo de i, y con almacenar la longitud de la matriz en una variable, hacemos que el bucle se ejecute 5,6 veces más rápido. Redondear números (Math.floor)
Resultado: 163 ms
Resultado: 29 ms
Resultado: 18 ms
Este test me ha sorprendido mucho. Convertir el número a int(entero), es 9 veces más rápido que utilizar Math.floor(). Teniendo en cuenta que el resultado es el mismo, y que encima int tiene menos letras que Math.floor, no veo motivos para no desterrar a Math.floor().
Obtener el valor absoluto de un número (Math.abs)
Resultado: 145 ms
Resultado: 26 ms Es decir, obtener el valor absoluto "a mano", 5,5 veces más rápido que utilizar Math.abs() |
AS3Dmod: utilización básica con Papervision |
Etiquetas: Bend ModifierStack Phase LibraryPv3d viewport3D BasicRenderEngine Plane |
![]() |
AS3Dmod es una libreria de modificadores para objetos 3D. Actualmente AS3Dmod dispone de 7 modificadores (doblar, deformar...) que funcionan con Papervision3D, Away3D, Sandy3D y Alternativa3D. Aunque hay muy poca documentación (sobre todo en castellano), es bastante fácil de utilizar. Los pasos para poder utilizarla son los siguientes: -Descargar AS3Dmod: -Saber utilizar alguno de los 4 motores 3D compatibles. Puedes ver tutoriales de Papervision3D y Away3D en esta misma página. -Una vez tenemos nuestra escena 3D en alguno de los motores, creamos una instancia de ModifierStack. El "modifier stack" es un link entre el objeto que queremos modificar y los modificadores:
Podemos ver como se pasan como parámetro un objeto indicando la librería que vamos a utilizar (en este caso Papervision), y el objeto que vamos a modificar (un plano). -Ahora necesitamos crear un modificador, y añadirlo a mstack. Para el ejemplo he utilizado "Bend", que recibe como parámetros la fuerza y el lugar donde se aplica:
-Por último, cada vez que se haga un cambio en el modificardor, debemos aplicarlo (algo asi como ordenar que se renderice):
Para este ejemplo he utilizado una clase de AS3Dmod que se llama Phase. Esta clase sirve para crear una animación tipo seno. Es decir, nosotros incrementamos su valor, y ella controla de que siempre esté entre -1 y 1. Es decir, si incrementamos su valor en 0.5 en cada fotograma, cuando llegue a 1 volverá sobre sus pasos hasta valer -1, y viceversa. Este es el código completo comentado: |
Dibujar en un cristal con vaho en Actionscript 3.0 |
Etiquetas: addEventListener MOUSE_MOVE drawCircle beginFill endFill |
![]() |
Este ejemplo muestra como hacer el efecto de "pintar sobre el vaho" en un cristal. Esta es la manera más sencilla que en encontrado de hacerlo, desde el punto de vista de alguien con pocos conocimientos de programación. Para hacer este efecto necesitamos: -Imagen del cristal con vaho:
-Imagen de cristal sin vaho:
-Nociones de AS3 (Sobre todo de la Los pasos a seguir serían los siguientes: -Importar las dos imágenes a Flash, y poner cada una en una capa (la imagen sin vaho por encima de la con vaho), en la posición (0,0) -Crear un clip vacio y llamarlo "Mascara_mc". Ponerlo en (0,0) -Hacer que "Mascara_mc" sea la mascara para la imagen sin vaho. Aquí tenemos un pequeño "problema", y es que al estar vacio, no nos va a aplicar bien la máscara. Por ello, antes de ponerlo como máscara, nos metemos dentro de "Mascara_mc" y dibujamos un pequeño cuadrado. La linea de tiempo nos quedaría asi:
-Por último, tenemos que programar la escena, para que cuando hagamos click, se dibuje dentro de "Mascara_mc" y se vaya destapando la imagen con vaho. El código en Actionscript 3.0, y el resultado, son los siguientes: |