Comunidad de diseño web y desarrollo en internet online

Borrando el Listener de un Tween

Citar            
MensajeEscrito el 17 Sep 2009 03:46 pm
Tengo una función que llama a un Tween de esta forma:

Código ActionScript :

function subir():void
{
   for ( var i:int = 0; i <= profundidade; i++ )
   {
      TAXI.addChild( RIGTH.getChildAt( 0 ) );
   }
   var animaTaxi:Tween = new Tween(TAXI,"x",Regular.easeOut,TAXI.x,aPosFin[0],1,true);
   animaTaxi.addEventListener(TweenEvent.MOTION_FINISH, doneTween);
}


Mi intención es que cuando el Tween termine sea llamada otra función, llamada aqui de doneTween

Código ActionScript :

function doneTween (e:Event):void
{
   for ( var i:int = 0; i <= profundidade; i++ )
   {
      LEFT.addChild( TAXI.getChildAt( 0 ) );
   }
   LEFT.x = aPosFin[0];
   animaTaxi.removeEventListener(TweenEvent.MOTION_FINISH, doneTween);
}


El problema es que como animaTaxi quedó definida dentro del escopo de la función subr ella no es reconocida por la doneTween. Intenté definirla afuera como var animaTaxi:Tween; pero no funciona. Dos preguntas

a) Cómo hago para que la función doneTween reconozca una variable definida en la función subir;
b) Es realmente necesário remover el Listener?

Desde ya muchas gracias. Claudio

Por Ishkandar

Claber

303 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 17 Sep 2009 04:35 pm
No creo que haga falta borrar ese listener al final de la función a la que llama cuando se dispara el evento. De todas formas yo diría que dentro de doneTween te puedes referir a animaTaxi como e.target.

Por porba

12 de clabLevel



 

