对于Actionscript 3中的每个循环和碰撞检测

时间:2011-06-11 20:45:59

标签: flash actionscript-3 for-loop foreach-loop-container

我正在制作Flash游戏,目前正在进行碰撞检测编码。碰撞检测将用于检测玩家是否遇到障碍物,如果玩家遇到障碍物,那么它将阻止他通过障碍物。

这是我用于碰撞检测的代码:

createLevel函数

   private function createLevel():void
    {
        for (var i:int; i < numChildren; i++)
        {
            if (getChildAt(i) is Trees)
            {
                var j = getChildAt(i);
                treesArray.push(j);
                trace(treesArray.length);
            }
        }
    }

和碰撞检测功能。

    private function checkCollisions():void
    {
        for each (var trees:Trees in treesArray)
        {
            if (player.hitTestObject(trees))
            {
                switch (true)
                {
                    case (player.x <= trees.x) :
                        player.setRightSpeed(0);
                        break;
                    case (player.x >= trees.x) :
                        player.setLeftSpeed(0);
                        break;
                }

                switch (true)
                {
                    case (player.y <= trees.y) :
                        player.setDownSpeed(0);
                        break;
                    case (player.y >= trees.y) :
                        player.setUpSpeed(0);
                        break;
                }
            }
            else
            {
                player.resetSpeeds();
            }
        }

我将拖动到Flash舞台上的所有Trees对象放入一个数组中。然后在游戏循环中,我有它,以便它检查与checkCollision()函数的冲突。

我拥有它,以便如果玩家完全击中任何一棵树,那么它将看到他击中了哪一侧并阻止玩家向那个方向移动。如果玩家没有击中任何东西,那么将速度重置为正常,这样他就可以向任何方向移动。

但该代码仅适用于treesArray中的第一个Tree对象。我的意思是说,只有当他移动到第一棵树而不是阵列中的任何其他树时,才会停止玩家。如何使它适用于所有树木?

另外我认为这可能是由于player.resetSpeeds()功能的位置,但我并不确定。

1 个答案:

答案 0 :(得分:2)

有点不清楚resetSpeeds()究竟是做什么的,但我可以从你提供的代码中看出它将永远被执行 - 除非玩家同时击中游戏中的所有树。

假设游戏中有4棵树,而玩家在左侧击中第二棵树,那么将按顺序对玩家对象执行以下操作:

  1. resetSpeeds()
  2. player.setRightSpeed(0)
  3. resetSpeeds()
  4. resetSpeeds()
  5. 你必须首先找到被击中的树,然后才改变玩家的速度一次(而不是游戏中树木的数量)。

    /** Find the first Trees that was hit by the player.
      * Note that the loop will quit early once a collision is found. */
    private function getHitTrees():Trees {
        for each (var trees:Trees in treesArray) {
            if (player.hitTestObject(trees)) {
                return trees;
            }
        }
        return null;
    }
    
    private function checkCollisions():void {
        var hitTrees:Trees = getHitTrees();
    
        if (hitTrees) { stopThePlayer(hitTrees); }
        else { letThePlayerMoveOn(); }
    }
    

    这也将使您的代码更具可读性,方法是将其拆分为更小的块,其中的函数名称可以准确地告诉您正在发生的事情;而不是一个有很多嵌套的大功能。

    顺便说一下:无论谁用switch(true)教你这个伎俩:请你坚持下去。那是完全不可读的。