lunes, 23 de abril de 2007
jueves, 12 de abril de 2007
Proteger los archivos externos
Un problema muy común para los desarrolladores flash es el hecho de evitar que los lamers se descargen sus archivos swf y los decompilen para copiar el codigo, las animaciones, los mp3, o cualquier cosa que puedan aprovechar…
Un truco muy fácil es cambiar la extensión a los archivos externos.
Flash para bien o para mal ignora las extensiones de los archivos, ya que supone que le estamos indicando un tipo de archivo correcto (sea un swf, un flv, un mp3…)
Por lo que si tenemos un swf externo en el que tenemos algún tipo de código que queremos evitar que nos copien, cargado de esta manera:
- loadMovie("peli.swf", 1);
Renombreamos el swf, le ponemos una extensión diferente, y lo cargamos de la misma manera.
- loadMovie("tabla_1_1.gif", 1);
Flash cargará correctamente el swf.
De esta manera cuando el lamer busque en la carpeta del caché del navegador buscando archivos swf o mp3… no los encontrará, ya que solo encontrará archivos gif que se confundiran con el resto de ficheros de caché.
Podemos colocar gran parte del código en la pelicula principal y cargar mediante este sistema unas cuantas funciones o variables que sean imprescindibles para el correcto funcionamiento de la pelicula. Esto seguro que desespera a más de uno antes de descubrir porque no le funciona la pelicula.
Drag and Drop en Action Script 3
Este es un pequeño ejemplo de como hacer un darg&drop de un movieclip en actionscript3.
Crearemos en flash9 un Movieclip al que llamaremos "clip".
En el fotograma añadiremos el siguiente código:
| clip.addEventListener(MouseEvent.MOUSE_DOWN, onMouse_Down); clip.addEventListener(MouseEvent.MOUSE_UP, onMouse_Up); |
Con esto asignaremoslos eventos de pulsar y soltar el mouse sobre el clip a las funciones "onMouse_Down" y "onMouse_Up".
Ahora definiremos estas funciones:
| function onMouse_Down(e:Event):void{ clip.startDrag() } function onMouse_Up(e:Event):void{ clip.stopDrag(); } |
Con esto ya tendríamos el MovieClip "clip" arrastrable.
Este mismo código lo podriamos haber puesto dentro de una clase AS3:
| package{ import flash.display.* import flash.events.*; //———————————— public class Drag extends MovieClip{ public var clip:MovieClip = new MovieClip(); //———————————— public function Drag(queClip){ clip = queClip clip.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); clip.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); } //———————————— private function onMouseDown(e:Event):void{ clip.startDrag() } //———————————— private function onMouseUp(e:Event):void{ clip.stopDrag(); }
} |
Al crear el contructor de la clase deberemos pasarle el MovieClip a arrastar como parámentro:
import Dragvar drag:Drag = new Drag(clip);
Controlar inactividad en una pelicula SWF
Este sencllo código nos puede servir para detectar un tiempo de inactividad por parte del usuario dentro de nuestra pelicula. Para por ejemplo, si el usuario está más de un minuto sin tocar el mouse, la pelicula salte directamente a un fotograma con una animación, y cuando el usuario vuelva a tocar el mouse la pelicula vuelva a su estado normal. Algo como un salvapantallas.
Primero de todo crearemos una pelicula flash con dos fotogramas. En el primero colocaremos un MovieClip que contendrá toda la pelicula, y en el segundo colocaremos otro MovieClip que contendrá la animación de salvapantallas.
En las acciones del primer fotograma colocaremos el código que controlará si hay actividad por parte del usuario, en el momento en el que pase un cierto tiempo en el que no la hay, mandará la pelicula al segundo fotograma.
| var posicionMouse:Number = _xmouse + _ymouse; intervalo = setInterval(this, "controlaPosicion", 2000); stop(); |
La variable posicionMouse guardará el valor de la posición del mouse en pantalla, y crearemos un intervalo que cada 2 segundos controle dicha posición.
| function controlaPosicion():Void { if (posicionMouse != _xmouse + _ymouse) { } } |
Esta función compara el valor de la variable posicionMouse (guardada hace 2 segundos) con el valor actual del mouse, si el valor es diferente con lo quiere decir el el usuario está activo, entonces ejecutaremos las siguientes acciones:
| clearInterval(intervalo2); intervalo2 = setInterval(this, "salvapantallas", 18000); gotoAndStop(1); |
Creamos un segundo intervalo, en este caso de 18 segundos (o el tiempo que queramos para que salte nuestro salvapantallas). Y colocamos un gotoAndStop que mantenga la pelicula en el primer fotograma.
¿Por qué eliminamos la referencia al intervalo antes de crearlo? porque de esta manera reseteamos el intervalo cada vez que ejecutamos la acción. Es decir: si cada 2 segundos comparamos los valores del mouse y son diferentes, reiniciamos el segundo intervalo haciendo que vuelva a empezar la cuenta desde cero con lo que nunca llegará a los 18 segundos y no ejecutará la acción "salvapantallas", En cambio en cuanto los valores del mouse coincidan por que no ha habido movimiento del ratón por parte del usuario este reinicio del intervalo no se ejecutará con lo que este si que llegará a los 18 segundos ejecutando la acción "salvapantallas".
Como última acción dentro de esta función colocaremos fuera del condicional, para que se ejecute siempre cada 2 segundos, una línea de código que nos actualice la variable de la posición del mouse.
| posicionMouse = _xmouse + _ymouse; |
La acción "salvapantallas" lo que hará es enviar la pelicula al segundo fotograma.
| function salvapantallas():Void { gotoAndStop(2); } |
Aun estando en el segundo fotograma el intervalo que comprueba el movimiento del mouse continua ejecutandose cada 2 segundos, con lo que al primer movimiento volverá a colocar la pelicula en el primer fotograma.
Este sería el código completo, que hiría en el primer fotograma:
function controlaPosicion():Void{
if (posicionMouse != _xmouse + _ymouse) {
clearInterval(intervalo2);
intervalo2 = setInterval(this, "salvapantallas", 18000);
gotoAndStop(1);
}
posicionMouse = _xmouse + _ymouse;
}
//———————————-
function salvapantallas():Void
{
gotoAndStop(2);
}
//—————————-
var posicionMouse:Number = _xmouse + _ymouse;
intervalo = setInterval(this, "controlaPosicion", 2000);
stop();
Enlaces de texto en Flash al estilo HTML
En flash podemos colocar textos en formato HTML con enlaces a otras páginas, pero tenemos el problema de que estos links no quedan resaltados en color azul y subrayados como pasa en un típico HTML.
Por ejemplo, este SWF contiene un campo de texto con varios enlaces, pero no se diferencian del resto del texto:
Esto lo podemos solucionar aplicando un poco de CSS al texto HTML.
El código para crear el estilo CSS sería este:
- import TextField.StyleSheet;
- var css:StyleSheet = new StyleSheet();
- css.parseCSS("a{color:#0000FF; text-decoration:underline;}");
Ahora al crear un texto HTML tendremos que aplicarle el CSS, de esta manera aplicamos a todas las etiquetas el color azul y el subrayado:
- texto.htmlText = "Troiae qui primus ab oris Italiam, fato profugus, Laviniaque venit litora, multum ille et terris iactatus et alto vi superum saevae memorem Iunonis ob iram; multa quoque et bello passus, dum conderet urbem, inferretque deos Latio, genus unde Latinum, Albanique patres, atque altae moenia Romae.";
Para añadir el texto al campo de texto utilizaremos esta nueva función de la clase:
- texto.htmlcss("Troiae qui primus ab oris Italiam, fato profugus, Laviniaque venit litora, multum ille et terris iactatus et alto vi superum saevae memorem Iunonis ob iram; multa quoque et bello passus, dum conderet urbem, inferretque deos Latio, genus unde Latinum, Albanique patres, atque altae moenia Romae.");
Sistema de transiciones entre fotos
Esta clase, permite generar de forma fácil un sistema de transiciones de fotografias. Este es un ejemplo:
Su funcionamiento es muy simple. La clase genera dos MovieClips contenedores en los que coloca la fotografía actual y la potografía posterior, y carga también un SWF que contiene la animación de la mascara. Esta mascara la aplica al MovieClip contenedor haciendo así es efecto de transicion de una foto a la otra.
Este sistema nos permite generar las animaciones de transición como archivos SWF externos e independientes, pudiendo tener una libreria de transiciones y eligiendo la que queramos para cada transición de fotos.
Un ejemplo de animación de transición sería este:
La clase:
- import mx.utils.Delegate;
- //
- class img.ImgTransition
- {
- private var ruta:MovieClip;
- private var clip:MovieClip;
- private var foto:String;
- private var foto_up:MovieClip;
- private var foto_down:MovieClip;
- private var mascara:MovieClip;
- private var intervalo:Number;
- private var ejecucion:Boolean;
- //----------------------------
- public function ImgTransition(qRuta:MovieClip, qFoto:String, qX, qY)
- {
- ruta = qRuta;
- clip = ruta.createEmptyMovieClip("ImgTransition", ruta.getNextHighestDepth());
- foto_down = clip.createEmptyMovieClip("foto_down", clip.getNextHighestDepth());
- foto_up = clip.createEmptyMovieClip("foto_up", clip.getNextHighestDepth());
- mascara = clip.createEmptyMovieClip("mascara", clip.getNextHighestDepth());
- foto_up.createEmptyMovieClip("mc", 1);
- foto_down.createEmptyMovieClip("mc", 1);
- mascara.createEmptyMovieClip("mc", 1);
- foto = qFoto;
- loadMovie(qFoto, foto_up.mc);
- loadMovie(qFoto, foto_down.mc);
- clip._x = qX;
- clip._y = qY;
- ejecucion = false;
- //
- }
- //----------------------------
- public function transition(qFoto:String, qMascara:String, qDuracion:Number):Void
- {
- if (!ejecucion)
- {
- if (qFoto != foto)
- {
- foto = qFoto;
- //
- var precarga:MovieClipLoader = newMovieClipLoader();
- var listener:Object = new Object();
- listener.onLoadInit = Delegate.create(this, xnLoadInit1);
- precarga.addListener(listener);
- precarga.loadClip(qFoto, foto_up.mc);
- mascara.swf = qMascara;
- mascara.duracion = qDuracion;
- foto_up._visible = false;
- }
- }
- }
- private function xnLoadInit1()
- {
- var precarga2:MovieClipLoader = new MovieClipLoader();
- var listener2:Object = new Object();
- listener2.onLoadInit = Delegate.create(this, xnLoadInit2);
- precarga2.addListener(listener2);
- precarga2.loadClip(mascara.swf, mascara.mc);
- }
- private function xnLoadInit2()
- {
- foto_up.setMask(mascara);
- foto_up._visible = true;
- intervalo = setInterval(this, "endTransition", mascara.duracion * 1000);
- ejecucion = true;
- }
- //----------------------------
- private function endTransition():Void
- {
- loadMovie(foto, foto_down.mc);
- foto_up.setMask(null);
- unloadMovie(mascara.mc);
- clearInterval(intervalo);
- ejecucion = false;
- }
- //----------------------------
- }
Su uso en el .fla es este:
- import img.ImgTransition;
- var foto:ImgTransition = new ImgTransition(this, "foto1.jpg", 10, 10);
- //
- bot1.onRelease = function()
- {
- foto.transition("foto1.jpg", "mascara1.swf", 5);
- };
- bot2.onRelease = function()
- {
- foto.transition("foto2.jpg", "mascara2.swf", 3);
- };
- bot3.onRelease = function()
- {
- foto.transition("foto3.jpg", "mascara3.swf", 2);
- };
- bot4.onRelease = function()
- {
- foto.transition("foto4.jpg", "mascara4.swf", 3);
- };
- bot5.onRelease = function()
- {
- foto.transition("foto5.jpg", "mascara5.swf", 2);
- };
miércoles, 11 de abril de 2007
Efecto de dibujo de línea con ActionScript -
El primer paso será crear el trazado completo que queremos dibujar:

