如何检查数组中的对象是否相互碰撞?

时间:2016-02-14 04:57:07

标签: arrays actionscript-3 for-loop flash-cs6

大家好,我希望我问的是正确的问题。所以基本上我有一个名为mcLiquidWaste的电影片段,我添加到舞台上。舞台上有3个不同的位置。在我的主引擎类中,我有一个for循环设置,可以控制一次出现的数量:

    private function addLiquidWaste():void 
    {
        //Duplicate Tween for repeat
        TweenLite.delayedCall(randomNumber(nDifficulty1, nDifficulty2), addLiquidWaste);
        //determine how many come out at a time 
        numberOfLiquids = randomNumber(1, 3);
        //iterate through for loop
        for (var i = 0; i < numberOfLiquids; i++)
        {
            //Instantiate liquid
            var liquid:mcLiquidWaste = new mcLiquidWaste();
            //Add liquid to stage
            stage.addChild(liquid);
            //push liquid MC into array
            aLiquidArray.push(liquid);
        }
    }

我遇到的问题是,有时当它们出来时它们会相互重叠,例如说同时出现3个,其中2个可能会出现在我不想要的相同位置。我想以某种方式处理,如果它们出现在相同位置而不是在舞台上的不同插槽中,则将它们移除或使重叠的影片剪辑转到不同的位置。这就是为什么我在考虑检查数组中的2个对象是否正在触摸然后以某种方式删除它们。

以下是我的mcLiquidWaste课程以及如何将他们添加到舞台的不同位置。

private function init():void 
    {
        nSpeed = 4;

        var liquidPosition:Number = randomNumber(1, 3);

        if (liquidPosition == 1) //Position Lava to the Left Hole
        {
            this.y = (stage.stageHeight / 2) - 200;
            this.x = (stage.stageWidth / 2) - 150;
        }
        if (liquidPosition == 2) //Position Lava to the Middle Hole
        {
            this.y = (stage.stageHeight / 2) - 200;
            this.x = (stage.stageWidth / 2) ;
        }
        if (liquidPosition == 3) //Position Lava to the Right Hole
        {
            this.y = (stage.stageHeight / 2) - 200;
            this.x = (stage.stageWidth / 2) + 150;
        }

        addEventListener(Event.ENTER_FRAME, liquidHandler);
    }
你可以在我的废液类中看到它们被添加到舞台的左侧,中间和右侧。如有任何帮助将不胜感激,谢谢!

我是如何设法修复它的

for (var a:int = 0; a < aLiquidArray.length - 1; a++) 
        {
           var l1:mcLiquidWaste = aLiquidArray[a];

           for (var j:int = a + 1; j < aLiquidArray.length; j++) 
           {
              var l2:mcLiquidWaste = aLiquidArray[j];
              if (l1.hitTestObject(l2))
              {
                 //do something on collision
                 l2.destroyLiquid();
              }
           }
        }

1 个答案:

答案 0 :(得分:2)

整个“尝试直到有效”的方法并不理想。理论上,代码可以永远运行,但这不是很可能。

核心问题是你放弃了程序的确定性行为。

  

或让重叠的影片剪辑转到其他位置。

你有这个代码,它同样可能在3个位置中的任何一个产生:

var liquidPosition:Number = randomNumber(1, 3);

    if (liquidPosition == 1) //Position Lava to the Left Hole
    {

现在如果你进入事实并改变位置,这段代码就变得毫无意义了。

假设你有不平等的分布。比方说,在超极端难度下,mcLiquidWaste主要产生于最接近玩家的位置。所以他们到达玩家的距离较短,这会让他们变得更加困难。现在你不想改变立场。

我不建议在确定后更改位置。最好以不能重叠的方式生成mcLiquidWaste

有你的问题

  

以下是我的mcLiquidWaste课程以及如何将他们添加到舞台的不同位置。

private function init():void 
{
    nSpeed = 4;

    var liquidPosition:Number = randomNumber(1, 3);

    if (liquidPosition == 1) //Position Lava to the Left Hole
    {
        this.y = (stage.stageHeight / 2) - 200;
        this.x = (stage.stageWidth / 2) - 150;
    }
//etc... 

每个单独的对象确定其位置本身的事实是问题所在。对象彼此不了解。他们也不应该彼此认识。

对象的定位应该在知道所有对象的类中进行。

溶液

将对象放置在图案中,以便它们不会重叠。一个例子是将它们全部放在一个足够大的圆上,这样它们就不会重叠。

这是一个示例类:

package
{
    public class SpawnPoint
    {
        private var _position:Point;

        public SpawnPoint(position:Point)
        {
            _position = position;
        }

        public spawn (amount:uint):Array
        {
            var waste:mcLiquidWaste;
            var wastes:Array = [];

            // the trivial case of 1, spawn at the position
            if(amount == 1)
            {
                waste = new mcLiquidWaste();

                waste.x = _position.x;
                waste.y = _position.y;

                wastes.push(waste);

                return wastes;
            }

            // if there are more than 1, distribute them on a circle around position

            /*  the radius depends on the size of mcLiquidWaste (and the amount)
                you have to either play around with that value or determine it  
                from the size dynamically
            */
            var radius:Number = 25;

            /*  the angle depends on the number of mcLiquidWaste
                you have to either play around with that value or determine it  
                from the size dynamically
            */
            var angle:Number = 2 * Math.PI / amount; 

            for (var i = 0; i < amount; i++)
            {
                waste = new mcLiquidWaste();

                var posititionOnCircle:Point = Point.polar(radius, i * angle).add(_position);

                waste.x = posititionOnCircle.x;
                waste.y = posititionOnCircle.y;

                wastes.push(waste);
            }

            return wastes;
        }
    }
}

这不会编译,但您明白了:使用radiusangle创建位于圆圈上的位置。用法看起来像这样:

//create spawn point
var leftHole:SpawnPoint = new SpawnPoint(new Point((stage.stageWidth / 2) - 150, (stage.stageHeight / 2) - 200));

// creation of objects
var spawnedObjects:Array = leftHole.spawn(4);

// adding to display list
for (var i:uint = 0; i < spawnedObjects.length; ++i)
{
    addChild(spawnedObjects[i]);
}