Столкновение для прямоугольника и пикселей, вызывающих телепортацию - PullRequest
0 голосов
/ 03 марта 2019

Я кодирую игру на 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);
}
...