Comunidad de diseño web y desarrollo en internet

El uso correcto de Actionscript 2.0

Desde que salió Flash CS y ActionScript 3.0 que han habido numerosas quejas de gente que opina que Actionscript 3 es muy diferente a Actionscript 2 y que no entiende por que Adobe ha realizado este cambio tan brusco que se está dejando fuera (según ellos) a mucha gente.

Se han oido muchas opiniones de gente que dice que continuará trabajando en Actionscript 2 por que ven muy complejo Actionscript 3. Freddie hace poco escribió un articulo sobre esta cuestión. Sobre que Actionscript 2 aún tiene mercado y que no es necesario el cambio a Actionscript 3. Es cierto que aun hay tiempo para hacer esta transición pero la pregunta es:

¿Realmente la transición se está haciendo de Actionscript 2 a Actionscript 3? o en realidad se está pretendiendo hacer de Actionscript 1 a Actionscript 3.

El problema es que NO se sabe programar correctamente Actionscript 2. Mucha gente cree saber programar en Actionscript 2 únicamente por utilizar MovieClipLoader o cualquier otra clase introducida para FlashPlayer 7, o simplemente por utilizar Flash 8 y seleccionar "Publicar para Actionscript 2.0" al crear la película. Pero en realidad siguen programando al estilo Actionscript 1.

Actionscript 2.0 lo introdujo Flash Mx 2004 hace más de tres años. Freddie escribió un tutorial mostrando las novedades que traía. Si nos fijamos en la última veremos que dice que Actionscript 2.0 introduce la programación orientada a objetos, y ese es el punto clave.

Flash Mx 2004 y Flash 8 permitieron combinar código de Actionscript 1 junto a código de Actionscript 2 haciendo que fuese más leve el paso de un lenguaje a otro. Permitiendo que gente que no quisiese aprender a programar orientado a objetos pudiese seguir programar como antes aprovechando las funciones que traía la versión 2. Pero esto a llevado al error de mucha gente que cree saber programar en Actionscript 2 cuando no es cierto, o por lo menos no saben hacerlo correctamente.

Hace unos días penHolder escribió un Tip y me pidió mi opinión. Le dije de debía escribirlo con programación orientada a objetos.

Antes de seguir he de decir que NO estoy criticando a penHoder ni diciendo que sea mal programador, su código es correcto y funciona perfectamente, pero es el último tip de AS2 y es un ejemplo que muestra claramente a lo que me refiero (sorry penHolder)

El ejemplo al que me refiero es este, y el código que utiliza es este:

Código :

this.createEmptyMovieClip("botonera", this.getNextHighestDepth());
var labels:Array = Array("home", "about", "services", "contact");
with (botonera) {
    this._x = 50;
    for (i = 1; i <= labels.length; i++) {
        var modelButton:MovieClip = this.attachMovie("boton", "boton" + i, this.getNextHighestDepth());
        modelButton._x = 0;
        modelButton._y = ((i * 0) + this._height) + 5;
         modelButton.t.text = labels[i - 1];
        modelButton.onEnterFrame = function()
        {
            this._alpha += (this.a - this._alpha) / this.v;
            if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
                this.a = 50;
                this.v = 5;
            } else {
                this.a = 100;
                this.v = 10;
            }
        };
        modelButton.onMouseDown = function()
        {
            if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
                if (this._name == "boton1") {
                    trace("welcome home");
                }
                if (this._name == "boton2") {
                    trace("about us");
                }
                if (this._name == "boton3") {
                    trace("our services");
                }
                if (this._name == "boton4") {
                    trace("contact us");
                }
            }
        };
    }
}

Creado en Flash 8 y publicado para Actionscript 2, siendo este el resultado:

Ejemplo publicado para AS2

El ejemplo funciona perfectamente, Pero ¿Realmente esto es un ejemplo de código creado para Actionscript 2?

Hagamos una prueba:


Eliminemos del código la asignación de tipo de las variables. Osea donde pone var labels:Array dejaremos var labels y donde pone var modelButton:MovieClip dejaremos var modelButton, quedando así el código:

Código :

this.createEmptyMovieClip("botonera", this.getNextHighestDepth());
var labels = Array("home", "about", "services", "contact");
with (botonera) {
    this._x = 50;
    for (i = 1; i <= labels.length; i++) {
        var modelButton = this.attachMovie("boton", "boton" + i, this.getNextHighestDepth());
        modelButton._x = 0;
        modelButton._y = ((i * 0) + this._height) + 5;
        modelButton.t.text = labels[i - 1];
        modelButton.onEnterFrame = function()
        {
            this._alpha += (this.a - this._alpha) / this.v;
            if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
                this.a = 50;
                this.v = 5;
            } else {
                this.a = 100;
                this.v = 10;
            }
        };
        modelButton.onMouseDown = function()
        {
            if (this.hitTest(_root._xmouse, _root._ymouse, true)) {
                if (this._name == "boton1") {
                    trace("welcome home");
                }
                if (this._name == "boton2") {
                    trace("about us");
                }
                if (this._name == "boton3") {
                    trace("our services");
                }
                if (this._name == "boton4") {
                    trace("contact us");
                }
            }
        };
    }
}

