Як боротися з відмінностями між двовимірними координатами екрана та декартовими координатами


23
  • У більшості 2D-екранових / растрових систем координат позитивна вісь Y спрямована вниз (з початком у верхньому лівому куті).
  • Це суперечить тому, як більшість людей думають геометрично з позитивною віссю Y вгору (з початком у центрі).

Як більшість ігор керують двома різними двовимірними системами координат? Є два основні типи координат (екран проти декартових), але може бути багато різних координатних просторів: спрайтовий простір, світовий простір, простір виду, простір екрану тощо ...

Фон:

Я спочатку зробив світові координати в своїй грі, що відповідає двовимірному екрану координат. Це зробило дуже природно використовувати графіки графіки малювання, але тонкі проблеми виникли при використанні тригонометричних функцій, таких як atan2 (). Результати подачі координат екрана 2D atan2 () дуже заплутані, оскільки atan2 () передбачає позитивну вісь y вгору.

Тому я змінив свої світові координати, щоб слідкувати за класичною декартовою системою координат (з початком у нижній лівій частині екрана). Міркування з atan2 () набагато простіше, але зараз важче робити інші типи міркувань:

  • Якщо тут натиснути екран, який спрайт знаходиться під ним?
  • Де я натиснув на цей спрайт?
  • Якщо спрайт намальовано в неправильному місці, що було обчислено неправильно? Координати екрану чи координати світу?

Я усвідомлюю, що перетворення з екрана в декартові координати включає просто масштабування значення y на -1 з необов'язковим перекладом обох (x, y) значень. Мене більше цікавлять кращі практики дизайну ігор:

  • Чи більшість ігор просто дотримуються домовленості про координати екрану і змінюють своє мислення про те, як повинні працювати такі речі, як atan2 ()?
  • Коли / як проводяться перетворення системи координат? (Використання матриць, абстрагування OOP тощо)
  • Чи зберігаються спрайтові місця як центр спрайта або один з кутів? Висота / ширина спрайта, що йде в неправильному напрямку, здається, є звичайною проблемою, коли я малюю їх.

Хоча моє запитання в основному стосується двомірних ігор, схоже, OpenGL використовує систему координат, де вісь Y спрямована вгору. Врешті-решт OpenGL повинен проеціювати ці 3D координати на систему координат 2D екрану. Можливо, деякі методи можна знайти в методі OpenGL ...

Відповіді:


8

Перепробувавши всі можливі способи цього, я виявив, що це суто 2D гра, просто використовуйте систему малювання екрана, це полегшить ваше життя. Sin, Cos та atan2 потрібно використовувати дещо інакше, але цю незручність легко компенсувати простотою того, що знати, який шлях вгору, вниз, за ​​годинниковою стрілкою та проти годинникової стрілки. Я б також рекомендував працювати в пікселях, а не в метрах для 2D-ігор - набагато простіше думати про екранні відстані, і шанси на те, що ви захочете змінити всю шкалу вашої гри, близькі до нуля.

"Як більшість ігор управляють двома різними двовимірними системами координат?"

  • Більшість 2D ігор я бачив як джерело для використання екранної системи, але кожна організація повинна знати свій світовий простір, нехай ваш менеджер малюнків перетворить це у положення екрану. У цей момент ви будете робити все необхідне для перетворення матриці.

"Чи зберігаються спрайтові місця як центр спрайта або один з кутів?"

  • Якщо ви працюєте з центру, це робить обертання більш прямим вперед, хоча ви хочете знати і кути.

"Можливо, деякі методи можна знайти в методі OpenGL ..."

  • 3D-двигуни - зовсім інший випадок. Оскільки у них є справжні камери, положення екрана може дико відрізнятися від світового. У грі зверху вниз ви працюєте в осях X і Z, а не X і Y для одного.

1

Я, можливо, надто спрощую тут речі, але моє схильність полягатиме в тому, щоб будь-яка 2D / UI підсистема відповідала суворо за тими, що ви назвали "екранними" координатами. У вас були дві матриці: ScreenToCartesianTransform та CartesianToScreenTransform. Коли приймаються події введення миші, координати миші будуть перетворені за допомогою CartesianToScreenTransform перед тим, як передаватись до менеджера вводу системи 2D / UI. Звідти система користувальницького інтерфейсу буде виконувати тест-хіт, використовуючи систему координатних екранів, і обробляти (або не обробляти) подію відповідно. Якщо подія введення миші не обробляється 2D / UI, вона може бути передана в 3D-систему (якщо така існує), використовуючи оригінальні непереформовані координати.

Оскільки система 2D / UI матиме справу лише з "екранними" координатами, її геометрію потрібно буде перетворити за допомогою ScreenToCartesianTransform, перш ніж обробляти двигун візуалізації.


Насправді, залежно від того, який інструментарій ви використовуєте, події введення миші вже можуть знаходитись у координатах екрана. У такому випадку ви б не трансформували їх для системи 2D / UI, а для 3D-системи (якщо така існує).
Майк Стробель

0

Я вважаю за краще використовувати дерево дисплея, як у Flash. У мене буде кореневий вузол (перегляд гри), який містить дитину для світу (world node) і один зверху для HUD. Всередині світового вузла будуть вузли для об'єктів у ігровому світі.

Потім я просто перетворюю світовий вузол. Поряд з перекладом (панорамування камери) та пропорційним масштабуванням (масштабування камери) я також застосовую ще два перетворення:

  • Шкала -1 у, щоб перевернути систему координат.
  • Масштабування для перетворення світових одиниць (метрів) у екранні одиниці (пікселі)

Потім я використовую координати y-up / world у коді малювання ігрового об'єкта та координатах y-down / screen у коді малювання HUD, які обидва відчувають себе дуже природними.

Щоб відповісти на запитання типу "на який об'єкт я натискаю", я використовую методи вузла відображення для перетворення координат між системами координат (такими як globalToLocalі його зворотний у Flash).

До речі, atanнасправді не працює по-іншому, коли y вниз, потрібно просто подумати про всі кути, як проходити за годинниковою стрілкою, а не проти.


0

OpenGL, як і DirectX, має осі X і Z вздовж горизонтальної площини та Y спрямовані вгору.
У мене ніколи не виникало проблем із координатами екрана, і я думаю, що найпростішим способом було б просто ставитись до цього, як це відбувається: якщо щось, наприклад, atan2, йому не подобається, то змініть параметри подавання.

Якщо ви використовуєте відносні або локальні координати, наприклад графік сцени, то така проста функція, як ToGlobalCoords (), є хорошою. Насправді, якщо ви хочете дізнатися більше про просторове позиціонування, графіки сцен та localToGlobal, про це говорить безкоштовний витяг з Game Engine Architecture.

Спрайти намальовані з верхнього лівого кута або (0,0) походження. Причини тому, що з-за верхнього лівого походження вікна.

Здається, трохи нерозумно змінити систему координат вікон, і зробить такі речі, як введення, яке грає більшу роль у більшості ігор, ніж триггер, значно складніше. Це також відчужує вас від норми та будь-яких користувачів вашого коду.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.