1

I am making a game similar to doodle jump and I have a powerup MovieClip that appears every time the character bounces up. When the character collides with the powerup, I want it to add to the live score, and then disappear. But I want it to reappear after is has been removed so there is a constant stream of powerups (one for each time the character jumps).

The problem I'm having is that as soon as the first powerup is hit, it visually removes all future powerups but the character is still able to collide with them - constantly adding to the score rather than just once.

I made a recording that I think would help explain.

Here's the block of code I'm trying to fix:

//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);
                    }

            }

In case it's something outside of this chunk, here's my whole code:

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;
    }
BadFeelingAboutThis
  • 14,445
  • 2
  • 33
  • 40
Ceejay1705
  • 35
  • 7

1 Answers1

0

Removing an object does not change its x/y coordinates or width/height (bounds). hitTestObject checks the two objects bounds - it does not take into consideration if an object is actually on the display tree or not. So even though you've successfully removed the object, the hit test will keep checking it. (as the object still exists, it just can't be seen)

You can remedy this by doing a check first to see if chickMc has been removed:

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

The parent property of a display object will null after being removed from the stage.

Though instead of that, you may want to null the reference to the object so it can be garbage collected later:

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)
    }
}
BadFeelingAboutThis
  • 14,445
  • 2
  • 33
  • 40
  • 1
    Instead of setting the element to null, consider removing it from the list. You'd have to iterate backwards then. – null May 23 '15 at 08:08
  • @null - Not much point unless they were to change the way they define the vector. As currently it's a fixed length vector (pointlessly set to 1, but I'm assuming they plan on adding more elements later once it's working) - I prefer dynamic arrays myself, but there is nothing wrong with using a fixed one, it *may* have a slight speed advantage I suppose – BadFeelingAboutThis May 24 '15 at 00:02
  • @LDMS If there would be many insertions/deletions into `powerup` array, the app would leak memory and lose performance counting all those `null`s that were formerly powerups. Not a good idea IMNSHO. – Vesper May 28 '15 at 14:34