即使使用完美的矩形,actionscript 3.0内置碰撞检测似乎也存在缺陷

时间:2013-06-10 06:11:50

标签: actionscript collision-detection

这是我的第一篇文章。我希望答案不是那么明显 - 我找不到它。 我在as3中有一个碰撞检测项目 - 我知道奇怪的形状不会完美地触及内置的检测方法,但据说完美的矩形正好是它们所包含的边界框的形状 - 但是 - 运行下面的代码,我发现每隔一段时间,一个形状似乎不会在正确的时间触发测试,我无法弄清楚原因。

我有两个类 - 一个创建一个矩形形状,一个主类创建一个具有随机宽度和高度的形状,从屏幕顶部以随机x值以设定的速率向底部动画它们,模仿引力。如果一个形状击中屏幕的底部,它就会在舞台的显示部分和未显示的部分中间位于其下边界之间,如预期的那样 - 但是当两个形状最终碰撞时,预期的行为并不总是发生 - 预期的行为因为已经下落并与另一个形状相撞的形状应该停止并停留在它所接触的形状的顶部,而有时下降的形状将部分地或完全地落在它应该碰撞的形状上。

有没有人知道为什么会这样?

以下是我的两个课程:

// box class //

package
{
    import flash.display.Sprite;

    public class Box extends Sprite
    {
        private var w:Number;
        private var h:Number;
        private var color:uint;
        public var vx:Number = 0;
        public var vy:Number = 0;

        public function Box(width:Number=50,
                            height:Number=50,
                            color:uint=0xff0000)

        {
            w = width;
            h = height;
            this.color = color;
            init();
        }

        public function init():void{
            graphics.beginFill(color);
            graphics.drawRect(0, 0, w, h);
            graphics.endFill();
        }
    }
}

//主要类//

package
{
    import flash.display.Sprite;
    import flash.events.Event;

    public class Boxes extends Sprite
    {
        private var box:Box;
        private var boxes:Array;
        private var gravity:Number = 16;


        public function Boxes()
        {
            init();
        }
        private function init():void

        {   
            boxes = new Array();
            createBox();
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
        }

        private function onEnterFrame(event:Event):void
        {
            box.vy += gravity;
            box.y += box.vy;

            if(box.y + box.height / 2 > stage.stageHeight)
            {
                box.y = stage.stageHeight - box.height / 2;
                createBox();
            }
            for(var i:uint = 0; i < boxes.length; i++)
            {
                if(box != boxes[i] && box.hitTestObject(boxes[i]))
                {
                    box.y = boxes[i].y - box.height;
                    createBox();
                }
            }

    }

        private function createBox():void
        {
            box = new Box(Math.random() * 40 + 10,
                          Math.random() * 40 + 10, 
                          0xffaabb)
            box.x = Math.random() *stage.stageWidth;
            addChild(box);
            boxes.push(box);
        }
}
}

1 个答案:

答案 0 :(得分:1)

确保box.vy永远不会超过任何创建的框的高度。否则,盒子可能会在掉落时穿过其他盒子。 (如果box.vy = 40并且box [i] .height = 30,则可以直接通过它。)

只需添加支票:

if(box.vy>terminalVelocity)box.vy=terminalVelocity)

其中terminalVelocity是一个盒子的最小高度(在你的代码中,它看起来像10)。如果你真的想要那些小盒子,你将不得不使用比hitTestObject更精确的东西。