基本的平台游戏基于矩形的碰撞问题

本文关键字:碰撞 问题 于矩形 平台 游戏 | 更新日期: 2023-09-27 17:53:57

背景:我最近在xna做了很多研究。我一直在完善我的游戏结构,为一款普通游戏创造基本课程,阅读了一些文章,观看了一些视频,并阅读了我所拥有的一本书的一部分。所以,在创造了一个良好的游戏结构后,我转向了真正的游戏——平台游戏。我目前有普通的块,和一个播放器-问题是在播放器。

问题/问题:与块碰撞通常是好的,但有时碰撞行为奇怪。IE:玩家处于方块中(通常是一个像素),这是一个大问题,因为这可能会导致玩家被推到地图的某个地方。

玩家游戏逻辑:玩家的移动是基于状态的。这些状态是"地面、跳跃和坠落"的枚举数。现在,问题似乎出在下降状态的内部。有时碰撞是正确的,有时玩家最终会在块内的一个像素内结束-这意味着如果玩家跳跃,他将立即被推到玩家上方的第一个块-无论多远。

碰撞逻辑:在下落状态中,玩家被重力推向地板。重力每一帧都被力加进来。在改变位置之前,一个碰撞方法被调用,检查在它的运动范围内的任何块之间是否有碰撞。现在,由于这是一个下落状态,玩家正在向下移动,所以当它发生碰撞时,while循环将玩家每帧向下推1像素,直到遇到方块。就像后退一样,这里有一个循环将玩家推出方块。然后将当前状态设置为接地。跳态也遵循同样的理论。

Falling State Script:阅读上面的代码解释

case PlayerState.Fall:
    // falling sprite
        mySpriteManager.mySpriteCurrent = mySpriteManager.mySpriteIndex["PlayerSprites/player_fall"];
    // fall velocity change
        myVelocity.Y += myDforce;
    if ( Collision( otObjectList.wallIndex, myPosition.X + 1, myPosition.Y, myPosition.X + myWidth - 1, myPosition.Y + myHeight + myVelocity.Y) )
    {
        while( !Collision( otObjectList.wallIndex, myPosition.X + 1, myPosition.Y, myPosition.X + myWidth - 1, myPosition.Y + myHeight) )
            myPosition.Y += 1;
        while ( Collision(otObjectList.wallIndex, myPosition.X + 1, myPosition.Y, myPosition.X + myWidth - 1, myPosition.Y + myHeight))
            myPosition.Y -= 1;
        myVelocity.Y = 0;
        myCurrentState = PlayerState.Ground;
    }
    else
    {
            myPosition.Y += myVelocity.Y;
    }
break;

碰撞脚本:此脚本遍历所有实体对象,直到发生碰撞,如果发生碰撞则返回true。

private bool Collision( List<ObjWall> otWalls, float x1, float y1, float x2, float y2)
{
    myBoundingBox.X = (int)Math.Ceiling(x1);
    myBoundingBox.Y = (int)Math.Ceiling(y1);
    myBoundingBox.Width = (int)Math.Ceiling(Math.Abs( x2 - x1));
    myBoundingBox.Height = (int)Math.Ceiling(Math.Abs( y2 - y1));
    foreach (ObjWall wall in otWalls)
    {
        if ( Box.Intersects( wall.Box ) )
        {
            return true;
        }
    }
    return false;
}

变量说明:

myBoundingBox -每个普通对象都建立在这个抽象类之上。每个对象都有一个边界矩形。

Box -是一个来自抽象对象类的trait,它只返回边界矩形。

myVelocity -是玩家的速度,这是一个Vector2,因为漂浮物提供了更干净的重力。

myDforce -是一个以正作用力改变yvelocity的浮点数。我想我应该让它成为常数。

ObjectList -这是一个类,它运行所有正常对象逻辑,并包含一个房间中所有可能对象的列表。

myPosition -这是抽象类提供的另一个受保护的变量,普通对象是从抽象类驱动的。这是一个向量2,所以它使用float。

在代码中更多的解释,请问!提前感谢您的时间和帮助。礁。

基本的平台游戏基于矩形的碰撞问题

你对Collision的第二次调用目前只检查当前位置,然后将玩家向下移动,而不管该动作是否会导致碰撞。

我可以看到你应该在第三次调用Collision并移动玩家时处理这个问题,但为了从你的代码中删除一些复杂性,你可以简单地让第二次调用Collision检查位置+ 1,如果为真则不移动玩家。

这消除了第三次调用Collision的需要,匹配你使用的逻辑与第一次调用碰撞的大多数下降(即通过重力移动,但如果移动会与墙壁碰撞则不会),并减少可能发生错误的地方。