繁体   English   中英

基于平铺的2D碰撞检测问题

[英]Tile-based 2D collision detection problems

我正在尝试按照本教程http://www.tonypa.pri.ee/tbw/tut05.html在基于磁贴的世界中实现实时冲突。

由于这些属性,我找到了我的实体的中心坐标:

public float CenterX
{
    get { return X + Width / 2f; }
    set { X = value - Width / 2f; }
}
public float CenterY
{
    get { return Y + Height / 2f; }
    set { Y = value - Height / 2f; }
}

然后在我的更新方法中,在每个帧调用的播放器类中,我有以下代码:

public override void Update()
{
    base.Update();

    int downY = (int)Math.Floor((CenterY + Height / 2f - 1) / 16f);
    int upY = (int)Math.Floor((CenterY - Height / 2f) / 16f);
    int leftX =     (int)Math.Floor((CenterX + Speed * NextX - Width / 2f) / 16f);
    int rightX = (int)Math.Floor((CenterX + Speed * NextX + Width / 2f - 1) / 16f);

    bool upleft = Game.CurrentMap[leftX, upY] != 1;
    bool downleft = Game.CurrentMap[leftX, downY] != 1;
    bool upright = Game.CurrentMap[rightX, upY] != 1;
    bool downright = Game.CurrentMap[rightX, downY] != 1;

    if(NextX == 1)
    {
        if (upright && downright)
           CenterX += Speed;
        else
           CenterX = (Game.GetCellX(CenterX) + 1)*16 - Width / 2f;
    }
 }

downY,upY,leftX和rightX应分别找到最低Y位置,最高Y位置,最左侧X位置和最右侧X位置。 我添加+ Speed * NextX,因为在本教程中,使用以下参数调用getMyCorners函数:

getMyCorners (ob.x+ob.speed*dirx, ob.y, ob);

GetCellX和GetCellY方法:

public int GetCellX(float mX)
{
    return (int)Math.Floor(mX / SGame.Camera.TileSize); 
}
public int GetCellY(float mY)
{
    return (int)Math.Floor(mY / SGame.Camera.TileSize); 
}

问题是玩家在撞墙时会“闪烁”,并且角落检测甚至无法正常工作,因为它可以重叠仅撞击其中一个角落的墙壁。 我不明白出了什么问题。 在本教程中,ob.x和ob.y字段应与我的CenterX和CenterY属性相同,ob.width和ob.height应与Width / 2f和Height / 2f相同。 但它仍然无效。

谢谢你的帮助。

很难说出这里发生了什么。 如果可能的话,您可以尝试将问题缩小一些,并告诉我们您的一些神奇数字和变量的含义。 但是根据我自己在碰撞检测方面的经验,您可能会因为代码正在将他的位置移到墙上并由于不允许重新设置而将其重置,所以您可能正在忽悠。 在获取输入之后和更新位置之前,需要进行碰撞检查。
像:(伪币......)

   if(input == "right" && !(Tile.right.collidable))
    {
        //vector.speed = {1, 0, 0};
    }
else
{
//vector.speed = {0, 0, 0};
}


也许不完全是这样,但我希望它有所帮助。 干杯〜

编辑 - 哎呀,你是对的。 CenterX是一个像素坐标,GetCellX将其转换为平铺坐标,因此代码是等效的。 确实很难遵循。

目前,我开始认为我们没有足够的信息来回答您的问题。 以下是一些想法:

速度是一个整数吗? 你的坐标是整数吗? 看起来可以将0.5像素传递到墙壁而不会发生碰撞,但是当你传入1.0像素时,你会被快照回来。 如果速度和坐标是不会发生的整数,这就是我假设教程有效的方法,但是如果任何分数进入,那么你可能会看到一些抖动。

base.Update()有什么重要的事情吗? 渲染何时发生? 在调用Update()之间,是否还有其他动作会使播放器移动?

地图和播放器是如何呈现的? 它们是否有可能意外地相对于彼此放置在错误的位置? 我不认为这会导致你的闪烁问题,但它可能会导致你的碰撞检测问题有时让你通过。

老答案:

本教程本身并不是特别清楚:很难理解它应该做什么。 你有的地方(Game.GetCellX(CenterX) + 1)*16 - Width / 2f教程有(ob.xtile+1)*game.tileW-ob.width 这些是不同的。 本教程采用一个tile索引,添加一个以获得下一个tile,然后转换为x坐标。 您的代码获取一个图块索引,转换为x坐标,然后添加一个像素。 这可能至少部分负责您的闪烁。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM