Cristalab

                 ¿Quieres registrarte?

Asignar código actionscript en clases a fotogramas concretos

Por: Zguillez
9 de Octubre del 2008
6418 de clabLevel
Otros artículos de Zguillez
3,462 visitas

Cuando trabajamos con Flash es probable que montemos la película colocando cada pantalla de la aplicación en un fotograma de la linea de tiempo principal, y que vayamos saltando de fotograma a fotograma para cambiar de pantalla.



Evidentemente cada fotograma tendrá sus gráficos y botones que deberán ejecutar unas funciones. En principio estos códigos deberíamos colocarlos en los fotogramas correspondientes. Quizás para el código no nos interese tener que ir colocándolo fotograma a fotograma sino que queramos trabajarlo a través de clases, y mantener el .fla limpio de código.



Mucha gente al hacer esto se encuentra con el problema que no sabe como escribir y ejecutar funciones a medida vas cambiando de fotograma en la película, o que les salta el típico error de ejecutar las acciones antes de que el fotograma esté disponible.

En este tip mostraré una serie de clases que me sirvieron para hacer esto.

El resultado es que en la clase de la película principal tengo esté código:

Código :

package 
{
   import flash.display.MovieClip;
   import com.zguillez.core.TimelineScript;
   //--------------------------------------------------------------------------------
   public class Main extends MovieClip
   {
      private var _timelineScript:TimelineScript;
      //----------------------------------------------------------------------------
      public function Main()
      {
         _timelineScript = new TimelineScript(this);
         _timelineScript.setFrame( 1, new Frame1(this) );
         _timelineScript.setFrame( 2, new Frame2(this) );
         _timelineScript.setFrame( 3, new Frame3(this) );
         /* etc.. */
         stop();
      }
      //----------------------------------------------------------------------------
   }
}


Como se ve, hay una clase que le llamo TimelineScript que me controla que código hay en cada fotograma, y a la que se le agragan a través de la función setFrame() una serie de clases (Frame1, Frame2, Frame3, etc..) que son las clases que contienen el código para cada fotograma independientemente.

Un ejemplo de clase para manejar un fotograma podría ser este:

Código :

package 
{
   import flash.display.MovieClip;
   import flash.events.MouseEvent;
   import com.zguillez.core.FrameScript;
   //--------------------------------------------------------------------------------
   public class Frame1 extends FrameScript
   {
      //----------------------------------------------------------------------------
      public function Frame1(ruta:MovieClip)
      {
         super(ruta);
      }
      //----------------------------------------------------------------------------
      override protected function actions():void
      {
         var boton:MovieClip = _ruta.getChildByName("bot1") as MovieClip;
         boton.buttonMode = true;
         boton.addEventListener(MouseEvent.CLICK, function()
         {
            gotoFrame(2)
         });
         /* resto del código para este fotograma */
      }
      //----------------------------------------------------------------------------
   }
}


El código para este fotograma lo colocaremos dentro de la función actions(). En este caso únicamente hacemos que un clip llamado "bot1" nos salte la película hasta el fotograma 2. En principio tendríamos una clase como esta para cada fotograma.

Hay que fijarse que esta clase extiende de otra clase llamada FrameScript. Esta clase contiene métodos comunes para todas las clases de fotogramas como la clase actions(), que deberemos sobreescribir desde las clases concretas, y la función pública gotoFrame() que es la que nos cambia de fotograma y que deberemos utilizar en lugar de un gotoAndStop().

Tanto la clase FrameScript como la TimelineScript las tendremos guardadas dentro de nuestro package de clases para reutilizarlas en diferentes proyectos ya que no necesitaremos editarlas para ningún proyecto concreto.

Aquí las vemos:

Código :

package com.zguillez.core
{
   import flash.display.MovieClip;
   import flash.events.Event;
   import com.zguillez.core.TimelineScript;
   //--------------------------------------------------------------------------------
   public class FrameScript
   {
      protected var _ruta:MovieClip;
      private var _timelineScript:TimelineScript;
      //----------------------------------------------------------------------------
      public function FrameScript(ruta:MovieClip)
      {
         _ruta = ruta;
      }
      //----------------------------------------------------------------------------
      internal function set timelineScript(t:TimelineScript):void
      {
         _timelineScript = t;
      }
      //----------------------------------------------------------------------------
      public final function init():void
      {
         _ruta.stage.addEventListener(Event.ENTER_FRAME, iniActions);
      }
      //----------------------------------------------------------------------------
      private final function iniActions(e:Event):void
      {
         if (_ruta.numChildren > 0)
         {
            if (_ruta.getChildAt(0) != null)
            {
               _ruta.stage.removeEventListener(Event.ENTER_FRAME, iniActions);
               actions();
            }
         }
         else
         {   
            _ruta.stage.removeEventListener(Event.ENTER_FRAME, iniActions);         
            actions();
         }
      }
      //----------------------------------------------------------------------------
      protected function actions():void { /* override */ }
      //----------------------------------------------------------------------------
      protected final function gotoFrame(f:uint):void
      {
         _ruta.gotoAndStop(f);
         _timelineScript.update();
      }
      //----------------------------------------------------------------------------
   }
}


Como vemos esta clase, que es de la que extienden todas las clases concretas de fotogramas, contiene una referencia de la ruta en la que están los gráficos y una referencia de la clase TimelineScript que es la que contiene todas las clases concretas de fotogramas.

