我正在用Java编写游戏,其中您通过迷宫式环境在JFrame周围移动Rectangle。我的碰撞检测的工作原理与人们对由许多像素组成的圆的右侧和顶部完全一样(每个像素被视为碰撞的矩形,因此我认为形状并不重要)。但是,当矩形与像素块的左侧或底部碰撞时,矩形将移至形状的相对侧。有人可以解释为什么会这样吗?我已经检查了该站点的所有内容,似乎没有人遇到我的问题。
player =一个矩形,pts =一个点的ArrayList
public void detectCollisions()
{
isHit = false;
pts.stream().forEach((p) ->
{
double w = 0.5 * (1 + player.width);
double h = 0.5 * (1 + player.height);
double dx = p.x - player.getCenterX();
double dy = p.y - player.getCenterY();
if (abs(dx) < w && abs(dy) < h)//collision
{
double wy = w * dy;
double hx = h * dx;
if (wy >= hx)
if (wy >= -hx)//top of block
player.y = p.y - player.height;
else//right of block
player.x = p.x + 1;
else
if (wy >= -hx)//left of block
player.x = p.x - player.width;
else//bottom of block
player.y = p.y + 1;
isHit = true;
}
});
if (isHit)
onHit(1);
}
edit:我已通过将像素更改为“矩形”并将播放器和其他矩形都设置为25 x 25像素来解决此问题。我还实现了水平和垂直增量变量,以使运动更平滑,并为可能的速度提供合理的限制。这是我的新代码:
public void detectCollisions()
{
isHit = false;
rects.stream().forEach((re) ->
{
double w = 0.5 * (re.width + player.width);
double h = 0.5 * (re.height + player.height);
double dx = re.getCenterX() - player.getCenterX();
double dy = re.getCenterY() - player.getCenterY();
if (abs(dx) < w && abs(dy) < h)//collision
{
double wy = w * dy;
double hx = h * dx;
if (wy >= hx)
if (wy >= -hx)//top of block
{
player.y = re.y - player.height;
vDelta = 0;
}
else//right of block
{
player.x = re.x + re.width;
hDelta = 0;
}
else
if (wy >= -hx)//left of block
{
player.x = re.x - player.width;
hDelta = 0;
}
else//bottom of block
{
player.y = re.y + re.height;
vDelta = 0;
}
}
});
hazardRects.stream().forEach((re) ->
{
double w = 0.5 * (re.width + player.width);
double h = 0.5 * (re.height + player.height);
double dx = re.getCenterX() - player.getCenterX();
double dy = re.getCenterY() - player.getCenterY();
if (abs(dx) < w && abs(dy) < h)
{
isHit = true;
double wy = w * dy;
double hx = h * dx;
if (wy >= hx)
if (wy >= -hx)//top of block
{
player.y = re.y - player.height;
vDelta = 0;
}
else//right of block
{
player.x = re.x + re.width;
hDelta = 0;
}
else
if (wy >= -hx)//left of block
{
player.x = re.x - player.width;
hDelta = 0;
}
else//bottom of block
{
player.y = re.y + re.height;
vDelta = 0;
}
}
});
if (isHit)
onHit(1);
}