AS3:被移除的孩子仍然通过HitTest

时间:2015-05-22 20:00:12

标签: actionscript-3 flash hittest removechild

我正在制作一个类似于涂鸦跳跃的游戏,每次角色反弹时我都会出现一个加电MovieClip。当角色与通电相撞时,我希望它添加到实时乐谱中,然后消失。但是我希望它在删除之后重新出现,因此有一个恒定的通电流(每次角色跳跃时都会有一个)。

我遇到的问题是,一旦第一次通电被击中,它就会在视觉上消除所有未来的通电,但角色仍然能够与它们发生碰撞 - 不断增加分数而不是仅仅一次。< / p>

我做了recording,我认为这有助于解释。

这是我尝试解决的代码块:

//IF MyChicken TOUCHES CHICKEN LEG, SCORE GOES UP BY 2000
            for (var c:int=0; c< 1; c++){
                chickMc = powerUp[c];
                if (MyChicken.hitTestObject(chickMc))
                    {
                        liveScore += 2000;
                        theScore.text = liveScore.toString();
                        tapSnd.play();
                        removeChild(chickMc);
                    }

            }

如果它是这个块之外的东西,这是我的整个代码:

import flash.events.Event;
import flash.sensors.Accelerometer;
import flash.events.AccelerometerEvent;
import flash.display.MovieClip;
import flash.media.Sound;
import flash.events.MouseEvent;

var firstPass:int = 1;
var liveScore:int;
var accX:Number;
var myVect:Vector.<MovieClip> = new Vector.<MovieClip>(5,true);
var powerUp:Vector.<MovieClip> = new Vector.<MovieClip>(1, true);
var vAcceleration:Number = 0.5;
var vVelocity:Number = -20;
var middleScreen:Number = stage.height / 2;
//var newEnemy:enemy;
//var nmeMc:MovieClip;
var newChicken:chicken;
var chickMc:MovieClip;
var newBouncer:bouncer;
var tmpMc:MovieClip;
var poolSnd:poolSound = new poolSound();
var tapSnd:tapSound = new tapSound();
var btnAgain:gameOver;

stop();

// MONITOR THE ACCELEROMETER
var myAcc:Accelerometer = new Accelerometer();
myAcc.addEventListener(AccelerometerEvent.UPDATE, onAccUpdate);

function onAccUpdate(evt:AccelerometerEvent):void{
    accX = evt.accelerationX;   
}

//MONITOR THE ENTER_FRAME EVENT
stage.addEventListener(Event.ENTER_FRAME, onMyEnterFrame);

//INIT STAGE WITH PLATFORMS (bouncer)
if (firstPass == 1){
    liveScore = 0;
    accX = 0;

    for (var i:int=0; i< 5; i++){
        newBouncer = new bouncer;
        newBouncer.x = Math.random()*stage.stageWidth;
        newBouncer.y = 0 + i*stage.stageHeight/6;

        myVect[i] = newBouncer;
        addChild(newBouncer);
        newBouncer.cacheAsBitmap = true;}

        for (var c:int=0; c< 1; c++){
        newChicken = new chicken;
        newChicken.x = Math.random()*stage.stageWidth;
        newChicken.y = 0 + c*stage.stageHeight/6;

        powerUp[c] = newChicken;
        addChild(newChicken);
        newChicken.cacheAsBitmap = true;}

        firstPass = 2;
}

