我正在尝试按照本教程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相同。但它仍然无效。
感谢您的帮助。
答案 0 :(得分:1)
很难说出这里发生了什么。如果可能的话,您可以尝试将问题缩小一些,并告诉我们您的一些神奇数字和变量的含义。但根据我自己的碰撞检测经验,你的玩家可能会闪烁,因为代码正在将他的位置移动到墙上并重置它,因为它是不允许的。在获得输入之后需要进行碰撞检查,在更新位置之前需要进行碰撞检查。
类似于:(伪编码......)
if(input == "right" && !(Tile.right.collidable))
{
//vector.speed = {1, 0, 0};
}
else
{
//vector.speed = {0, 0, 0};
}
可能不完全是这样,但我希望它有所帮助。干杯〜
答案 1 :(得分:1)
此时我开始认为我们没有足够的信息来回答你的问题。以下是一些想法:
速度是一个整数吗?你的坐标是整数吗?看起来可以将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坐标,然后添加一个像素。这可能至少部分地导致你的闪烁。