firefox
Citar            
MensajeEscrito el 17 Sep 2009 04:42 pm
el "tween" lo tienes en "e.target" (o en e.currentTarget -siempre me hago un lío-

Código ActionScript :

function doneTween (e:Event):void 
{ 
  //creo una variable que haga referencia al "target"
   var animaTaxi:Tween=e.target as Tween; //<--es necesaria la conversión de cast
   //ahora 
   animaTaxi.removeEventListener(TweenEvent.MOTION_FINISH, doneTween); 
} 

He llamado a la variable igual, pero la puedes nombrar como quieras

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 17 Sep 2009 05:03 pm
No creo que el casting sea necesario. Si fueras a utilizar el Tween para algo dentro de la función doneTween sí sería necesario pero para realizar la llamada a removeEventListener yo creo que no es necesario y funciona perfectamente con e.target sin casting.

Por porba

12 de clabLevel



 

firefox
Citar            
MensajeEscrito el 17 Sep 2009 05:14 pm
Perdón, ni siquiera haría falta el casting si necesitaras utilizar el Tween. No hace falta el casting porque ya es un Tween.

Qué la propiedad target de Event sea de tipo Object permite que pueda almacenar cualquier tipo de objeto, lo que no quiere decir que esos objetos pierdan su clase, o eso creo.

En esa función lo puedes comprobar simplemente poniendo:

Código ActionScript :

if (e.target is Tween) {
  trace("Pues claro que soy un tween que pensabas");
}

Por porba

12 de clabLevel



 

firefox
Citar            
MensajeEscrito el 17 Sep 2009 07:31 pm
Touché, el "target" de un TweenEvent, debería ser un Tween -gracias por la corrección-

Por Eliseo2

710 de clabLevel



 

msie8
Citar            
MensajeEscrito el 17 Sep 2009 08:05 pm
Creo que no captaste exactamente por qué es.

Un manejador de evento es una función que se ejecuta cuando se dispara ese evento. Estas funciones son de la forma:

Código ActionScript :

function manejadorEvento (e:Event) : void {
}


Un manejador de evento lo pueden compartir varios eventos, lo cual en ocasiones puede ser lo deseable (porque varios objetos van a hacer lo mismo en diferentes eventos, porque hay una parte común dentro del código del manejador de evento y otra parte que depende del target, etc...). e.target siempre contendrá el objeto que disparó el evento.

Un ejemplo sencillo en el que vamos a imaginar que tenemos un MovieClip y un Sprite con diferentes eventos pero un manejador de evento compartido:

Código ActionScript :

miClip.addEventListener(MouseEvent.MOUSE_OVER, manejador);
miSprite.addEventListener(KeyboardEvent.KEY_DOWN, manejador);
function manejador (e:Event) : void {
  // comun se ejecuta con los dos eventos
   miClip.x = miClip.x + 1;
   miSprite.x = miSprite.x + 1;

  // codigo dependiente del target
  if (e.target is MovieClip) {
    miClip.y = miClip.y + 1;
  }
  if (e.target is Sprite) {
    miSprite.y = miSprite.y + 1;
  }
}


Como ves se trata de dos eventos que nada tienen que ver uno con otro, uno evento de teclado y el otro evento de ratón, esto es para aclarar que nada tiene que ver con el tipo de evento. Simplemente con el manejador nosotros hacemos lo que deseemos y el e.target siempre contendrá el objeto que disparó el evento, lo cual podemos utilizar para realizar las acciones adecuadas teniendo en cuenta el objeto que disparó el evento. Aquí utilizo la clase del target para actuar en consecuencia pero también podría ser por el nombre del target o teniendo en cuenta la posición x del target o lo que sea que se nos ocurra. Lo que tiene que quedar claro es que con e.target tenemos acceso al objeto que disparó el evento.

Por porba

12 de clabLevel



 

firefox
Citar            
MensajeEscrito el 17 Sep 2009 08:29 pm
Bien, la solución me la dió mi amigo Mauro Fernandez que simplemente desdobló la declaración de la variable haciendo de esta forma:

Código ActionScript :

var animaTaxi:Tween;

function subir():void
{
   for ( var i:int = 0; i <= profundidade; i++ )
   {
      TAXI.addChild( RIGTH.getChildAt( 0 ) );
   }
   animaTaxi = new Tween(TAXI,"x",Regular.easeOut,TAXI.x,aPosFin[0],1,true);
   animaTaxi.addEventListener(TweenEvent.MOTION_FINISH, doneTween);
}

function doneTween (e:Event):void
{
   for ( var i:int = 0; i <= profundidade; i++ )
   {
      LEFT.addChild( TAXI.getChildAt( 0 ) );
   }
   LEFT.x = aPosFin[0];
   animaTaxi.removeEventListener(TweenEvent.MOTION_FINISH, doneTween);
}


De todas formas muchas gracias a todos los que se dispusieron a ayudarme, voy a leer detenidamente los posts sobre "cast" concepto que todavía no tengo muy claro.

Eliseo, tengo un tutorial que explica claramente la diferencia entre target e current.target si querés que te mande escribime a [email protected]

Abrazo grande a todos. Claudio

Por Ishkandar

Claber

303 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 18 Sep 2009 10:54 am

porba escribió:

Creo que no captaste exactamente por qué es.
Un manejador de evento es una función que se ejecuta cuando se dispara ese evento. Estas funciones son de la forma:

Código ActionScript :

function manejadorEvento (e:Event) : void {
}


Efectivamente, de vez en cuando me paso con las conversions de cast. Cuando no es necesario hacerlas en muchos casos. encima la idea de que

Eliseo2 escribió:

el "target" de un TweenEvent, debería ser un Tween

NO es correcta.

e.target es SIEMPRE de la Clase "Objeto"

Así, por el hecho de serlo se puede escribir

Código ActionScript :

e.target.variable=100
e.target.unMetodoCualquiera()


Es por eso que funciona sin conversión de cast. -Como es lógico, si "unMetodoCualquiera" no fuera un método del objeto nos daría un error en tiempo de ejecución-

Es necesaria la conversión de cast SÓLO cuando queremos usarlo como argumento de una función que precise como argumento algo más que un objeto. Así, p.e.

Código ActionScript :

addChild(e.target) //<---daría error porque no se puede añadir un
                   //"Object" al Stage, 

addChild(e.target as MovieClip)
//ó
addChild(e.target as DisplayObject)  //<---sí funcionaría


Aclarar, aunque eso ya lo sabes, que no todas las funciones de eventos reciben como argumento un e:Event, de hecho, si añadimos un evento del tipo MouseEvent.CLICK, aunque podemos recoger dicho evento con una variable Event, estrictamente deberíamos recoger dicho evento con una variable del tipo MouseEvent

Código ActionScript :

function manejadorEvento (e:MouseEvent) : void {
}

Si quisiéramos acceder a las propiedades localX y localY, por ejemplo.

NOTA:Claudio, perdona que haya desvirtuado tu post y gracias por el ofrecimiento, Te mando un email reclamando el tutorial y unas gracias anticipadas

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 18 Sep 2009 01:39 pm
Eliseo no tienes que pedir perdón por nada, por el contrário agradezco mucho que hayamos podido "transitar" otros caminos que permitirán enriquecer tanto mis conocimientos como los de todas las personas que lean estos posts.

Abrazo grande Claudio

Por Ishkandar

Claber

303 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 18 Sep 2009 02:28 pm
Crear un nuevo documento y en el primer fotograma escribir este código:

Código ActionScript :

import fl.transitions.Tween;

var miSprite = new Sprite();
miSprite.x = 50;
miSprite.y = 50;
miSprite.graphics.beginFill(0x000000);
miSprite.graphics.drawRect(0,0,10,10);
miSprite.graphics.endFill();
miSprite.addEventListener(MouseEvent.MOUSE_DOWN, moverloAClip);

var miClip = new MovieClip();
miClip.x = 100;
miClip.y = 100;
miClip.graphics.beginFill(0xFF0000);
miClip.graphics.drawRect(0,0,100,100);
miClip.graphics.endFill();

addChild(miSprite);
addChild(miClip);

function moverloAClip(e:MouseEvent) : void {
   if (e.target is Object) {
      trace("Todos somos objetos y yo no voy a ser menos");
   }
   if (e.target is Sprite) {
      trace("Claro que soy sprite o es que no recuerdas que el listener me lo pusiste a mí");
   }
   if (e.target is SimpleButton) {
      trace("No, no, no, no, que soy sprite");
   }
   // Sin casting
   miClip.addChild(e.target);
   
   if (miClip.getChildAt(0) is Sprite) {
      trace("Pesado, que sí que soy sprite. Nunca he dejado de serlo");
      trace("También soy DisplayObjectContainer, soy InteractiveObject, soy DisplayObject, soy EventDispatcher y soy Object");
      trace("Y el que escribió este código es un humano y es un animal, pero esto último no se lo digas que suena mal");
   }
   
   if (miClip.getChildAt(0) is Tween) {
      trace("Que no que no soy de ninguna otra clase a no ser que sea ascendente mío. ");
   }
}

Por porba

12 de clabLevel



 

firefox
Citar            
MensajeEscrito el 18 Sep 2009 04:51 pm
Amigo Porba voy a aprovechar el ejemplo que diste para hacerte una pregunta. Cuando miSprite es creado, él tiene un posición ( x = 0, y = 0 ) relativa al stage pero posteriormente cuando él es adicionado a miClip el posicionamiento se hace relativo a este último Display Object Container.

Cómo hago para mantener la posición original?

Por Ishkandar

Claber

303 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 18 Sep 2009 05:07 pm
Bueno eso suele ser la idea cuando deseas meter algo en un clip que su posición sea relativa a ese clip.

Pero si quisieras mantenerlo en su sitio tan solo tendrías que restarle a la coordenada x del sprite la coordenada x del clip donde lo metes y a la coordenada y lo mismo.

O sea:

Código ActionScript :

miClip.addChild(miSprite);
miSprite.x = miSprite.x - miClip.x;
miSprite.y = miSprite.y - miClip.y;


y eso lo debería mantener en la misma posición.

Por porba

12 de clabLevel



 

firefox
Citar            
MensajeEscrito el 18 Sep 2009 05:38 pm
Se puede obtener el mismo resultado con globalToLocal();

Por Ishkandar

Claber

303 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 18 Sep 2009 05:39 pm
Se puede obtener el mismo resultado con globalToLocal(); ?

Por Ishkandar

Claber

303 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 18 Sep 2009 07:20 pm
Este sería un ejemplo con la primera solución que funcionará siempre que el sprite se mueva desde el stage y no funcionaría si el sprite está contenido en algún otro displayObject:

Código ActionScript :

var miSprite = new Sprite();
miSprite.x = 50;
miSprite.y = 50;
miSprite.graphics.beginFill(0x000000);
miSprite.graphics.drawRect(0,0,10,10);
miSprite.graphics.endFill();
miSprite.addEventListener(MouseEvent.MOUSE_DOWN, moverloAClip);

var miClip = new MovieClip();
miClip.x = 100;
miClip.y = 100;
miClip.graphics.beginFill(0xFF0000);
miClip.graphics.drawRect(0,0,100,100);
miClip.graphics.endFill();

miClip.addEventListener(MouseEvent.MOUSE_DOWN, moverClip);

addChild(miSprite);
addChild(miClip);

function moverloAClip(e:MouseEvent) : void {
   
   e.target.removeEventListener(MouseEvent.MOUSE_DOWN, moverloAClip);

   miClip.addChild(e.target);
   
   e.target.x = e.target.x - miClip.x;
   e.target.y = e.target.y - miClip.y;
   
}

function moverClip (e:MouseEvent) : void {
   e.target.x = e.target.x + 1;
}


Esto sin embargo te permitiría mover el sprite de un displayobject a otro sin variar su posición con respecto al stage:

Código ActionScript :

var miSprite = new Sprite();
miSprite.x = 20;
miSprite.y = 20;
miSprite.graphics.beginFill(0x000000);
miSprite.graphics.drawRect(0,0,10,10);
miSprite.graphics.endFill();
miSprite.addEventListener(MouseEvent.MOUSE_DOWN, moverloAClip2);

var miClip = new MovieClip();
miClip.x = 10;
miClip.y = 10;
miClip.graphics.beginFill(0x0000FF);
miClip.graphics.drawRect(0,0,50,50);
miClip.graphics.endFill();

var miClip2 = new MovieClip();
miClip2.x = 100;
miClip2.y = 100;
miClip2.graphics.beginFill(0xFF0000);
miClip2.graphics.drawRect(0,0,100,100);
miClip2.graphics.endFill();


miClip.addEventListener(MouseEvent.MOUSE_DOWN, moverClip);
miClip2.addEventListener(MouseEvent.MOUSE_DOWN, moverClip);

addChild(miClip);
miClip.addChild(miSprite);
addChild(miClip2);

function moverloAClip2(e:MouseEvent) : void {
   
   // e.target es el sprite
   e.target.removeEventListener(MouseEvent.MOUSE_DOWN, moverloAClip2);
   
   var antiguasCoordenadas:Point;
   var nuevasCoordenadas:Point;
   
   // Antiguas coordenadas globales
   // Aquí lo que transformas son las coordenadas locales del sprite dentro de miClip
   // a coordenadas globales
   antiguasCoordenadas = e.target.localToGlobal(new Point(e.target.x, e.target.y));

   miClip2.addChild(e.target);

   // Aquí lo que transformas son las coordenadas globales antiguas
   // en coordenadas locales con respecto a miClip2 que es el que contiene
   // el sprite después del addChild anterior
   nuevasCoordenadas = e.target.globalToLocal(antiguasCoordenadas);

   e.target.x = nuevasCoordenadas.x;
   e.target.y = nuevasCoordenadas.y;

}

function moverClip (e:MouseEvent) : void {
   if (e.target is MovieClip) {
      e.target.x = e.target.x + 1;
   }
}


Puedes pinchar en los clips contenedores para moverlos y ver en todo momento a quien pertenece el sprite.

Por porba

12 de clabLevel



 

firefox
Citar            
MensajeEscrito el 21 Sep 2009 08:06 am
Porba, un apunte

Código ActionScript :

miClip.addChild(e.target); 

NO dará error siempre que tengamos DESACTIVADO el modo estricto (es el "compilador" el que da error). Al menos era así con CS3 y con FlashDevelop -no sé si lo cambiaron con CS4-. Efectivamente, en tiempo de ejecución es un Sprite o o que sea.

Por Eliseo2

710 de clabLevel



 

firefox
Citar            
MensajeEscrito el 22 Sep 2009 09:50 am
Yo la verdad que entiendo que tiene sentido lo que dices: en compilación de target lo único que se puede saber es que es un Object y addChild requiere un DisplayObject.

Sin embargo a mí no me da ningún error tanto haciendo el test de la película como publicándola, no encuentro ninguna opción en los menús para hacer una compilación. Uso CS3 y AS3, y pruebo con el código que he puesto arriba. En publish settings del proyecto en AS3 tiene ACTIVADO strict mode.

La única forma que tengo de comprabar errores de flash es hacer un test de la película y los errores siempre son errores en tiempo de ejecución. El código de arriba no contiene ningún error en tiempo de ejecución. Se produciría error en tiempo de ejecución si en algún momento ese e.target no es un DisplayObject ya que no podría usarse en addChild. Pero siempre que e.target contenga un objeto DisplayObject se producirá una conversión forzada al utilizarlo como parámetro de addChild y no se producirá ningún error.

Si tuviera que hacer una conversión explícita obtaría por el código:

Código ActionScript :

miClip.addChild(e.target as DisplayObject);


que valdría para cualquier tipo de DisplayObject (Sprite, MovieClip, SimpleButton...) y podría utilizar el manejador sin cambios para distintos DisplayObjects.

Por porba

12 de clabLevel



 

firefox
Citar            
MensajeEscrito el 22 Sep 2009 11:02 am
Eliseo, te mandé lo que me habías pedido. Recibiste?. Claudio

Por Ishkandar

Claber

303 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 22 Sep 2009 11:12 am
Claudio, sí, lo recibí. Perdona que no te haya dicho nada -no he tenido tiempo de echarle un vistazo-
Porba, ahora mismo no tengo a mano el CS3 (en FlashDevelop, ya te aseguro que da error), pero es que, además, hay tanta literatura al respecto del "strict mode" que casi no lo he dudado en ningún momento que daría error. Si no es así me ocurre como a tí, que no entiendo el motivo (y que casi lo echo de menos :))

Por Eliseo2

710 de clabLevel



 

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.