Cómo crear una máquina de estados en AS.

Como crear una Maquina de Estados from Emmanuel Ulloa on Vimeo.

He aqui el codigo:

//Estados: cuadrado, circulo, estrella
//***State Machine start
var _state:String = "";

function leaveState()
{
   switch(_state)
   {
     case "cuadrado":
     cuadrado_mc._xscale = cuadrado_mc._yscale = 100;
     break;
     case "circulo":
     circulo_mc._alpha = estrella_mc._alpha = 100;
     break;
     case "estrella":
     delete estrella_mc.onEnterFrame;
     estrella_mc._rotation = 0;
     break;
   }
}

function enterState()
{
   switch(_state)
   {
     case "cuadrado":
     cuadrado_mc._xscale = cuadrado_mc._yscale = 200;
     break;
     case "circulo":
     circulo_mc._alpha = estrella_mc._alpha = 20;
     break;
     case "estrella":
     estrella_mc.onEnterFrame = function()
     {
        estrella_mc._rotation += 5;
     }
     break;
   }
}

function setState(val:String)
{
     if(val != "")
     {
        leaveState();
        _state = val;
        enterState();
     }
}
//***State Machine end
//Codigo normal
cuadrado_mc.onPress = function(){setState("cuadrado")};
circulo_mc.onPress = function(){setState("circulo")};
estrella_mc.onPress = function(){setState("estrella")};
setState("cuadrado");

Un video player basico en AS3

Hoy ayudando a unos compañeros del trabajo a crear unos controles para un Video Player volvi a repasar los metodos para crear uno desde cero. Ahora bien la pregunta es para que crear uno desde cero si ya existen los componentes? Pues por tamaño, los componentes de Flash agregan como 30kb y lo que estaban desarrollando era para banners donde el mínimo a veces es de 40kb para el polite preload.

import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;

//Buenas noticias, el video object ahora se puede crear por codigo
var videoObj:Video = new Video();
var conn:NetConnection = new NetConnection();
var ns:NetStream = new NetStream(conn);

conn.connect(null); //Esto se debe a que el video es local
videoObj.attachNetStream(ns);
ns.play("miVideo.flv");
addChild(videoObj);

//Luego se pueden usar diferentes metodos para reproducir y detener los videos
ns.pause(); //pausa (detiene) el video
ns.resume(); //reinicializa un video pausado
ns.seek(15); //avanza el video hasta el segundo 15

Certificación en Flash

Una de las preguntas mas comunes de mis estudiantes es: Como me certifico? Lo que recomiendo es que estudien mucho de Flash, practiquen con la herramienta a tiempo completo (ojala en un trabajo) durante unos 6 a 9 meses y luego tomen el examen basico, el ACA (Adobe Certified Associate).

Estos examenes se pueden tomar en CyberU

setTimeout en AS2

Generalmente cuando yo querí retardar el lanzamiento de una función en AS2 utilizaba el setInterval. El problema es que el setInterval se repite cada n cantidad de veces, a veces se pierde el puntero y causa problemas en general si no se usa correctamente. Hace poco descubrí que existe una función como en JavaScript que dispara una única vez: es el setTimeout.

//forma comun
setTimeout(functionName,1000,"parametro");
//otra forma
setTimeout(this,"functionName",1000,"parametro");
//para clases se utiliza un poco diferente ya que no fue implementado como una funcion intrínseca
_global.setTimeout(this,"functionName",1000,"parametro");

BitmapData en AS3

De las mejores cosas que tiene Flash desde el player 8 es el BitmapData. Dicha clase permite obtener un mapa de bits de un movieclip especifico y manipularlo como se manipularia en un programa de edición de imagenes (como Photoshop). En AS3 es un poco diferente de como se hacía en AS2, ya que los movieclips no tienen el metodo de attachBitmap. Lo que se hace es crear una instancia de Bitmap y esta se agrega a un display object (como un Sprite o un MovieClip).

import flash.display.Bitmap;
import flash.display.BitmapData;

var misDatosDeBitmap:BitmapData;
var miBitmap:Bitmap;
//photo_mc es un movieclip en el stage 

