Я кодирую игру на Java, в которой вы перемещаете прямоугольник вокруг JFrame через среду лабиринта.Мое обнаружение столкновений работает точно так, как можно было бы ожидать для правой и верхней сторон круга, состоящего из множества пикселей (каждый пиксель рассматривается как прямоугольник для столкновений, поэтому я не думаю, что форма имеет значение).Однако, когда прямоугольник сталкивается с левой или нижней частью массы пикселей, он перемещается в противоположную сторону фигуры.Может кто-нибудь объяснить, почему это происходит?Я проверил все вокруг этого сайта, и, похоже, ни у кого нет моей проблемы.
player = Rectangle, pts = ArrayList of Points
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 х 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);
}