AS3:防止事件发生两次?

问题描述:

在我的游戏中,如果球击中了winBox,你会得到一个Win消息。问题在于球弹跳,它可能会重复打击球。我怎样才能防止邮件每次会话发生两次?AS3:防止事件发生两次?

  if (simContacts.isCurrentContact(winBox,gameBall)) 
     { 
      // Won. 
      trace ('You won!'); 
      isFiring=false; 

      //Win Message 
      winMsg=new win_mc(); 
      addChild(winMsg); 
      winMsg.y=250; 
      winMsg.x=40; 
      winMsg.gotoAndPlay(2); 

     } 

完整代码:

package { 

import flash.display.MovieClip; 
import com.actionsnippet.qbox.*; 
import flash.events.MouseEvent; 
import flash.events.Event; 

[SWF(width = 300, height = 600, frameRate = 60)] 

public class LuckyHitBeta extends MovieClip { 

    public var sim:QuickBox2D; 
    var winBox:QuickObject; 
    var looseBox:QuickObject; 
    var looseBox2:QuickObject; 
    var gameBall:QuickObject; 
    var simContacts:QuickContacts; 
    var isFiring:Boolean=false; 
    var ballIcon:ballIcon_mc; 
    var winMsg:win_mc; 



    /** 
    * Constructor 
    */ 
    public function LuckyHitBeta() 
    { 
     liveIcon(); 
     sim = new QuickBox2D(this); 
     simContacts = sim.addContactListener(); 
     simContacts.addEventListener(QuickContacts.ADD, contactListener); 
     //Important Collisions; 

     winBox = sim.addBox({x:2,y:597/30, width:98/30, height:10/30, density:0, skin:stick, skinScale:false}); 
     looseBox = sim.addBox({x:5,y:597/30, width:98/30, height:10/30, density:0, skin:stick, skinScale:false}); 
     looseBox2 = sim.addBox({x:8,y:597/30, width:98/30, height:10/30, density:0, skin:stick, skinScale:false}); 
     //Collisions 
     sim.addBox({x:3.5,y:560/30, width:72/30, height:13/30, density:0, skin:stick, skinScale:false, angle:1.57}); 
     sim.addBox({x:6.5,y:560/30, width:72/30, height:13/30, density:0, skin:stick, skinScale:false, angle:1.57}); 
     sim.addBox({x:0/30,y:300/30, width:600/30, height:28/30, density:0, skin:stick, skinScale:false, angle:1.57}); 
     sim.addBox({x:300/30,y:300/30, width:600/30, height:28/30, density:0, skin:stick, skinScale:false, angle:1.57}); 



     // make obstacles 
     for (var i:int = 0; i<(stage.stageWidth/28); i++){ 
     //End 
      sim.addCircle({x:1.2 + i * 0.8, y:16, radius:0.15, density:0, skin:ping, scaleSkin:false}); 
      sim.addCircle({x:0.6 + i * 0.8, y:15, radius:0.15, density:0, skin:ping, scaleSkin:false}); 
     } 

     for (var o:int = 0; o<(stage.stageWidth/55); o++){ 
     //Middle 

       sim.addCircle({x:1.3 + o * 1.5, y:14, radius:0.15, density:0, skin:ping, scaleSkin:false}); 
       sim.addCircle({x:1.3 + o * 1.5, y:13, radius:0.15, density:0, skin:ping, scaleSkin:false}); 
       sim.addCircle({x:1.3 + o * 1.5, y:12, radius:0.15, density:0, skin:ping, scaleSkin:false}); 
       sim.addCircle({x:1.3 + o * 1.5, y:11, radius:0.15, density:0, skin:ping, scaleSkin:false}); 
       sim.addCircle({x:1.3 + o * 1.5, y:10, radius:0.15, density:0, skin:ping, scaleSkin:false}); 
     } 

     for (var u:int = 0; u<(stage.stageWidth/45); u++){  
     //Start 
      sim.addCircle({x:0.8 + u * 1.3, y:09, radius:0.15, density:0, skin:ping, scaleSkin:false}); 
      sim.addCircle({x:1.55 + u * 1.3, y:08, radius:0.15, density:0, skin:ping, scaleSkin:false}); 
      sim.addCircle({x:0.8 + u * 1.3, y:07, radius:0.15, density:0, skin:ping, scaleSkin:false}); 
      sim.addCircle({x:1.55 + u * 1.3, y:06, radius:0.15, density:0, skin:ping, scaleSkin:false}); 

     } 
     addEventListener(Event.ENTER_FRAME,onEnterFrm); 
     stage.addEventListener(MouseEvent.CLICK, _clicked); 
     sim.start(); 



    } 

    /** 
    * .. 
    * @param e MouseEvent.CLICK 
    */ 
    private function _clicked(e:MouseEvent) 
    { 
     if (! isFiring){ 
      gameBall = sim.addCircle({x:(mouseX/30), y:(2), radius:0.15, density:1, restitution:0.7, friction:0, skin:ball, scaleSkin:false, angularDamping:20}); 
      isFiring=true; 
      ballIcon.gotoAndStop(2); 

     } 
    } 

    private function liveIcon():void { 
     ballIcon=new ballIcon_mc(); 
     addChild(ballIcon); 
     ballIcon.y=30; 
    }   

    private function onEnterFrm(e:Event):void 
    {   
     ballIcon.x=mouseX; 
     if (gameBall && gameBall.body.IsSleeping()) 
      { 
       gameBall.destroy(); 
       gameBall = null; 
       isFiring=false; 
       ballIcon.gotoAndStop(1); 
      } 
    } 

    private function contactListener(e:Event) 
    { 
     if (simContacts.isCurrentContact(winBox,gameBall)) 
     { 
      // Won. 
      trace ('You won!'); 
      isFiring=false; 
      ballIcon.gotoAndStop(1); 

      winMsg=new win_mc(); 
      addChild(winMsg); 
      winMsg.y=250; 
      winMsg.x=40; 
      winMsg.gotoAndPlay(2); 

     } 

     if (simContacts.isCurrentContact(looseBox,gameBall)) 
     { 
      // Loose. 
      trace ('You loose!'); 
      //gameBall({friction:1,restitution:0}); 
      isFiring=false; 
      ballIcon.gotoAndStop(1); 
     } 
    } 


} 

}