//Creamos el mapa de bits, le definimos su ancho y alto de una vez.
misDatosDeBitmap = new BitmapData(photo_mc.width,photo_mc.height);
//le sacamos una "foto" al movieclip de origen
misDatosDeBitmap.draw(photo_mc);
//ahora creamos el objeto bitmap que agregaremos al stage
miBitmap = new Bitmap(misDatosDeBitmap);
//por ultimo agregamos el bitmap
addChild(miBitmap);

Parseando datos con estructuras propias.

Generalmente cuando pensamos en datos externos pensamos en XML. Eso por la ventaja de que XML es bastante verboso y puede ser editado muy fácilmente por cualquier persona.

Sin embargo en mis proyectos utilizo XML solo cuando son estructuras muy complicadas. Cuando quiero usar datos que son simplemente registros de bases de datos con las mismas cantidad de campos utilizo un simple archivo de texto. Utilizando el metodo split() puedo parsear muy facilmente los datos. La ventaja es que los archivos son mas livianos y se exactamente donde estan los datos sin necesidad de acudir a E4X.

Ejemplo(el archivo fue escrito en Notepad utilizando UTF-8 en el metodo de encoding, el primer campo es el nombre, segundo la edad y tercero la residencia):

Emmanuel,31,Heredia
Maria,23,Heredia
Pedro,35,Alajuela
Juan,53,Guanacaste

El codigo para parsear los datos sería el siguiente:

import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.events.Event;

var file:URLLoader = new URLLoader();
var datos:Array = [];

function miParser(evento:Event)
{
 var datosCrudos:String = evento.target.data;
 //Vamos a probar que se pueda romper en filas cada uno de las lineas de texto
 //Probemos hacer split con los caracteres de nueva linea y retorno de carro
 datos = datosCrudos.split(String.fromCharCode(13,10));
 if(datos.length == 1)
 {
  //no encontro 10,13.  Probemos solo con 10.
  datos = datosCrudos.split(String.fromCharCode(10));
  if(datos.length == 1)
  {
   //no encontro 10. Probemos solo con 13.
   datos = datosCrudos.split(String.fromCharCode(13));
   //si despues de esto no encuentra nada quiere decir que solo hay un registro
  }
 }
 //ya sacamos las filas, saquemos ahora los campos
 for (var i:int = 0; i < datos.length; i++)
 {
  datos[i] = datos[i].split(",");
 }
 testearDatos();
}

function testearDatos()
{
 trace(datos[1][2]); //muestra 'Heredia'
}

file.addEventListener("complete", miParser);
file.dataFormat = "text";
file.load(new URLRequest("file.txt"));

cacheAsBitmap y transiciones de transparencia

Ayer un compañero de trabajo me preguntaba como podia hacer un efecto que le solicitaron para un banner. La idea era que aparecia la foto de una persona y poco a poco empezaban a aparecerle tatuajes en el cuerpo. En Photoshop le pasaron dos layers: uno con la foto de la persona y otro con los tatuajes. La solucion mas simple era cortar cada uno de los tatuajes y hacerles un tween en su propiedad de alpha. Sin embargo eso significaba crear una imagen por cada tatuaje (eran como 8) y por lo tanto el peso del banner se volveria muy grande. Utilizando la propiedad cache as bitmap de la paleta de propiedades y enmascarando por codigo los tatuajes con una pelicula con las transiciones en alpha que se necesitaban logramos utilizar solo dos imagenes. Es dificil de explicar por escrito, hay que verlo para enterderlo. Les adjunto un codigo que hice en AS3 que talvez les aclare lo que les cuento:
import flash.display.Sprite;
import fl.transitions.Tween;
import fl.transitions.easing.Strong;

var enmascarado:Sprite = new Sprite();
var mascara:Sprite = new Sprite();

enmascarado.graphics.beginGradientFill("linear",[0x00FF00,0x0000FF],[1,1],[127,255]);
enmascarado.graphics.drawRect(0,0,300,300);
enmascarado.graphics.endFill();

mascara.graphics.beginFill(0xFF0000);
mascara.graphics.drawCircle(100,100,100);

enmascarado.cacheAsBitmap = true;
mascara.cacheAsBitmap = true;

enmascarado.mask = mascara;

addChild(enmascarado);
addChild(mascara);

var tween:Tween = new Tween(mascara, "alpha", Strong.easeIn, 0, 1, 5, true);