碰撞检测 – 确保玩家精确触摸物体

我知道这确实是我应该能够自己弄清楚的,但是一个解决办法就是逃避我。

好的,这是我的代码的几个相关部分。

bool Game::Col(int x1,int y1,int w1,int h1, int x2, int y2,int w2,int h2) { if(x1 > x2 + w2 || y1 > y2 + h2 || x2 > x1 + w1 || y2 > y1 + h1) { return false; } return true; } 

这是我的碰撞检测algorithm。 很简单,只适用于矩形。

  int bX = (player.getX() - 64) / 32; int bY = (player.getY() - 64) / 32; int tX = (player.getX() + 64) / 32; int tY = (player.getY() + 64) / 32; for(int a=bX;a<tX;a++) { for(int b=bY;b<tY;b++) { if(Col(player.getX(), player.getY(), 32, 32, a * 32, b * 32, 32, 32) && blocks[a][b] == 1) { player.setX(oldX); player.setY(oldY); goto loopExit; } } } loopExit: 

这是我的碰撞检测。 这是在玩家x / y被操纵之后执行的(每1/60秒在任何方向上5个像素)。 块是我的瓷砖地图只是一个二维数组。 我知道我现在有碰撞检测的方式不是太优化,但是它需要几秒钟才能实现,而且速度相当快。

但玩家现在只能在一个物体的5个像素内。 我该如何解决?

你需要做的是创建一个方法,获取玩家与平铺的数量。 您将为每个轴创建此方法的副本。 当您移动播放器时,您首先在X轴上移动播放器。 然后你检查碰撞。 如果你发现一个相互碰撞的方块,你可以将玩家的偏移量join到方块中,并从玩家的X轴上减去它(注意你必须考虑到玩家正在移动的方向)。

在X轴上移动播放器之后,您将在Y轴上重复该过程,获取碰撞的贴片并抵消播放器。 有一个原因,我们必须独立移动每个轴。 如果我们不这样做,你将无法分辨哪一个动作引起了碰撞。 换句话说,我们坠落的事实是否造成碰撞,这意味着我们必须得到Y抵消? 还是因为我们正在向右移动?

有了这个知识,我们的碰撞代码应该是这样的:

 void movePlayer() { int left = // get the left-most tile to check for collision int right = // get the right-most tile to check for collision int top = // get the top-most tile to check for collision int bottom = // get the bottom-most tile to check for collision for(int xt = left; xt < right; xt++) { for(int yt = top; yt < bottom; yt++) { Tile t = world.getTile(xt, yt); if(aabb.collidesWith(t.getBox()) { xPos -= t.getBox().getOffsetX(aabb, /* Here you may also pass in the movement direction to determine wether you should pass a positive or negative number, to ensure you move the player in the right direction. */); } } } aabb.updateBox(); // Because we moved the character. You may also want to update the left and right variables for(int xt = left; xt < right; xt++) { for(int yt = top; yt < bottom; yt++) { Tile t = world.getTile(xt, yt); if(aabb.collidesWith(t.getBox()) { yPos -= t.getBox().getOffsetY(aabb, /* Again, pass the movement direction. I usually represent this with a positive or negative integer. */); } } } aabb.updateBox(); } 

你显然将不得不适应这个代码来适应你的程序,但这应该对你有所帮助。

如果您以5个像素的增量移动,则会将玩家“locking”到距离块一定距离的地方。 你必须建立代码,让玩家以较小的增量移动剩余的距离,例如1像素,以接触块。