Showing posts with label actionscript. Show all posts
Showing posts with label actionscript. Show all posts

¿Cómo crear objetos arrastrables en Actionscript 3.0?

Arrastrar un objeto en Actionscript es uno de los conocimientos básicos que se requieren a la hora de crear interactividad. La lógica básica es la siguiente:

  1. Detectar cuando se presionó sobre el objeto.
  2. Indicar que hacer cuando se presiona el objeto.
  3. Detectar cuando se suelta el botón del mouse.
  4. Indicar que hacer cuando se suelta el botón del mouse.

Digamos que el objeto tiene el nombre de instancia miObjeto_mc, en otro layer ponga el siguiente código:

//1) Detectar cuando se presionó sobre el objeto.
miObjeto_mc.addEventListener("mouseDown", miObjeto_mc_mouseDown);
//2) Indicar que hacer cuando se presiona el objeto.
function miObjeto_mc_mouseDown(event)
{
     miObjeto_mc.startDrag();
}
//3) Detectar cuando se suelta el botón del mouse.
miObjeto_mc.addEventListener("mouseUp", miObjeto_mc_mouseUp);
//4)Indicar que hacer cuando se suelta el botón del mouse. 
function miObjeto_mc_mouseUp(event)
{
     miObjeto_mc.stopDrag();
}

Antes de proceder asegurese de que ha leído y comprende el concepto de eventos.

Los eventos mouseDown y mouseUp

Estos dos eventos se disparan cuando se aprieta el botón izquierdo del mouse.

Se dispara cuando se aprieta el mouse: "mouseDown"
Se dispara al soltar el botón del mouse (aquí también ocurre el evento click): "mouseUp"

Los métodos startDrag y stopDrag

Estos dos métodos permiten decirle al objeto que inicie y detenga el arrastre de acuerdo a donde se mueve el cursor.

Inicia el arrastre: startDrag( )
Detiene el arrastre: stopDrag( )
Práctica:
Crear una muñeca de papel que se pueda vestir.

¿Cómo hacer un link en Actionscript 3.0?

Cuando se comienza a aprender Actionscript 3.0, lo más básico que se necesita saber es cómo crear un link en un botón.

Ahora bien digamos que tenemos un botón con el nombre de instancia "miBoton", en otro layer vamos a poner el siguiente código:



var url = "http://www.google.com";
var window = "_blank" //Abrirá en una ventana nueva, puede ser tambien _self para que abra en la misma ventana.
//Por cada botón requiere una función diferente.
function miBoton_click(event) 
{
 navigateToURL(new URLRequest(url), window);
}
miBoton.addEventListener("click", miBoton_click);

Nada más necesitará cambiar los contenidos de var url = "http://www.google.com"; para cambiar a donde apunta el botón. Memorice o guarde este código para que sea tan fácil como copiar y pegar. Recuerde cambiar miBoton.addEventListener("click", miBoton_click); de acuerdo al nombre de instancia de su botón.

La explicación sería la siguiente:

miBoton. addEventListener( "click", miBoton_click);
nombre de instancia. empiece a escuchar( "cuando le hacen click", nombre de la funcion a ejecutar);

¿Qué es un evento?

Un evento es un suceso que es detectado por el Flash Player. Existen dos tipos: eventos de usuario y eventos de sistema. Los eventos de usuario son aquellos que son causados por el usuario: hacer click, mover el mouse, apretar una tecla, hablar en el microfono, moverse enfrente de la camara, etc. Los eventos de usuario son los que ocurren dentro de la computadora sin interferencia del usuario: cuando termina de cargar un archivo, cuando empieza a reproducirse un sonido, cuando cambia la fecha, etc.

Vocabulario:

La instancia, ejemplo: miBoton
El método para escuchar cualquier evento: addEventListener
El evento a escuchar: "click"
La función es el código que se ejecuta cuando ocurre el evento. Cualquier función llamada por un evento, SIEMPRE tiene que recibir un event como parámetro: function miBoton_click(event){}
Parámetro: cualquier cosa que se escriba entre los paréntesis de una función.

Por último conocimos como indicarle que haga un pedido de un recurso en internet (en este caso un sitio web externo al .swf):

Ir a otro sitio web: navigateToUrl
Cargar un sitio web con una dirección: new URLRequest("http://www.sitio.com")
En futuros tutoriales exploraremos más a fondo el URLRequest.
Práctica:
Crear un menu que lleve a los siguientes sitios web: Google, Adobe.com, Yahoo, Apple, Facebook

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

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);

SoundMixer.computeSpectrum y el ByteArray

Actualmente estoy investigando como crear visualizaciones de sonidos usando la información de sonido que trae un MP3. Al final resulto ser mas simple de lo que pensaba. Tan solo hay que crear un ByteArray (que es asi como información binaria cruda) y utilizar esos datos para las visualizaciones. Cada vez que se usa el SoundMixer.computeSpectrum(byteArray), lo que hace es cargar el byteArray con 512 valores (los primeros 256 son del canal izquierdo del audio y los otros 256 son del canal derecho), a travez del metodo byteArray.getFloat() obtengo un numero entre -1 y 1. Aplicando eso con el Drawing API se puede lograr un monton de efectos interesantes. Ahora quiero investigar sobre el espectro de cada uno de los tonos (bajos y altos). He obtenido alguna información que puede resultar util:http://blog.trycatchgames.com/?p=9

import flash.media.SoundMixer;
import flash.utils.ByteArray;
var mySoundBytes:ByteArray = new ByteArray();
SoundMixer.computeSpectrum(mySoundBytes);//Saca el espectro de cualquier sonido que este sonando al momento.
for(var i:int=0; i > 512;i++)
{
   trace(mySoundBytes.getFloat());
   //getFloat avanza al siguiente valor
}