En opciones de publicación seleccionemos FlashPlayer 7 y Actionscrip 1.



Comprobemos el resultado:

Ejemplo publicado para AS1

Vayamos más lejos. Eliminemos el método getNextHighestDepth() y dejemos un valor fijo, por ejemplo 1. Ahora publiquemos la pelicula para FlashPlayer 6:

Ejemplo publicado para AS1 y FlashPlayer 6 desde Flash MX

Nota: Para esta última publicación he utilizado Macromedia Flash MX. Versión de Flash que salió al mercado a principios del 2002, más de un año y medio antes de que apareciese Actionscript 2...

Cómo vemos el resultado es el mismo. Es decir, este ejemplo es 99.8% código Actionscript 1.

Entonces... ¿Podemos considerar el código como Actionscript 2 únicamente por añadir el tipo de datos a dos Arrays? Evidentemente NO. Podremos utilizar una o varias funciones propias de Actionscript 2 pero seguiremos programando en Actionscript 1.

Cómo he dicho antes Actionscript 2 introduce la programación orientada a objetos y esa es la única manera de programar correctamente Actionscript 2.

Veamos el ejemplo escrito con programación orientada a objetos


Tampoco me voy a extender mucho en explicar este código, solo diré que utilizaremos dos objetos, uno que será la botonera que a su vez creará los objetos de los botones necesarios. Así que tendremos dos clases:
Botonera.as

Código :

class Botonera
{
   private var _ruta:MovieClip;
   private var _clip:MovieClip;
   private var _vinculo:String;
   private var _botones:Array = new Array();
   private var _labels:Array = new Array();
   private var _acciones:Function;
   private var _x:Number;
   private var _y:Number;
   private var _distanciaY:Number;
   public function Botonera(ruta:MovieClip, vinculo:String, labels:Array, acciones:Function, x:Number, y:Number, distanciaY:Number)
   {
      _x = x;
      _y = y;
      _distanciaY = distanciaY;
      _ruta = ruta;
      _vinculo = vinculo;
      _labels = labels;
      _acciones = acciones;
      creaBotonera();
   }
   private function creaBotonera()
   {
      _clip = _ruta.createEmptyMovieClip("botonera", _ruta.getNextHighestDepth());
      _clip._x = _x;
      _clip._y = _y;
      var total = _labels.length;
      for (var i:Number = 1; i <= total; i++) {
         creaBoton(_labels[i - 1],i);
      }
   }
   private function creaBoton(label:String, id:Number):Void
   {
      var boton:Boton = new Boton(_clip, _vinculo, label, _acciones, _distanciaY, id);
      _botones.push(boton);
   }
}

Boton.as

Código :

import mx.transitions.Tween;
import mx.transitions.easing.*;
import mx.utils.Delegate;
//
class Boton
{
   private var _ruta:MovieClip;
   private var _clip:MovieClip;
   private var _vinculo:String;
   private var _label:String;
   private var _accion:Function;
   private var _distanciaY:Number;
   private var _id:Number;

   public function Boton(ruta:MovieClip, vinculo:String, label:String, accion:Function, distanciaY:Number, id:Number)
   {
      _ruta = ruta;
      _vinculo = vinculo;
      _label = label;
      _accion = accion;
      _distanciaY = distanciaY;
      _id = id;
      creaBoton();
   }
   private function creaBoton():Void
   {
      _clip = _ruta.attachMovie(_vinculo, _vinculo + _id, _ruta.getNextHighestDepth());
      _clip.t.text = _label;
      _clip._x = 0;
      _clip._y = (_id - 1) * (_clip._height + _distanciaY);
      _clip.boton = _id;
      _clip.accion = _accion;
      _clip.onRelease = Delegate.create(this, mouse_down);
      _clip.onRollOver = Delegate.create(this, mouse_over);
      _clip.onRollOut = Delegate.create(this, mouse_out);
   }
   private function mouse_down():Void
   {
      _accion(this._id);
   }
   private function mouse_over():Void
   {
      var alfa:Tween = new Tween(_clip, "_alpha", Regular.easeIn, 100, 50, 5, false);
   }
   private function mouse_out():Void
   {
      var alfa:Tween = new Tween(_clip, "_alpha", Regular.easeIn, 50, 100, 5, false);
   }
}

Y en el .fla tendremos esto:

Código :

