Comunidad de diseño web y desarrollo en internet online

Problema con drag & drop y Tween

Citar            
MensajeEscrito el 28 Oct 2009 04:53 pm
Hola a todos!!!

Estoy haciendo un pequeño menu que se compone de diferentes fichas las cuales se pueden arrastrar y colocar al gusto.
Para darle un efecto de suavidad al arrastre uso TweenLite.
No me acaba de funcionar bien, el problema esta cuando hago MouseUp fuera del clip....

alguien sabe como mejorar este comportamineto???

Ahi va la clase que uso:

Código ActionScript :

package {
   import flash.display.MovieClip;
   import flash.events.*;
                import gs.TweenLite; 
   import gs.easing.*
   import flash.filters.DropShadowFilter

   public class Ficha extends MovieClip {

      //constructor
      public function Ficha() {
         this.buttonMode =true
         this.addEventListener(MouseEvent.MOUSE_DOWN,comienzaDrag);
         this.addEventListener(MouseEvent.MOUSE_UP,finDrag);
      }
      
      function comienzaDrag(e:MouseEvent):void {
         //la traemos al frente
         var arriba:int = e.target.parent.numChildren - 1;
         e.target.parent.setChildIndex(e.target, arriba);
         
         //Le aplicamos un filtro de sombra (distancia, angulo, color, alpha, blurX, blurY)
         e.target.filters=[new DropShadowFilter(5,45,0x000000,0.5,15,15)];                  
         e.target.addEventListener(MouseEvent.MOUSE_MOVE, mover); 
      }
      
      function finDrag(e:MouseEvent):void {
         e.target.filters=null;
         e.target.removeEventListener(MouseEvent.MOUSE_MOVE, mover); 
      }      
      
      function mover(e:MouseEvent):void {
         TweenLite.to (this, 1, {x: this.parent.mouseX, y: this.parent.mouseY, ease:Cubic.easeOut}); 
      }
   }
}




Luego en el fla tengo un MC asociado a esta clase que instancio de la forma habitual:

Código ActionScript :

import Ficha;

var ficha:Ficha = new Ficha();
ficha.x = 200
ficha.y = 200
addChild(ficha);