使 “你赢了!”消息每球触发一次,当玩家获胜时移除事件监听器,并且每次用户创建球时添加它。将事件监听器多次添加到同一个对象是可以的;事件监听器函数仍然只会被调用一次。

private function clicked(e:MouseEvent) 
{ 
    if (!isFiring) 
    { 
     // Add the ball. 
     simContacts.addEventListener(QuickContacts.ADD, contactListener); 
    } 
} 

... 

private function contactListener(e:Event):void 
{ 
    if (simContacts.isCurrentContact(winBox, gameBall)) 
    { 
     // You win. 
     simContacts.removeEventListener(QuickContacts.ADD, contactListener); 
    } 
    else if (simContacts.isCurrentContact(winBox, gameBall)) 
    { 
     // You lose. 
    } 
} 
+0

谢谢,问题是如果我再次击中目标,将不会有任何消息! – 2011-12-20 06:09:21

+1

这不就是目标吗?你说过,“防止邮件每次会话发生两次。”什么是会话,何时/如何重置? – 2011-12-20 06:14:38

+0

对不起,我没有解释清楚,我使用isFiring = true或false,如果没有触发,那么它不应该允许消息出现。 – 2011-12-20 06:23:42

或者您可以检查是否已添加winMsg。 (无论你将它添加到这个例子中的舞台)。

if (stage.contains(winMsg)) 
{ 
winMsg=new win_mc(); 
addChild(winMsg); 
winMsg.y=250; 
winMsg.x=40; 
winMsg.gotoAndPlay(2); 
} 

所以winMsg只会添加一次。

然后删除winMsg并在完成后将其设置为null。

removeChild(winMsg); 
winMsg = null; 

PS。当设置事件监听器时,最好的做法是(IMO)始终使用弱引用,否则可能会遇到从内存中清除对象的问题。要做到这一点只需添加

,假,0,真正

您addEventListeners结束。例如

simContacts.addEventListener(QuickContacts.ADD,contactListener,false,0,true);