Вращающиеся координаты (Java и геометрия) - PullRequest
0 голосов
/ 15 декабря 2018

Я работаю над 2D-движком Java, используя основу AWT.Частью этого игрового движка является то, что он должен иметь хитбоксы при столкновении.Не только встроенные прямоугольники (уже пробовал эту систему), но мне нужен мой собственный класс Hitbox, потому что мне нужно больше функциональности.Таким образом, я сделал один, поддерживает круглые и четырехсторонние многоугольные хитбоксы.Класс hitbox настроен так, что он использует четыре координатные точки в качестве 4 угловых вершин, которые соединяются, чтобы сформировать прямоугольник.Линии - это линии, соединяющие точки, и эти линии используются для обнаружения пересечений с другими хитбоксами.Но теперь у меня есть проблема: вращение.

Существует две возможности для хитбокса бокса, это может быть просто четыре координатные точки или 4 координатные точки, прикрепленные к игровому объекту.Разница заключается в том, что первая - это всего лишь 4 координаты, основанные на 0,0 в качестве ординаты, тогда как прикрепленный к игровому объекту хранит смещения в координатах, а не в необработанных данных о местоположении, поэтому (-100, -100), например, представляет местоположение хоста.gameobject, но 100 пикселей влево и 100 пикселей вверх.

В сети я нашел формулу для вращения точек относительно начала координат.Поскольку хитбоксы, основанные на Gameobject, были сосредоточены вокруг определенной точки, я подумал, что это будет лучшим вариантом, чтобы примерить это.Этот код запускает каждый тик для обновления хитбокса персонажа игрока

            //creates a rectangle hitbox around this gameobject 
        int width = getWidth();
        int height = getHeight();
        Coordinate[] verts = new Coordinate[4]; //corners of hitbox. topLeft, topRight, bottomLeft, bottomRight
        verts[0] = new Coordinate(-width / 2, -height / 2);
        verts[1] = new Coordinate(width / 2, -height / 2);
        verts[2] = new Coordinate(-width / 2, height / 2);
        verts[3] = new Coordinate(width / 2, height / 2);
        //now go through each coordinate and adjust it for rotation
        for(Coordinate c : verts){
            if(!name.startsWith("Player"))return; //this is here so only the player character is tested
            double theta = Math.toRadians(rotation);
            c.x = (int)(c.x*Math.cos(theta)-c.y*Math.sin(theta));
            c.y = (int)(c.x*Math.sin(theta)+c.y*Math.cos(theta));
        }
        getHitbox().vertices = verts;

Я прошу прощения за плохое качество видео, но вот каковы результаты вышеупомянутого: https://www.youtube.com/watch?v=dF5k-Yb4hvE

Все связанные классынайдено здесь: https://github.com/joey101937/2DTemplate/tree/master/src/Framework

edit: желаемый эффект состоит в том, что контур окна следует за символом в круге, сохраняя соотношение сторон, как показано здесь: https://www.youtube.com/watch?v=HlvXQrfazhA.Текущая система использует приведенный выше код, эффект которого можно увидеть выше в предыдущей ссылке на видео. Как мне изменить четыре 2D-координаты, чтобы поддерживать относительное соотношение сторон при вращении вокруг точки?

Текущая система вращения выглядит следующим образом:

  • x =x * Cos (theta) - y * Sin (theta)
  • y = x * Sin (theta) + y * Cos (theta)

где theta - степень вращения вraidians

1 Ответ

0 голосов
/ 15 декабря 2018

Вы допустили классическую ошибку:

    c.x = (int)(c.x*Math.cos(theta)-c.y*Math.sin(theta));
    c.y = (int)(c.x*Math.sin(theta)+c.y*Math.cos(theta));

Во второй строке вы используете измененное значение c.x.Просто запомните tempx = c.x перед вычислениями и используйте его.

    tempx = c.x;
    c.x = (int)(tempx*Math.cos(theta)-c.y*Math.sin(theta));
    c.y = (int)(tempx*Math.sin(theta)+c.y*Math.cos(theta));

Другая проблема: округление координат после каждого поворота вызывает искажения и сжатие после некоторых поворотов.Было бы целесообразно хранить координаты в числах с плавающей запятой и округлять их только для вывода, или запоминать начальные значения и применять к ним вращение на накопленный угол.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...