Llevo rato dandole vueltas y no consigo hacerlo funcionar bien, a ver si me podeis ayudar :-(
Gracias de antemano

Por Manolito_BCN

25 de clabLevel



 

msie7
Citar            
MensajeEscrito el 28 Oct 2009 04:56 pm
Has probado de asignar el evento de mouseup al stage?

Es decir, asigna el evento mouseup al clip y al stage, llamando a la misma función.

Por ur!

256 de clabLevel



 

Barcelona

chrome
Citar            
MensajeEscrito el 28 Oct 2009 05:06 pm

ur! escribió:

Has probado de asignar el evento de mouseup al stage?

Es decir, asigna el evento mouseup al clip y al stage, llamando a la misma función.


Lo acabo de probar poniendo:

Código ActionScript :


public function Ficha() {
   this.buttonMode =true
   this.addEventListener(MouseEvent.MOUSE_DOWN,comienzaDrag);
   this.addEventListener(MouseEvent.MOUSE_UP,finDrag);
         
   stage.addEventListener(MouseEvent.MOUSE_UP,finDrag);
}



Pero me retorna un error :

TypeError: Error #1009: No se puede acceder a una propiedad o a un método de una referencia a un objeto nulo.


:(

Por Manolito_BCN

25 de clabLevel



 

msie7
Citar            
MensajeEscrito el 28 Oct 2009 05:09 pm
Este error supongo que viene porqué intentas acceder al stage antes de tiempo, es decir, antes que Ficha este instanciado en el stage.

Existe el evento addedtostage, echale un ojo.

Por ur!

256 de clabLevel



 

Barcelona

chrome
Citar            
MensajeEscrito el 28 Oct 2009 05:28 pm

ur! escribió:

Este error supongo que viene porqué intentas acceder al stage antes de tiempo, es decir, antes que Ficha este instanciado en el stage.

Existe el evento addedtostage, echale un ojo.


Lo primero...gracias por las respuestas, me estan dando pistas ;-). Lo segundo...soy novato en AS 3.

He modificado el codigo de la siguiente manera pero sigue sin ir bien:

Código ActionScript :

public function Ficha() {         
         this.addEventListener(Event.ADDED_TO_STAGE, ini);
      }
      
      function ini(e:Event):void {
         this.buttonMode =true
         
         this.addEventListener(MouseEvent.MOUSE_DOWN,comienzaDrag);
         this.addEventListener(MouseEvent.MOUSE_UP,finDrag);
         stage.addEventListener(MouseEvent.MOUSE_UP,finDrag);
      }



No se si uso bien el ADDED_TO_STAGE :-(

Por Manolito_BCN

25 de clabLevel



 

msie7
Citar            
MensajeEscrito el 29 Oct 2009 09:41 am
:-( sigue sin funcionar bien :twisted:

alguna ayuda por favor? sabeis de algun codigo de ejemplo sobre el tema? he mirado por ahi y no he encontrado nada

Gracias!!!

Por Manolito_BCN

25 de clabLevel



 

msie7
Citar            
MensajeEscrito el 29 Oct 2009 05:05 pm
Dejame comprender bien tu problema...tu drag & drop te funciona bien y tu efecto de suavidad tmb?? el problema es al detectar el MouseUp fuera de tu clip que se esta arrastrando no??


Prueba mandandole como parametro el stage o en todo caso el parent.

Código ActionScript :

public function Ficha(padre:DisplayObject) {          
         this.buttonMode =true  
         this.addEventListener(MouseEvent.MOUSE_DOWN,comienzaDrag); 
         this.addEventListener(MouseEvent.MOUSE_UP,finDrag); 

         padre.addEventListener(MouseEvent.MOUSE_UP,finDrag);  
      } 
       


De modo que al crear una ficha sera de esta forma.

Código ActionScript :

//Mandando el stage como parametro (ya que añadiras ficha al stage)
var ficha:Ficha = new Ficha(stage); 
ficha.x = 200 
ficha.y = 200 
addChild(ficha); 

//Tienes la ventaja de mandar algun otro clip contenedor como parametro
//por si quisieras tener tus fichas almacenadas en un clip en especifico
var ficha:Ficha = new Ficha(Mi_clip);//Mi_clip es un moviclip previamente creado 
ficha.x = 200 
ficha.y = 200 
Mi_clip.addChild(ficha); 

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 29 Oct 2009 06:03 pm

Angel Roberto escribió:

Dejame comprender bien tu problema...tu drag & drop te funciona bien y tu efecto de suavidad tmb?? el problema es al detectar el MouseUp fuera de tu clip que se esta arrastrando no??


Prueba mandandole como parametro el stage o en todo caso el parent.

Código ActionScript :

public function Ficha(padre:DisplayObject) {          
         this.buttonMode =true  
         this.addEventListener(MouseEvent.MOUSE_DOWN,comienzaDrag); 
         this.addEventListener(MouseEvent.MOUSE_UP,finDrag); 

         padre.addEventListener(MouseEvent.MOUSE_UP,finDrag);  
      } 
       


De modo que al crear una ficha sera de esta forma.

Código ActionScript :

//Mandando el stage como parametro (ya que añadiras ficha al stage)
var ficha:Ficha = new Ficha(stage); 
ficha.x = 200 
ficha.y = 200 
addChild(ficha); 

//Tienes la ventaja de mandar algun otro clip contenedor como parametro
//por si quisieras tener tus fichas almacenadas en un clip en especifico
var ficha:Ficha = new Ficha(Mi_clip);//Mi_clip es un moviclip previamente creado 
ficha.x = 200 
ficha.y = 200 
Mi_clip.addChild(ficha); 



Gracias por la respuesta, he seguido tus consejos pero el problema persiste NO SE QUE ESTA MAL.
Si haces Up fuera del mc, luego al pasar por encima de este es como si se quedara enganchado :shock:

Vuelvo a pasar la clase completa, probarlo y vereis a lo que me refireo:


Código ActionScript :


package {

   import flash.display.MovieClip;
   import flash.display.DisplayObject;
   import flash.text.TextField;
   import flash.events.*;
   import gs.TweenLite;
   import gs.easing.*;
   import flash.filters.DropShadowFilter;

   public class Ficha extends MovieClip {

      //constructor
      public function Ficha(padre:DisplayObject) {
         this.addEventListener(MouseEvent.MOUSE_DOWN,comienzaDrag);
         this.addEventListener(MouseEvent.MOUSE_UP,finDrag);
         padre.addEventListener(MouseEvent.MOUSE_UP,finDrag);
      }
      
      function comienzaDrag(e:MouseEvent):void {
         //la traemos al frente
         var arriba:int=this.parent.numChildren - 1;
         this.parent.setChildIndex(this,arriba);

         //Le aplicamos un filtro de sombra (distancia, angulo, color, alpha, blurX, blurY)
         e.target.parent.filters=[new DropShadowFilter(5,45,0x000000,0.5,15,15)];
         //lo movemos
         e.target.addEventListener(MouseEvent.MOUSE_MOVE,mover);
      }
      function finDrag(e:MouseEvent):void {
         //le quitamos el movimiento
         e.target.removeEventListener(MouseEvent.MOUSE_MOVE,mover);
      }
      function mover(e:MouseEvent):void {         
         TweenLite.to(this,1, :this.parent.mouseX,y:this.parent.mouseY,ease:Cubic.easeOut});
      }
   }
}

Por Manolito_BCN

25 de clabLevel



 

msie7
Citar            
MensajeEscrito el 29 Oct 2009 09:06 pm
Lo acabo de probar...no tengo tween lite asi que use el tween de flash pero creo que logre buen testing XD


Tienes dos problemas y son mas o menos con la logica de tu programa:

Parece ser que tu problema es la parte en la que asiganas la funcion mover.

Código ActionScript :

e.target.addEventListener(MouseEvent.MOUSE_MOVE,mover); 


En la funcion comienzaDrag que se ejecuta al mousedown en tu ficha ojo EN LA FICHA osea que el e.target es la ficha misma en la parte donde la remueves en finDrag hay de dos o el mouseup se da sobre la ficha o sobre la escena entonces le remueves el mover a tu escena y al acercarte parce quedarse pegado. asi que yo cambiaria esas dos lineas de la siguiente manera.

Código ActionScript :

this.addEventListener(MouseEvent.MOUSE_MOVE,mover); 
this.removeEventListener(MouseEvent.MOUSE_MOVE,mover); 

//siempre remueves el evento de tu ficha


El segundo problema que veo esque si arreglas lo que te menciono arriba funcionara en teoria bien pero va parecer que no funciona (si se que es confuso).

Agregas un listener de mousemove sobre tu ficha entonces al moverse el mouse SOBRE TU FICHA esta se mueve hacia el mouse pero si el mouse se mueve fuera de tu ficha que pasa......exacto nada la ficha parecer no obedecer entonces yo agregaria estos listener a escena o al padre, para esto guardo en una variable esa referencia ue tu pasas como parametro

Código ActionScript :

public class Ficha extends MovieClip { 
 
      //constructor 
var padre:DisplayObject;
      public function Ficha(padre:DisplayObject) { 
         this.addEventListener(MouseEvent.MOUSE_DOWN,comienzaDrag); 
         this.addEventListener(MouseEvent.MOUSE_UP,finDrag); 
         padre.addEventListener(MouseEvent.MOUSE_UP,finDrag); 
this.padre=padre;
      } 


Entonces las lineas del listener mover las cambiaria por

Código ActionScript :

as]
padre.addEventListener(MouseEvent.MOUSE_MOVE,mover); 
padre.removeEventListener(MouseEvent.MOUSE_MOVE,mover); 

//siempre remueves el evento de padre

[/as]

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 30 Oct 2009 07:38 am
Gracias por la respuesta Angel Roberto pero no acabo de entender tu propuesta...

Dentro del metodo comienzaDrag hecemos add y remove?

padre.addEventListener(MouseEvent.MOUSE_MOVE,mover);
padre.removeEventListener(MouseEvent.MOUSE_MOVE,mover);

Has logrado que funcione el codigo que me comentas? si es asi...puedes poner como queda la clase completa?

Yo lo he probado y no me funciona, como comente antes soy novato en esto del AS 3 :-(

Muchisimas gracias por el apoyo, la verdad es que sin vosotros esto se haria mucho mas dificil ;-)

Por Manolito_BCN

25 de clabLevel



 

msie7
Citar            
MensajeEscrito el 30 Oct 2009 03:48 pm
No hago un add y remove ya que esto no hace nada XD.

Mi propuesta es poner el listener de mover al padre y no ala ficha y lo hice asi:

Código ActionScript :

package { 
 
   import flash.display.MovieClip; 
   import flash.display.DisplayObject; 
   import flash.text.TextField; 
   import flash.events.*; 
   import fl.transitions.*; 
   import fl.transitions.easing.*;
   import flash.filters.DropShadowFilter; 
 
   public class Ficha extends MovieClip { 
 
      //constructor 
     var padre:DisplayObject;

      public function Ficha(padre:DisplayObject) { 
         this.addEventListener(MouseEvent.MOUSE_DOWN,comienzaDrag); 
         this.addEventListener(MouseEvent.MOUSE_UP,finDrag); 
         padre.addEventListener(MouseEvent.MOUSE_UP,finDrag); 
       this.padre=padre;
      } 
       
      function comienzaDrag(e:MouseEvent):void { 
         //la traemos al frente 
         var arriba:int=this.parent.numChildren - 1; 
         this.parent.setChildIndex(this,arriba); 
 
         //Le aplicamos un filtro de sombra (distancia, angulo, color, alpha, blurX, blurY) 
         e.target.parent.filters=[new DropShadowFilter(5,45,0x000000,0.5,15,15)]; 
         //lo movemos 
         //e.target.addEventListener(MouseEvent.MOUSE_MOVE,mover); 
      padre.addEventListener(MouseEvent.MOUSE_MOVE,mover); 
      } 
      function finDrag(e:MouseEvent):void { 
         //le quitamos el movimiento 
         //e.target.removeEventListener(MouseEvent.MOUSE_MOVE,mover); 
      padre.removeEventListener(MouseEvent.MOUSE_MOVE,mover); 
      } 
      function mover(e:MouseEvent):void {   
     trace("Moviendose");
         var t=new Tween(this,"x",Regular.easeIn,x,parent.mouseX,.5,true); 
       var t2=new Tween(this,"y",Regular.easeIn,y,parent.mouseY,.5,true); 
      } 
   } 
} 


Si te fijas almaceno el padre en una variable y los listener de mover se los pongo o remuevo al padre con esto funcoina un poco mejor pero creo que aun no es el efecto que deseas.


Nota1: Yo use el tween nativo cambialo por el tuyo ;)
Nota2:Cuando se hace mouseUp tu remueves el listener de mover pero como los tweens ya fueron creados la ficha no se
detendra hasta terminarse estos tweens, si quieres que en cuanto se haga mouseUp se detenga necesitas detener esos
tweens.

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 30 Oct 2009 04:12 pm
Ya veo Angel, pero si te fijas sigue comportandose de la misma forma. Si haces Up fuera de la ficha, al pasar sobre esta se queda "enganchada" aunque no hagas Down sobre ella...

Alguna idea de porque pasa esto?????

Me tiene loco!!!

Por Manolito_BCN

25 de clabLevel



 

msie7
Citar            
MensajeEscrito el 30 Oct 2009 11:42 pm
Ami no me pasa eso de que se queda pegada postea el codigo para verlo de nuevo.

Por Angel Roberto

Claber

248 de clabLevel



 

firefox
Citar            
MensajeEscrito el 31 Oct 2009 11:43 am
COMORRR?????

Angel uso el codigo de la clase tal cual lo has colgado y te puedo asegurar que se "engancha", es mas con Tween nativo va bastante peor que con TweenLite

Si quieres te paso los archivos a tu mail.

Gracias por el interes

Por Manolito_BCN

25 de clabLevel



 

msie7
Citar            
MensajeEscrito el 02 Nov 2009 10:40 am
Yo acabo de probar la clase y me funciona bien:

Código ActionScript :

package {  
  
   import flash.display.MovieClip;  
   import flash.display.DisplayObject;  
   import flash.text.TextField;  
   import flash.events.*;  
   import fl.transitions.*;  
   import fl.transitions.easing.*; 
   import flash.filters.DropShadowFilter;  
  
   public class Ficha extends MovieClip {  
  
      //constructor  
     var padre:DisplayObject; 
 
      public function Ficha(padre:DisplayObject) {  
         this.addEventListener(MouseEvent.MOUSE_DOWN,comienzaDrag);  
         this.addEventListener(MouseEvent.MOUSE_UP,finDrag);  
         padre.addEventListener(MouseEvent.MOUSE_UP,finDrag);  
       this.padre=padre; 
      }  
        
      function comienzaDrag(e:MouseEvent):void {  
         //la traemos al frente  
         var arriba:int=this.parent.numChildren - 1;  
         this.parent.setChildIndex(this,arriba);  
  
         //Le aplicamos un filtro de sombra (distancia, angulo, color, alpha, blurX, blurY)  
         e.target.parent.filters=[new DropShadowFilter(5,45,0x000000,0.5,15,15)];  
         //lo movemos  
         //e.target.addEventListener(MouseEvent.MOUSE_MOVE,mover);  
      padre.addEventListener(MouseEvent.MOUSE_MOVE,mover);  
      }  
      function finDrag(e:MouseEvent):void {  
         //le quitamos el movimiento  
         //e.target.removeEventListener(MouseEvent.MOUSE_MOVE,mover);  
      padre.removeEventListener(MouseEvent.MOUSE_MOVE,mover);  
      }  
      function mover(e:MouseEvent):void {    
         var t=new Tween(this,"x",Regular.easeIn,x,parent.mouseX,.5,true);  
        var t2=new Tween(this,"y",Regular.easeIn,y,parent.mouseY,.5,true);  
      }  
   }  
}  


Me he creado un archivo fla, y un rectangulo mc linkado a la clase.
En el primer frame del .fla pongo el siguiente codigo:

Código ActionScript :

var ficha:Ficha = new Ficha(stage);  
ficha.x = 200  
ficha.y = 200  
addChild(ficha); 


Y funciona correctamente, no me pasa eso de que se engancha.

Por ur!

256 de clabLevel



 

Barcelona

chrome
Citar            
MensajeEscrito el 02 Nov 2009 11:01 am
Quizas no me explique bie ncon lo qde que se engancha.
Desde luego el efecto conseguido no es nada fluido.

Creo que optare por buscar otra solucion al problema


gracias por el interes

Por Manolito_BCN

25 de clabLevel



 

msie7

 

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