var labels:Array = new Array("home", "about", "services", "contact");
var botonera:Botonera = new Botonera(this, "Boton", labels, acciones, 50, 20, 5);

function acciones(boton)
{
   if (boton == 1) {
      trace("welcome home");
   }
   if (boton == 2) {
      trace("about us");
   }
   if (boton == 3) {
      trace("our services");
   }
   if (boton == 4) {
      trace("contact us");
   }
}

Resultado:

AS2 con POO


Evidentemente este código ahora es imposible publicarlo desde Actionscript 1, es un código orientado a objetos con lo que es un código 100% Actionscript 2.

Ahora pasemos el ejemplo a Actionscript 3


Seguiremos teniendo dos objetos, botonera y botón.

Botonera.as

Código :

package 
{
   import flash.display.Sprite;
   import flash.utils.getDefinitionByName;
   //
   public class Botonera extends Sprite
   {
      private var _ruta:Sprite;
      private var _clip:Sprite;
      private var _vinculo:String;
      private var _botones:Array = new Array();
      private var _labels:Array = new Array();
      private var _acciones:Function;
      private var _x:Number;
      private var _y:Number;
      private var _distanciaY:Number;
      public function Botonera(ruta:Sprite, vinculo:String, labels:Array, acciones:Function, x:Number, y:Number, distanciaY:Number)
      {
         _x = x;
         _y = y;
         _distanciaY = distanciaY;
         _ruta = ruta;
         _vinculo = vinculo;
         _labels = labels;
         _acciones = acciones;
         creaBotonera();
      }
      private function creaBotonera():void
      {
         _clip = new Sprite();
         _clip.x = _x;
         _clip.y = _y;
         var total:uint = _labels.length;
         for (var i:uint = 1; i <= total; i++) {
            creaBoton(_labels[i - 1],i);
         }
         addChild(_clip);
      }
      private function creaBoton(label:String, id:Number):void
      {
         var ClassReference:Class = getDefinitionByName(_vinculo) as Class;
         var boton:Sprite = new ClassReference(_clip, label, _acciones, _distanciaY, id) as Sprite
         _clip.addChild(boton);
      }
   }
}

Boton.as

Código :

package 
{
   import flash.display.Sprite;
   import flash.text.TextField;
   import flash.events.MouseEvent;
   import fl.transitions.*;
   import fl.transitions.easing.*;
   //
   public class Boton extends Sprite
   {
      private var _ruta:Sprite;
      private var _clip:Sprite;
      private var _label:String;
      private var _accion:Function;
      private var _distanciaY:uint;
      private var _id:uint;
      public function Boton(ruta:Sprite, label:String, accion:Function, distanciaY:uint, id:uint)
      {
         _ruta = ruta;
         _label = label;
         _accion = accion;
         _distanciaY = distanciaY;
         _id = id;
         creaBoton();
      }
      private function creaBoton()
      {
         var texto = getChildByName("t");
         texto.text = _label;
         x = 0;
         y = (_id - 1) * (height + _distanciaY);
         addEventListener(MouseEvent.MOUSE_DOWN, mouse_down);
         addEventListener(MouseEvent.ROLL_OVER, mouse_over);
         addEventListener(MouseEvent.ROLL_OUT, mouse_out);
      }
      private function mouse_down(e:MouseEvent):void
      {
         _accion(this._id);
      }
      private function mouse_over(e:MouseEvent):void
      {
         var alfa:Tween = new Tween(this, "alpha", Regular.easeIn, 1, 0.5, 5, false);
      }
      private function mouse_out(e:MouseEvent):void
      {
         var alfa:Tween = new Tween(this, "alpha", Regular.easeIn, 0.5, 1, 5, false);
      }
   }
}

Y en el .fla:

Código :

var labels:Array = new Array("home", "about", "services", "contact");
var botonera:Botonera = new Botonera(this, "Boton", labels, acciones, 50, 20, 5);
addChild(botonera);

function acciones(boton)
{
   if (boton == 1) {
      trace("welcome home");
   }
   if (boton == 2) {
      trace("about us");
   }
   if (boton == 3) {
      trace("our services");
   }
   if (boton == 4) {
      trace("contact us");
   }
}


Ejemplo en Actionscript 3


Evidentemente Actionscript 3 introduce cambios respecto a Actionscript 2, elimina funciones e introduce otras. No utilizaremos attachMovie utilizaremos addChild, no utilizaremos métodos en clip, utilizaremos listeners. etc... Pero los cambios son MÍNIMOS. La base sigue siendo la misma, una programación orientada a objetos.

Conclusión:


Únicamente comparen los códigos... ¿Realmente creemos que ha cambiado tanto Actionscript 3 respecto a Actionscript 2? o es que en realidad no sabemos programar bien Actionscript 2 y aun estamos con Actionscript 1...

¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.

Publica tu comentario

o puedes...

¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate