【问题标题】:AS3 - How to properly stop player with hitTestObject and restrict player's movement based on colliding area?AS3 - 如何使用 hitTestObject 正确停止玩家并根据碰撞区域限制玩家的移动?
【发布时间】:2015-12-31 14:35:08
【问题描述】:

我有两个碰撞问题,当玩家多次按下移动键时,玩家可能会在对象上出现故障,并且玩家的xy 移动一旦接触到对象的任何一侧都会停止。它应该只停止xy,具体取决于它接触到哪一侧。

当它触及边界框的左/右侧时,它应该仍然能够上下移动。当它接触边界框的顶部/底部时,它应该能够左右移动。

我在 Player 类中的移动代码 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 类 ENTER_FRAMEMovieClips 的基类)中的 hitTestObject 代码:

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 文件包括一个播放器和一个可以与之碰撞的床。

【问题讨论】:

    标签: actionscript-3 hittest


    【解决方案1】:

    您的游戏设计结构不合理。您应该有一个 ENTER_FRAME 用于游戏逻辑。取而代之的是,您有一个ENTER_FRAME 用于玩家,一个ENTER_FRAME 用于交换孩子,一个ENTER_FRAME 用于每个障碍物。这种设计不仅让您头疼,而且会让您的游戏性能发挥得淋漓尽致。

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

    把这段代码放在CollisionBaseClass:

    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

    【讨论】:

    • 碰撞似乎在示例文件上运行良好。但是它不使用基类作为障碍物,而是使用主类。您能否更新示例,以便移动和碰撞代码在玩家类和障碍物基类中工作,而不是使用主类?很抱歉,我很困惑,无法正常工作,谢谢!
    • 如果你愿意,你可以有一个class 用于障碍物,但是如果你看一下这个例子,我试图解释的是:所有的游戏逻辑代码(main ENTER_FRAME)Main Class 更好。如果你有很多ENTER_FRAMES,你会有很多麻烦。但是,如果您想这样做,请按照我在帖子中提到的步骤使用您当前的游戏逻辑修复您的游戏。
    • 我试过你的代码,但我猜它有问题?由于某种原因,我的播放器在触摸对象时停止并且无法移动。我使用了 if(_collision){}。即使我没有在代码中添加任何内容,它也会让我的角色停止。
    • 我已经用上面的代码修改了你的FLA,但是你会看到出现闪烁。这个问题的解释在我上面的评论中。请按照我的建议为您的游戏逻辑添加一个ENTER_FRAMEFLA
    猜你喜欢
    • 1970-01-01
    • 2021-05-10
    • 1970-01-01
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多