function onMyEnterFrame(evt:Event):void{

    //MOVE X DEPENDING ON THE ACCELEROMETER
    MyChicken.x += (MyChicken.x - (MyChicken.x + accX * 20))*0.6;

    //MOVE CHAR TO THE LEFT OR TO THE RIGHT
    if(accX < 0) {
        MyChicken.gotoAndStop(2);
    }else{
        MyChicken.gotoAndStop(1);
    }

    // VERTICAL SPEED OF MyChicken
    vVelocity += vAcceleration;

    if((MyChicken.y > middleScreen) && (vVelocity < 0)){
            // MyChicken IS GOING UP
            MyChicken.y += vVelocity;
        }else{
            if(vVelocity > 0){
                // MyChicken IS GOING DOWN
                MyChicken.y += vVelocity;

                // TEST IF MyChicken HITS PLATFORM
                for (var i:int=0; i< 5; i++){
                    tmpMc = myVect[i];
                    if (MyChicken.hitTestObject(tmpMc))
                        {
                            vVelocity = -20;
                            tapSnd.play();
                        }

                }

                //IF MyChicken TOUCHES CHICKEN LEG, SCORE GOES UP BY 2000
                for (var c:int=0; c< 1; c++){
                    chickMc = powerUp[c];
                    if (MyChicken.hitTestObject(chickMc))
                        {
                            liveScore += 2000;
                            theScore.text = liveScore.toString();
                            tapSnd.play();
                            removeChild(chickMc);
                        }

                }

            }else{
                // THE WORLD IS GOING DOWN
                // WHEN MyChicken IS IN THE MIDDLE OF THE SCREEN

                for (var m:int=0; m< 1; m++){
                    chickMc = powerUp[m];
                    chickMc.y -=  vVelocity;
                }

                for (var j:int=0; j< 5; j++){
                    tmpMc = myVect[j];
                    tmpMc.y -=  vVelocity;
                }

                liveScore += 5;
                theScore.text = liveScore.toString();
            }
        }

        //CHECK IF PLATFORMS ARE OUT OF THE SCREEN
        if(myVect[0] != null){
        for (var k:int=0; k< 5; k++){
                    tmpMc = myVect[k];
                    if(tmpMc.y > stage.stageHeight){
                        tmpMc.y = -5;
                        tmpMc.x =  Math.random()*stage.stageWidth;
                    }
                }
        }

        if(powerUp[0] != null){
        for (var p:int=0; p< 1; p++){
                    chickMc = powerUp[p];
                    if(chickMc.y > stage.stageHeight){
                        chickMc.y = -5;
                        chickMc.x =  Math.random()*stage.stageWidth;
                    }
                }
        }

        //FAIL - IF CHICKEN FALLS OUT OF THE SCREEN
        if  (MyChicken.y > stage.stageHeight) {
            btnAgain  = new gameOver();
            addChild(btnAgain);
            btnAgain.x = 160;
            btnAgain.y = 230;
            btnAgain.theScoreFinal.text =  liveScore.toString();
            theScore.visible = false;
            btnAgain.addEventListener(MouseEvent.MOUSE_DOWN, onPlayAgain);

            //PAUSE GAME
            MyChicken.y = -300;
            vVelocity = 0;
            vAcceleration = 0;

            // PLAY FAIL SOUND
            poolSnd.play();
        }

        // CLICKS ON THE PLAY AGAIN BUTTON
        function onPlayAgain(evt:MouseEvent):void{

            removeChild(btnAgain);

            //NEW GAME
            MyChicken.y = stage.stageHeight - 50;
            MyChicken.x = stage.stageWidth / 2;
            theScore.text = "0";
            liveScore = 0;
            vVelocity = -20;
            vAcceleration = 0.5;
            theScore.visible = true;
        }

        //STAGE BOUNDS MyChicken ON THE LEFT OR RIGHT OF THE SCREEN
        if(MyChicken.x < 0) MyChicken.x = stage.stageWidth;
        if(MyChicken.x > stage.stageWidth) MyChicken.x = 0;
    }

1 个答案:

答案 0 :(得分:0)

删除对象不会更改其x/y坐标或宽度/高度(边界)。 hitTestObject检查两个对象边界 - 它没有考虑对象是否实际在显示树上。因此,即使您已成功删除对象,命中测试也会继续检查它。 (因为对象仍然存在,它无法被看到)

您可以先检查是否已删除chickMc来解决此问题:

if (chickMc.parent && MyChicken.hitTestObject(chickMc))

从舞台中删除后,显示对象的parent属性将为null。

虽然不是这样,但您可能希望null对对象的引用,以便以后可以对其进行垃圾回收:

for (var c:int=0; c< 1; c++){
    chickMc = powerUp[c];
    if (chickMc != null && MyChicken.hitTestObject(chickMc)){
        liveScore += 2000;
        theScore.text = liveScore.toString();
        tapSnd.play();
        removeChild(chickMc);
        powerUp[c] == null; //now that powerup object isn't referenced anywhere and can be garbage collected (destroyed from memory)
    }
}