2011-10-03 2 views
0

Supposons que nous avons une scène avec deux places, comme ceci: Our example Flash stageQuelle est la meilleure façon de faire une détection capotage de la souris/déploiement en Flash avec AS3

Supposons que nous aimerions que le carré jaune à d'abord caché , et nous aimerions que tant que le curseur de la souris est à l'intérieur des limites du carré rouge - le carré jaune sera visible, et aussi longtemps que le curseur de la souris est hors des limites du carré rouge - que le carré jaune sera caché.

L'approche intuitive est d'écrire quelque chose comme ceci:

inSqr.visible = false; 
outSqr.addEventListener (MouseEvent.ROLL_OVER,sqrOver); 
outSqr.addEventListener (MouseEvent.ROLL_OUT,sqrOut); 

function sqrOver(e:MouseEvent) { 
    inSqr.visible = true; 
} 

function sqrOut (e:MouseEvent) { 
    inSqr.visible = false; 
} 

Avec ce code, cependant - chaque fois que vous déplacez le curseur de la souris dans le carré jaune - il, apparemment, compte comme une ROLL_OUT pour la ROUGE carré - ainsi la fonction sqrOut est déclenchée - faire le carré jaune disparaissent, et une fois le carré jaune est pas là - le curseur se trouve tout à coup dans les limites de la ROUGE carré à nouveau - donc la fonction sqrOver est appelée - ramenant la visibilité du carré jaune - déclenchement de sqrOut et ainsi de suite, créant ainsi un carré jaune "clignotant" quand le curseur de souris est sur lui: le carré jaune disparaît et réapparaît à plusieurs reprises encore et encore. Une "solution" possible pour cela est de supprimer l'écouteur pour l'événement de déploiement du rouge alors que le curseur est dans le jaune (si c'est à l'intérieur du jaune il est sûrement dans le rouge aussi), et le ramener quand il est sorti, en ajoutant ceci au code ci-dessus:

inSqr.addEventListener (MouseEvent.ROLL_OVER,insqrOver); 
inSqr.addEventListener (MouseEvent.ROLL_OUT,insqrOut); 
function insqrOver(e:MouseEvent) { 
    if (outSqr.hasEventListener (MouseEvent.ROLL_OUT)) { 
     outSqr.removeEventListener(MouseEvent.ROLL_OUT,sqrOut); 
    } 
    inSqr.visible = true; 
} 
function insqrOut(e:MouseEvent) { 
    if (!outSqr.hasEventListener (MouseEvent.ROLL_OUT)) { 
     outSqr.addEventListener(MouseEvent.ROLL_OUT,sqrOut); 
    } 
} 

Cela fonctionne. Mais c'est lourd. Vous devez le faire pour chaque objet à l'intérieur des limites du carré rouge - ce qui entraîne un long code et de nombreux écouteurs d'événements et l'écoute et l'enregistrement continus des écouteurs.


Il y a quelques années quelqu'un m'a suggéré de cette technique:

outSqr.addEventListener (Event.ENTER_FRAME,hoverCheck); 

function hoverCheck (e:Event) { 
    if (e.currentTarget.hitTestPoint(stage.mouseX,stage.mouseY,true)) { 
     inSqr.visible = true; 
    } 
    else { 
     inSqr.visible = false; 
    } 
} 

Ceci est un code simple et bref qui fonctionne. Mais, si votre projet n'a pas vraiment besoin d'utiliser l'événement ENTER_FRAME, il crée le surcoût inutile et les cpu-cycles d'exécution répétée du test d'accès. En outre, si le carré rouge couvre toute la scène (a les mêmes dimensions que la scène) - il crée des problèmes (il ne fonctionne pas).


Quelqu'un est-il au courant d'une manière élégante simple d'y parvenir - qui ne comporterait pas un code trop lourd et long et ce ne serait pas avoir à utiliser une minuterie répétée qui a frappé tests maintes et maintes fois. ..?

Répondre

2

Placez le carré jaune à l'intérieur du carré rouge.

outSqr.addChild(inSqr); 

Cela résoudra vos problèmes bien et simplement. Assurez-vous simplement que outSqr est une instance de la classe Sprite ou MovieClip.

+0

utilisé cette méthode à la fin, un Bien qu'il ait fallu beaucoup de réarrangement de code et de réécriture ... –

0

the simpliest solution i can imagine:

package { 
    import flash.events.MouseEvent; 
    import flash.display.Sprite; 
    public class FlashTest extends Sprite { 
     private var inner:Sprite; 
     private var outer:Sprite; 
     public function FlashTest() { 
      outer = giveRect(200, 200, 0xff0000); 
      addChild(outer); 
      inner = giveRect(50, 50, 0xffff00); 
      addChild(inner); 
      inner.x = inner.y = 75; 
      stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);  
     } 

     private function giveRect(w:int, h:int, color:int):Sprite{ 
      var spr:Sprite = new Sprite(); 
      spr.graphics.beginFill(color); 
      spr.graphics.drawRect(0, 0, w, h); 
      spr.graphics.endFill(); 
      return spr;    
     } 

     private function onMove(e:MouseEvent):void{ 
      inner.visible = stage.mouseX > outer.x && 
          stage.mouseX < outer.x + outer.width && 
          stage.mouseY > outer.y && 
          stage.mouseY < outer.y + outer.height; 
     } 
    } 
} 
1

Je ne sais pas si cela aide dans votre cas, mais vous pouvez également désactiver les actions de la souris du inSqr, alors vous pouvez passer la souris sur le carré jaune qui ne déclenche pas la ROLL_OUT

inSqr.mouseEnabled = false 

..then vous pouvez simplement utiliser ceci:

inSqr.visible = false; 
outSqr.addEventListener (MouseEvent.ROLL_OVER,sqrOver); 
outSqr.addEventListener (MouseEvent.ROLL_OUT,sqrOut); 

function sqrOver(e:MouseEvent) { 
    inSqr.visible = true; 
} 

function sqrOut (e:MouseEvent) { 
    inSqr.visible = false; 
} 
Questions connexes