AS3 错误 #1010 术语未定义且没有属性(两个对象数组之间的冲突)

AS3 Error #1010 A term is undefined and has no properties (Collision between two arrays of objects)

现在我让玩家向随机生成的吃豆人扔披萨。碰撞检测只有 40% 的时间有效。有时,披萨直接穿过 PacMan 或中途消失,并且此错误消息不断出现:TypeError: Error #1010: A term is undefined and has no properties。 在 PizzaDelivery/update()。请帮忙!

package  
{
      import flash.display.MovieClip;
      import flash.events.Event;
      import flash.events.KeyboardEvent;

public class PizzaDelivery extends MovieClip
{
    var moveLeft:Boolean;
    var moveRight:Boolean;
    var moveDown:Boolean;
    var moveUp:Boolean;
    var playerSpeed = 10;
    var numOfPizza = 0;
    var genList:Array = [];
    var genX:Array = [10,10,10,115,115,115];
    var genY:Array = [10,115,215,10,115,215];
    var pizzaList:Array = [];
    var enemyList:Array = [];
    var spawnTimeList:Array = [];
    var timer = 0;

    public function PizzaDelivery() 
    {

        for(var s=0; s!=12; s++)
        {
            spawnTimeList[s] = Math.floor(Math.random()*480);
        }

        for(var a=0; a!=6; a++)
        {
            genList[a]= new pizzaGen();
            stage.addChild(genList[a]);
            genList[a].x = genX[a];
            genList[a].y = genY[a];
            genList[a].timer = 60;
        }

        stage.addEventListener(Event.ENTER_FRAME, update);
        stage.addEventListener(KeyboardEvent.KEY_DOWN, movePlayer);
        stage.addEventListener(KeyboardEvent.KEY_UP, ceasePlayer);

        stackOfPizza.stop();
        player.stop();
    }

    function update(event:Event):void
    {

        //spawning enemies
        timer++;
        for(var o=0; o<=spawnTimeList.length-1; o++)
        {
            if(timer==spawnTimeList[o])
            {
                addEnemy(new PacMan);
            }
        }

        //pizza
        if(pizzaList.length != 0)
        {
            for(var f = 0; f <= pizzaList.length - 1; f++)
            {
                if(pizzaList[f].x >= 1000)
                {
                    if(pizzaList[f].parent)
                    {
                        pizzaList[f].parent.removeChild(pizzaList[f]);
                        pizzaList.splice(f,1);
                    }
                }
                if(enemyList.length != 0)
                {
                    for(var e = 0; e != enemyList.length - 1; e++)
                    {
                        if(pizzaList[f].hitTestObject(enemyList[e]))
                        {
                            if(pizzaList[f].parent)
                            {
                                pizzaList[f].parent.removeChild(pizzaList[f]);
                                pizzaList.splice(f,1);
                            }
                            if(enemyList[e].parent)
                            {
                                enemyList[e].parent.removeChild(enemyList[e]);
                                enemyList.splice(f,1);
                            }
                        }
                    }
                }
            }
        }

        //pizza generators
        for(var b=0;b!=6;b++)
        {
            if(player.hitTestObject(genList[b]))
            {
                if(genList[b].timer==60)
                {
                    if(numOfPizza!=10)
                    {
                        genList[b].timer = 0;
                        genList[b].gotoAndStop(0);
                        genList[b].visible = false;
                        numOfPizza++;
                        stackOfPizza.gotoAndStop(numOfPizza+1);
                    }
                }
            }
            if(genList[b].timer != 60)
            {
                genList[b].timer++;
            } else
            {
                genList[b].visible = true;
                genList[b].gotoAndStop(4);
            }
        }

        //player movement
        if(moveLeft==true)
        {
            player.play();
            player.x -= playerSpeed;
            stackOfPizza.x -= playerSpeed;
        }
        if(moveRight==true)
        {
            player.play();
            player.x += playerSpeed;
            stackOfPizza.x += playerSpeed;
        }
        if(moveUp==true)
        {
            player.play();
            player.y -= playerSpeed;
            stackOfPizza.y -= playerSpeed;
        }
        if(moveDown==true)
        {
            player.play();
            player.y += playerSpeed;
            stackOfPizza.y += playerSpeed;
        }
    }

    function addEnemy(object:Object):void
    {
        enemyList.push(object);
        stage.addChild(enemyList[enemyList.length-1]);
        object.x = 1000;
        object.y = Math.floor(Math.random() * (400-object.height));
    }

您几乎答对了,但需要做一些微小的改动。

1。当 pizzaList[f].x > 1000 时,你删除了那个披萨,你不能再用它来检查碰撞,因为它已经不存在了。最简单的方法是在碰撞检测之前有一个单独的 x 位置检查循环。

2。 For 循环:当您 运行 一个数组循环并在循环内删除它的元素时,您需要记住,在删除任何元素时,您也会更改数组中其余元素的顺序。

F.ex。如果你删除第二个元素,那么第三个将变成第二个,依此类推。同时你的循环变量从 1 增加到 2,结果是当下一个循环周期使用 array[2] 时,它跳过第二个元素(以前的第三个元素)。

为避免这种情况,您有几种不同的解决方案。

  • 在某些情况下 break循环会起作用,但并非总是如此。
  • 当你得到一个 "match" 时,将循环变量减 1 以避免跳过下一个循环。
  • 使用反向循环,从头到尾计数。

3。当您获得正面的 hitTestObject 时,您将移除比萨饼和敌人。但是,由于披萨现在已被移除,您无法使用相同的披萨继续敌人循环,因为它已不复存在。 因此,匹配后,仅 break; 内循环然后外循环继续下一个元素。

//pizza
var f:int;
if(pizzaList.length != 0){
    for(f = pizzaList.length - 1; f > -1; f--){ // 1 & 2
        if(pizzaList[f].x >= 1000){
            if(pizzaList[f].parent){
                pizzaList[f].parent.removeChild(pizzaList[f]);
                pizzaList.splice(f,1);
            }
        }
    }
    if(enemyList.length != 0){
        for(f = pizzaList.length - 1; f > -1; f--){ // 2
            for(var e:int = enemyList.length - 1; e > -1; e--){ // 2
                if(pizzaList[f].hitTestObject(enemyList[e])){
                    if(pizzaList[f].parent){
                        pizzaList[f].parent.removeChild(pizzaList[f]);
                        pizzaList.splice(f,1);
                    }
                    if(enemyList[e].parent){
                        enemyList[e].parent.removeChild(enemyList[e]);
                        enemyList.splice(f,1);
                    }
                    break; // 3
                }
            }
        }
    }
}

实际上你不需要检查 .parent 比萨饼和敌人。

编辑: 我的第一点不是必须的,因为你可以把所有的东西都放在同一个循环中,只在底部有 else 块:

if(pizzaList[f].x >= 1000){
  //removing pizza
}else{
  if(enemyList.length != 0){
    //check collisions
  }
}

请记住,您不需要在此 else 块中使用另一个 pizzaList 循环,因为您已经在一个循环中了。