2015-05-22 5 views
1

Я делаю игру, подобную прыжку с каракулями, и у меня есть powerup MovieClip, который появляется каждый раз, когда символ отскакивает. Когда персонаж сталкивается с powerup, я хочу, чтобы он добавил к счету в реальном времени, а затем исчез. Но я хочу, чтобы он снова появился после того, как был удален, поэтому существует постоянный поток бонусов (по одному за каждый раз, когда персонаж прыгает).AS3: Удалено Child Still Passes HitTest

Проблема, с которой я столкнулся, заключается в том, что сразу после первого включения питания она визуально удаляет все будущие бонусы, но персонаж все еще может столкнуться с ними - постоянно добавляя счет, а не только один раз.

Я сделал 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; 
    } 

ответ

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) 
    } 
} 
+1

Вместо того чтобы устанавливать элемент обнулить, рассмотреть возможность удаления его из списка. Тогда вам придется повторить попытку. – null

+0

@null - Не так много, если только они не изменили способ определения вектора. Поскольку в настоящее время это фиксированный вектор длины (бессмысленно установлен на 1, но я предполагаю, что они планируют добавлять дополнительные элементы позже, когда он работает). Я предпочитаю динамические массивы самостоятельно, но нет ничего плохого в использовании фиксированного, оно может * имеет небольшое преимущество в скорости. Я полагаю, что – BadFeelingAboutThis

+0

@LDMS. Если в массив 'powerup' будет много вложений/исключений, приложение будет терять память и терять производительность, считая все эти« null », которые раньше были бонусами. Нехорошая идея IMNSHO. – Vesper

Смежные вопросы