Cristalab

Cómo duplicar MovieClips con gráficos en ActionScript 3

Por: Zguillez + 03.01.2008

Escribo este tip a raíz de una pregunta en el foro donde se mostraba un problema a la hora de duplicar MovieClips que contienen gráficos creados con código.

Ya escribí un tip en que mostraba cómo duplicar un MovieClip, en el que se veía que había que para duplicar el clip lo que hay qu hacer es crear otra instancia de la misma clase y aplicarle todas las propiedades del clip original al clip duplicado.

El problema viene cuando la propiedad graphics no puede ser copiada directamente, por lo que no podemos hacer esto:

Código :

duplicado.graphics = target.graphics;


De manera que al duplicar el clip los gráficos que hayan sido creados por código no se visualizaran.

Navegando por Kirupa vi un método de solucionar este problema. Consiste en crear un objeto Proxy que irá guardando un registro de la propiedad graphics del clip original, y se utilizará para asignarla al clip duplicado.

Esta es la clase que utilizaremos como Proxy:

Código :

package com.zguillez.display
{
   import flash.display.Graphics;
   import flash.utils.flash_proxy;
   import flash.utils.Proxy;
   //-----------------------------
   public class GraficoDuplicado extends Proxy
   {
      private var _graphics:Graphics;
      private var historial:Array = new Array();
      //-----------------------------
      public function GraficoDuplicado(graphics:Graphics)
      {
         _graphics = graphics;
      }
      //-----------------------------
      public function get graphics():Graphics
      {
         return _graphics;
      }
      public function set graphics(g:Graphics):void
      {
         _graphics = g;
         copy(this);
      }
      //-----------------------------
      public function copy(graficos:GraficoDuplicado):void
      {
         var hist:Array = graficos.historial;
         historial = hist.slice();
         if (_graphics) {
            var i:int;
            var n:int = hist.length;
            _graphics.clear();
            for (i=0; i<n; i += 2) {
               _graphics[hist[i]].apply(_graphics, hist[i + 1]);
            }
         }
      }
      //-----------------------------
      //-----------------------------
      override flash_proxy function callProperty(metodo:*, ... args):*
      {
         metodo = String(metodo);
         switch (metodo) {
            case "clear" :
               historial.length = 0;
               break;
            default :
               historial.push(metodo, args);
         }
         if (_graphics && metodo in _graphics) {
            return _graphics[metodo].apply(_graphics,args);
         }
      }
      //-----------------------------
   }
}

En la que en el contructor pasaremos la referencia de la propiedad graphics del clip original.

lo importante de esta clase es el método override flash_proxy function callProperty con el que asignaremos los métodos al proxy para que guarde en un Array el historial de graficos del clip original a medida que se van creando, y los asignaremos al clip duplicado a través del método copy();

Creada esta clase deberemos instanciarla dentro de los objetos gráficos que creemos, así que para un clip en el que vayamos a crear gráficos por código que posteriormente queramos duplicar escribiremos esta otra clase:

Código :

package com.zguillez.display
{
   import flash.display.Shape;
   import com.zguillez.display.GraficoDuplicado;
   //-----------------------------
   public class Grafico extends Shape
   {
      private var _graficos:GraficoDuplicado;
      //-----------------------------
      public function Grafico()
      {
         _graficos = new GraficoDuplicado(graphics);
      }
      //-----------------------------
      public function get graficos():GraficoDuplicado
      {
         return _graficos;
      }
      //-----------------------------
   }
}

Únicamente es una clase que extiende de Shape que incluye un objeto de la clase anterior.

Ahora en el documento .FLA escribiremos así tanto el clip original como las sucesivas copias:

Código :

import com.zguillez.display.Grafico;

//original
var grafico1:Grafico = new Grafico();
Object(grafico1.graficos).beginFill(0xFFFFFF);
Object(grafico1.graficos).lineStyle(1, 0);
Object(grafico1.graficos).drawRect(0, 0, 50, 50);
grafico1.x = 10;
grafico1.y = 10;
addChild(grafico1);

//duplicado
var grafico2:Grafico = new Grafico();
grafico2.graficos.copy(grafico1.graficos);
grafico2.x = 100;
grafico2.y = 10;
addChild(grafico2);

Así de fácil miau

Etiquetas actionscript_3

Comentarios | Enviar un comentario
Buena respuesta Zguilles...
Por: M@U
Muy bueno pero me doy cuenta que los Tips de ActionScript 3 vienen sin los *.fla (estaría bueno para la gente que ve esto por primera ves... y... por ahi no saben muy bien que son las clases, se pierden y andan como buitres viendo como conectar la clase).

Eso me paso a mí mmmm pero hace mucho ya Riendo Thumbs up .
Por: (ristalab
te quedó bien Z, felicidades miau
Por: eldervaz
A weno pos yo fui el ke hice la preguntita, lo malo eske ese efecto lo trate de hacerlo desde mi Fla ke se controla por AS2 y ya todo lo tengo en AS2 Triste este script es valido para AS2?

y el amigo M@u tiene razon, yo ya lei varios tutos de AS3 y todavia no me cay el veinte de como cargar las clases Triste

y muchas gracias por tu respuesta

Zguillez
Por: Beyondark_blog

Beyondark_blog :

este script es valido para AS2?

No, este código es para AS3. En AS2 para duplicar MovieClips tienes el metodo duplicateMovieClip(); que te duplica el clip directamente.
De hecho este tip es para solucionar el problema de que AS3 ya no tiene disponible ese método.
Por: Zguillez
Que rollooo el AS3! cada vez más críptico y lioso
Por: waka_blog
Muy bien Zguillez Bien.
Por: Carloz.Yanez
hola..iio entre aca ii nii idea q es jeje..
Por: ale nieto_blog
ristalab, tienes toda la razon, por eso qro voy a otro sitio a buscar ayuda y 2do adobe cada vez hace als cosas mas dificiles a los diseñadores, disculpen pero adobe esta comiendo m.
Por: mdaniel_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.