Esta clase contiene un método actions() que esta vacío ya que este método será sustituido a través de un override desde las clases concretas de fotograma, ya que evidentemente cada clase tendrá sus propias funciones a ejecutar.

También tiene el método gotoFrame() que como he dicho antes es el que nos hace saltar de fotograma. Vemos que esta función contiene el gotoAndStop() y además ejecuta el método update() de la clase TimelineScript.

Las acciones que incluyamos en la función actions() han de ser inicializadas desde el método init(), más concretamente desde el método iniActions().

Como podemos ver hemos utilizado un ENTER_FRAME para realizar la llamada a la función actions(). Esto es debido a que cuando cambiamos de fotograma y ejecutamos un código, este código se ejecuta antes de que los elementos gráficos de dicho fotograma estén disponibles, con lo que cualquier referencia a ellos desde el código (como por ejemplo el getChildByName("bot1")) nos daría el error de que no existen. Con el ENTER_FRAME generemos un bucle de llamadas hasta que reconoce los elementos gráficos del fotograma, en ese momento ejecuta la acción que les asigna el código.

Vista esta clase, nos queda la clase TimelineScript:

Código :

package com.zguillez.core
{
   import flash.display.MovieClip;
   import com.zguillez.core.FrameScript;
   //--------------------------------------------------------------------------------
   public class TimelineScript
   {
      private var _ruta:MovieClip;
      private var _frameScript:Array = new Array();
      //----------------------------------------------------------------------------
      public function TimelineScript(ruta:MovieClip)
      {
         _ruta = ruta;
         initArray();
      }
      //----------------------------------------------------------------------------
      private function initArray():void
      {
         for (var i:uint = 0; i <= _ruta.totalFrames; i++)
         {
            _frameScript.push(void);
         }
      }
      //----------------------------------------------------------------------------
      public function setFrame(n:uint, s:FrameScript):void
      {
         s.timelineScript = this;
         _frameScript[n] = s;
         if (n == _ruta.currentFrame)
         {
            _frameScript[n].init();
         }
      }
      //----------------------------------------------------------------------------
      public function update():void
      {
         _frameScript[_ruta.currentFrame].init();
      }
      //----------------------------------------------------------------------------
   }
}


Esta clase contiene un Array al que le introducimos tantos elementos como fotogramas tiene la línea de tiempo principal.

A este Array le añadiremos las clases de código concreto para cada fotograma en la posición que les corresponda, a través del método setFrame(), tal como vimos en la clase de la película.

Esta clase también contiene una función update() que lo que hace es ejecutar la función init() de la clase que corresponda al fotograma actual y de esta manera ejecutar las funciones correspondientes para dicho fotograma, y como hemos visto anteriormente esta función update() se ejecuta cada vez que cambiamos de fotograma en la película.

Espero que se entienda el proceso y les sea útil ;)


Artículos Relacionados


Etiquetas flash actionscript_3

Comentarios | Enviar un comentario
Yo personalmente no soy muy amigo de los fotogramas, prefiero tenerlo todo en la biblioteca bien ordenado, pero para cuando te pasan las cosas "así" es una buena solución ;)

Un saludo!
Por: Elecash
si, se ve bien, aunque yo prefiero asociar Class a los MC, sin embargo veo a esta solución viable (Y) bien Z
Por: eldervaz
Hey, se ve interesante, aun no me pasa así pero la forma como te has trabajado el código esta muy buena. Lo probaré ;) .
Por: Otaku RzO

eldervaz-blog :

si, se ve bien, aunque yo prefiero asociar Class a los MC, sin embargo veo a esta solución viable (Y) bien Z

Si está claro. Este es un recuro para cuando te llega un .fla que lo han montado así y lo que tienes que hacer es meterle el código, incluso puede que te lo pasen que ya le hayan añadido parte de código en los fotogramas. De esta manera evitas tener que andar modificando el .fla para meter todo el contenido de los fotogramas en clips y también evitar tener que andar programando en los fotogramas, dejando el .fla tal cual te lo enviaron.
Por: Zguillez
gran tip Zguillez, aun no lo he probado pero lo veo perfecto para cuando te pasan chapuzas algunos diseñadores ;)
Por: roger-blog
Muy buen tip, no solo para cuando llega un flash de otra persona, sino cuando tengo que trabajar con proyectos míos antiguos en que las chapuzas las realizaba yo. XD
Por: elchininet
Excelente tip Z, hasta ahora no me he visto en la necesidad de utilizarlo, pero lo tendré en cuenta pues por lo que comentan es muy útil para los casos de mezclar diseñadores y programadores, jejeje. Saludos!!!
Por: Tata
Excelente tip, tendré que cambiar muchos archivos flash..!
Por: torrealbaruben
gracias por el tip
me ayudo muxooooo
gracias
Por: andrea rivas-blog
pues
Por: axel-blog
Deja un comentario
IMPORTANTE

Recuerda ser respetuoso, no insultes a otras personas, ni uses palabrotas, hay una persona al otro lado de la pantalla.

Habla bien, NO ESCRIBAS EN MAYUSCULA TODO, no escribas como en un SMS, evita cosas como "ke", "x q" y demás abreviaciones.

Aquí funcionan las etiquetas de los foros, puedes usar [b] para negrita, [img] para las imágenes, [url] para los enlaces, etc.

Si tienes preguntas técnicas, envíalas mejor al foro.