AS3 - 如何使用 hitTestObject 正确停止玩家并根据碰撞区域限制玩家的移动?

AS3 - How to properly stop player with hitTestObject and restrict player's movement based on colliding area?

我有两个关于碰撞的问题,当玩家多次按下移动键时,玩家可能会穿过物体,并且玩家的 xy 移动都会在接触物体的任何一侧时停止目的。它应该只停止 xy 取决于它接触的哪一侧。

虽然它接触到边界框的 left/right 边,但它应该仍然可以上下移动。当它接触边界框的 top/bottom 边时,它应该能够左右移动。

我在播放器中的移动代码class ENTER_FRAME:

private function onEnterFrame(event:Event):void
{
    _vx = 0;
    _vy = 0;

    if (isRight)
    {
        _vx = 5;
    }

    if (isLeft)
    {
        _vx = -5;
    }

    if (isUp)
    {
        _vy = -5;
    }

    if (isDown)
    {
        _vy = 5;
    }

    x += _vx;
    y += _vy;

}

我在 CollisionBase class ENTER_FRAME 中的 hitTestObject 代码(Base Class for MovieClips):

private function onEnterFrame(event:Event):void
{
    if (MovieClip(parent).player.collisionArea.hitTestObject(this))
    {
        if (MovieClip(parent).player.isLeft)
        {
            MovieClip(parent).player.x -= MovieClip(parent).player._vx;
        }

        if (MovieClip(parent).player.isRight)
        {
            MovieClip(parent).player.x -= MovieClip(parent).player._vx;
        }

        if (MovieClip(parent).player.isUp)
        {
            MovieClip(parent).player.y -= MovieClip(parent).player._vy;
        }

        if (MovieClip(parent).player.isDown)
        {
            MovieClip(parent).player.y -= MovieClip(parent).player._vy;
        }
    }
}

FLA 文件:https://www.dropbox.com/s/k5dlxrsnvbrmtke/Subject.zip?dl=0

FLA 文件包含一个播放器和一个碰撞床。

您的游戏设计结构不合理。您应该有一个 ENTER_FRAME 用于游戏逻辑。取而代之的是,玩家有一个 ENTER_FRAME,一个 ENTER_FRAME 可以交换 children,每个障碍物都有一个 ENTER_FRAME。这种设计不仅让您头疼,而且会让您的游戏性能大打折扣。

要解决 hitTest 的问题,请执行以下操作:

将此代码放在 CollisionBase Class:

private function onEnterFrame(event:Event):void
{

    var player:MovieClip = MovieClip(this.parent).player;

    if (player.collisionArea.hitTestObject(this)) player.collision = true;
}

将此 属性 添加到 Player Class:

private var _collision:Boolean = false;

public function set collision(value:Boolean):void{
    _collision = value;
}

接下来,在 onEnterFrame 函数的开头添加这些行:

private function onEnterFrame(event:Event):void
{

    if(_collision){

        x -= _vx;
        y -= _vy;

        _collision = false;

       return;

    }

    _vx = 0;
    _vy = 0;

    if (isRight)
    {
    ....

问题已解决,但现在您的播放器在碰到障碍物时会闪烁。发生这种情况是因为玩家 ENTER_FRAME 移动玩家,然后其他 ENTER_FRAME 检查碰撞(在 CollisionBase.class 中)并且在玩家 ENTER_FRAME 的下一个循环中玩家做了一个退后。如果你只有一个ENTER_FRAME,这样的事情就不会发生。

我建议你其他选择。看看这个例子,看看它是如何制作的,也许它会给你一些想法;)

Download the example