Luego utilizaremos este trazado como guía para un MovieClip, utilizando como punto inicial y final de la interpolación el punto inicial y final del trazado: Ahora mediante código haremos que este MovieClip mientras se desplaza por la guía vaya redibujando el trazado. Para eso crearemos una clase:
- class redibujaGuia
- {
- }
En el constructor de la clase pasaremos como parámentros la ruta de la instancia de clase y el MovieClip que utilizaremos
- public function redibujaGuia(qRuta:MovieClip, qGlider:MovieClip)
- {
- ruta = qRuta;
- glider = qGlider;
- //glider._visible = false;
- var num:Number = ruta.getNextHighestDepth();
- linea = ruta.createEmptyMovieClip("line"+num, num);
- linea.lineStyle(1, 0x000000, 100);
- }
Tambien creamos un MovieClip vacio donde dibujaremos el trazado, y creamos un lineStyle por defecto.
Crearemos tambien una función para poder editar el estilo del trazado:
- public function lineStyle(qGrosor:Number, qColor:Number, qAlfa:Number):Void
- {
- grosor = qGrosor;
- color = qColor;
- alfa = qAlfa;
- linea.lineStyle(grosor, color, alfa);
- linea.moveTo(glider._x, glider._y);
- }
- public function start():Void
- {
- glider.onEnterFrame = Delegate.create(this, onEnterFrame);
- }
- //---------------------------------
- private function onEnterFrame():Void
- {
- act = {x:glider._x, y:glider._y};
- linea.lineTo(act.x, act.y);
- if (prev && act.x == prev.x && act.y == prev.y)
- {
- delete glider.onEnterFrame;
- } else
- {
- prev = act;
- }
- }
- import mx.utils.Delegate;
- //---------------------------------
- class redibujaGuia
- {
- private var grosor:Number;
- private var color:Number;
- private var alfa:Number;
- private var ruta:MovieClip;
- private var glider:MovieClip;
- private var linea:MovieClip;
- private var act:Object;
- private var prev:Object;
- //---------------------------------
- public function redibujaGuia(qRuta:MovieClip, qGlider:MovieClip)
- {
- ruta = qRuta;
- glider = qGlider;
- //glider._visible = false;
- var num:Number = ruta.getNextHighestDepth();
- linea = ruta.createEmptyMovieClip("line"+num, num);
- linea.lineStyle(1, 0x000000, 100);
- }
- //---------------------------------
- public function lineStyle(qGrosor:Number, qColor:Number, qAlfa:Number):Void
- {
- grosor = qGrosor;
- color = qColor;
- alfa = qAlfa;
- linea.lineStyle(grosor, color, alfa);
- linea.moveTo(glider._x, glider._y);
- }
- //---------------------------------
- public function start():Void
- {
- glider.onEnterFrame = Delegate.create(this, onEnterFrame);
- }
- //---------------------------------
- private function onEnterFrame():Void
- {
- act = {x:glider._x, y:glider._y};
- linea.lineTo(act.x, act.y);
- if (prev && act.x == prev.x && act.y == prev.y)
- {
- delete glider.onEnterFrame;
- } else
- {
- prev = act;
- }
- }
- //---------------------------------
- }
Para utilizarla (a parte del proceso manula de dibujar la guía y colocar el MovieClip) utilizaremos este código en el fotograma donde empieze la interpolación:
- import redibujaGuia;
- var linea1:redibujaGuia = new redibujaGuia(this, glider1);
- linea1.lineStyle(2, 0x000000, 100);
- linea1.start();