Підробка ізометричної графіки в 2D космічній грі


15

По-перше, я точно знаю, у чому полягає моя проблема малювання, і у мене є різні ідеї, як підійти до її вирішення. Я тут, щоб зрозуміти, як відрегулювати, який кадр намальований, щоб збереглась ізометрична «ілюзія».

Я пишу 2D гру з видом на птахи, яка відбувається в космосі. Я намагаюся використовувати ізометричну графіку в світі, де Up is North, немає обертання ігрового світу, як у традиційних ізометричних іграх (пам’ятайте, гра відбувається в просторі, без місцевості). Ось приклад спрайту, який я намагаюся використати: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64.png Повертається 64 рази щодо власної вертикальної осі з кутом огляду 35 градусів (так, ізо). Зображення було згенеровано, тому це можна змінити.

Для наочності я продиктував, що північ (вгору) 0 градусів, а схід (праворуч) 90.

Моя проблема полягає в тому, що мій спрайт не завжди виглядає так, як стикається там, де гра вважає, що це пов'язано з різницею в використовуваних 3D-площинах. Не впевнений, чи правильно я використовую термінологію, але мій космічний корабель був повернутий на одну площину, і площина огляду очікує, що речі будуть обернені у власній площині. Ось змалювання проблеми:

http://cell.stat-life.com/images/stories/AsteroidOutpost/ProjectionIssue.png Ліворуч я маю вигляд збоку, праворуч - вид зверху вниз. На вершині у мене є світове космічне судно / спрайт. Знизу я маю те, як виглядає спрайт, коли його малюють на екрані.

У верхньому правому куті - спрощена версія того, як обертався мій космічний корабель (рівномірна ступінь поділу між кожним кадром). У нижньому правому куті розташований кут, на який спрайт виглядає, як він стикається, коли на екрані намальований певний кут. Проблема найбільш очевидна при температурі близько 45 градусів. Ось зображення, накладене лінією "площини екрана", яка вказується у напрямку, до якого повинен бути судно: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64RedLine.png Червону лінію слід завжди вказувати в точно такому ж напрямку, що і корабель, але, як ви бачите, проблема проекції викликає проблему. Я сподіваюся, що я досить добре описую це питання.

EDIT: Червона лінія обертається на площині екрана, тоді як космічний корабель обертається на "площині корабля", отже, велика різниця між кутом судна та кутом екрана при його малюванні. END EDIT

Це виглядає досить дивним, коли цей корабель стріляє лазерним променем у ціль, що знаходиться в бік, коли він повинен стріляти прямо вперед.

Отже ... рішення, яке я придумав:

  1. Перестаньте намагатися підробити ізометричний вигляд, ідіть великим або йдіть додому. Поверніть мій світ уже. (PS: це вирішить мою проблему, правда?)
  2. Змініть аркуш спрайта (якимось чином), щоб у ньому були кадри, які представляють "кут екрану", на який буде розглянута модель. Тож коли я попрошу зображення на 45 градусів, воно буде фактично виглядати так, що воно на екрані 45 градусів.
  3. Змініть мою спрайтову систему спрайтів, щоб схопити інший кадр із аркуша спрайта (якось), знаючи, що захоплення "нормального" кадру буде виглядати смішно. Тож замість того, щоб захопити 45-градусний кадр, він захопить ... 33-градусний кадр (просто здогадуючись), щоб він виглядав правильно для користувача.
  4. Просто використовуйте 3D! Людина так набагато простіше

Для одного: яке рішення ви б рекомендували? Я схиляюся до 2, хоча я знаю, що це неправильно. Пам'ятайте, що я маю повний доступ до інструменту генерації спрайтів. Метод 3 був би моїм другим вибором. Обидва ці методи просто вимагають, щоб я застосував деяку математику до кута (кутів), щоб отримати бажаний результат. До речі, я додав туди №4 як жарт, я не хочу переходити на 3D.

Для двох: Використовуючи методи 2 або 3, як би я відрегулював кути вводу чи виходу? Мені не все так добре з 3D-проекціями та 3D-матрицями (не кажучи вже про 2D-матриці), і будь-якою іншою математикою, що може бути використана для досягнення бажаного результату.

Думаючи тут голосно: якщо я візьму одиничний вектор, спрямований у напрямку, в якому я хочу, щоб судно виглядало (на площині екрана), то спроектував це на корабельну площину, а потім зрозумій, який кут між цією проектованою лінією та площиною На північ - у мене повинен бути кут графіки корабля, який я хочу відображати. Правильно? (рішення для №3?) Людина ... Я не можу це зробити.

Редагувати:

Я знаю , що проблема важко візуалізувати зі статичними зображеннями, так що я виконав свою Sprite Library Візуальний Tester для відображення питання: http://cell.stat-life.com/downloads/SpriteLibVisualTest.zip Це вимагає XNA 4.0 Ця програма просто обертаючи спрайт і прорисуючи лінію від його центральної точки назовні під кутом, який гра вважає, що корабель повинен бути стикається.

EDIT 8 вересня

Продовжуючи з мого абзацу "вголос": Замість використання проекції (тому що це виглядає важко) Я думаю, що я міг би взяти одиничний вектор, орієнтований на північ (0x, 1y, 0z), використовую матрицю, щоб повернути його на кут спрайт справді облицьований, потім повернути його знову від "площини огляду" назовні до "площини спрайта" навколо осі X, потім ... сплюснути? вектор (по суті проектує його) назад на площу перегляду, використовуючи лише X і Y (ігноруючи Z). Тоді, використовуючи цей новий сплющений вектор, я міг визначити його кут і використати його для ... чогось чогось. Я подумаю більше пізніше.

EDIT 8 вересня (2)

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

Vector3 vect = new Vector3(0, 1, 0);
vect = Vector3.Transform(vect, Matrix.CreateRotationZ(rotation));
vect = Vector3.Transform(vect, Matrix.CreateRotationY((float)((Math.PI / 2) - MathHelper.ToRadians(AngleFromHorizon))));
Vector2 flattenedVect = new Vector2(vect.X, vect.Y);

float adjustedRotation = (float)(getAngle(flattenedVect.X, flattenedVect.Y));

Де rotationзнаходиться кут екрана і adjustedRotationзараз цей кут екрану виглядає на площині спрайта. Я не знаю, чому мені потрібно було обертати Y замість X, але це, мабуть, щось із 3D, про що я не знаю.

Отже, зараз у мене є додаткова інформація, але як я можу використовувати це, щоб вибрати більш відповідний кадр? Можливо, замість того, щоб обертатися з площини виду в площину спрайта, а потім проектуючи назад, я повинен спробувати зробити це навпаки. Ось мій спрайт із скоригованою червоною лінією, але те, що я дійсно хочу зробити, - це коригувати модель, а не лінію: http://cell.stat-life.com/images/stories/AsteroidOutpost/Spaceship64RedLineCorrected.png

EDIT 9 вересня

ХОРАЙ! Це виправлено! Я опишу, що я зробив, щоб виправити це:

Я дотримувався порад електронного бізнесу та "скупився" за світовою системою координат (чи розтягувалась ...?). Це по суті рішення №1, хоча я мав враження, що мені доведеться повертати свою світову систему координат по відношенню до системи координат екрану. Неправда! Вгору все ще + y, а справа - + x. Я змінив свої методи WorldToScreen і ScreenToWorld для належного перетворення між координатами світу та екрана. Ці методи можуть бути не оптимальними, але ось єдині два методи в моїй кодовій базі, які довелося змінити.

public Vector2 ScreenToWorld(float x, float y)
{
    float deltaX = x - (size.Width / 2f);
    float deltaY = y - (size.Height / 2f);

    deltaX = deltaX * scaleFactor / (float)Math.Sqrt(3);
    deltaY = deltaY * scaleFactor;

    return new Vector2(focusWorldPoint.X + deltaX, focusWorldPoint.Y + deltaY);
}

public Vector2 WorldToScreen(float x, float y)
{
    float deltaX = x - focusWorldPoint.X;
    float deltaY = y - focusWorldPoint.Y;

    deltaX = deltaX / scaleFactor * (float)Math.Sqrt(3);
    deltaY = deltaY / scaleFactor;

    return new Vector2(size.Width / 2f + deltaX, size.Height / 2f + deltaY);
}

Це було все! Зміна цих двох методів вплинула на все інше: те, що я дивився, де об’єкти, де малювали, де я клацав, все. Мій космічний корабель зараз дивиться прямо в ціль, яку він стріляє, і все стає на свої місця. Я буду експериментувати з ортографічною проекцією, побачу, чи це робить все більш "справжнім".


Вітаю. Не забудьте ткнути мене, як тільки у вас є щось, що грається, я хотів би побачити, куди це йде.
aaaaaaaaaaaa

@eBusiness Як і обіцяли: cell.stat-life.com/images/stories/AsteroidOutpost/… та cell.stat-life.com/images/stories/AsteroidOutpost/AOOhNoes.png Зверніть увагу, як судно виглядає, як дивиться на цю вежу? : D Дякую!
Джон Макдональд

@eBusiness, відео youtube.com/watch?v=Q8pR9KDBsCo З того часу ви також посилалися на завантаження.
Джон Макдональд

Відповіді:


4

Вибравши ізометричну перспективу, вам потрібно виправити шкалу між віссю X і Y. Якщо задана відстань проектується на 1 на осі Y екрану, то ця ж відстань буде проектуватися на sqrt (3) на екрані X-осі. Тож якщо ви малюєте речі на екрані, ви зробите щось на кшталт:

draw(object.image, object.x*sqrt(3), object.y)

Примітки без відповідей:

  • Чому б ти возився з спрайтовими листами та іншим предметом? Ви можете отримати 3D-рендерір для виконання ізометричної, якщо хочете.
  • Оскільки ви використовуєте спрайтові листи, чому вони не є анти-псевдонімом?
  • Ізометричний у космосі, я не думаю, що я ніколи не бачив, щоб гра використовувала це, я не впевнений, наскільки добре це буде працювати, враховуючи відсутність чітко ізометричного майданчика для візуального орієнтування.

1
Я думаю ... Це могло б все виправити. Це легко виправити, і я можу залишити аркуш у спокої. Я спробую це якнайскоріше, і я дам вам знати, як це відбувається. Щоб відповісти на ваші замітки: 1) Я використовую 2D, тому що це я знайомий, і я генерую свої аркуші з 3D-моделей. 2) Краї повинні бути гострими, але всередині жорстких країв я міг би використовувати альфа-канал для анти-псевдоніму, який прийде. 3) Я не планую імітувати третій вимір (багато), я в основному хочу 2D графіки, які не зверху вниз і дозволяють бачити сторони речей.
Джон Макдональд

5

Як утворюється обертовий спрайт? Це скріншоти обертової 3D-моделі? Кут нахилу обличчя може бути відключений через перспективу камери інструменту 3D моделювання. Ізометрична перспектива - не точне зображення тривимірного простору. Речей, далеких від «камери», не стає менше.

Якщо ви просто хочете швидкого виправлення. Рішення 2 може бути важким для отримання правильного рішення. Рішення 3 здається простим, просто поміняйте рамки, не збігаючи кут, на той, який краще відповідає куту.

Іноді лазери все одно вимикаються. Оскільки ви не робите плавне обертання, але показуєте різні кадри для певних діапазонів градусів.

Редагувати:

Ваша проблема полягає в тому, що створені скріншоти - це не ізометрична перспектива, а звичайний перегляд 3D-камери.

введіть тут опис зображення

Ізометричний вигляд імітує 3D-простір, але не є точним поданням. Зі збільшенням відстані від камери все стає менше. Це не робиться для ізометричної точки зору, оскільки це може спричинити потворні масштабування артефактів у спрайті.

Ваші скріншоти космічного корабля зроблені в перспективі 3D-камери. Ось чому лазерна зйомка вимкнена. Порівняйте червону лінію в "ізометричній" та "перспективі".

Ваш генератор спрайтів повинен використовувати Matrix.CreateOrthographic () замість Matrix.CreatePerspective () для матриці проекції.


Спрайт генерується за допомогою інструменту 3D до 2D, який я розробляю, тому проблема може бути в цьому інструменті. Інструмент просто завантажує 3D-модель, щоб потім досягти Spaceship64.png (вище), він обертає модель на (360/64) = 5.625 градусів, економить її як кадр, а потім повертає її знову на ту саму суму, поки не буде все 64 кадри. Код, який використовується для візуалізації моделі, тут: code.google.com/p/sprite-maker/source/browse/trunk/XNAWindow/… Поворот здійснюється в іншому класі. Я також думав, що рішення 2 і 3 є зворотними один одному, ні?
Джон Макдональд

Відредагував мою відповідь. Дивись вище.
Стівен

Я думаю, що мені може знадобитися зробити і те, і інше: змусити генератор спрайтів використовувати ортографічну проекцію І змінити мою світову систему координат, як те, що говорить @eBusiness. Я спробував ортографічну проекцію вчора ввечері, і це, безумовно, змінило те, як виглядав мій корабель, але одне воно не виправило проблему кута, яку я відчував.
Джон Макдональд

Щойно побачив вашу редакцію. Виправлений спрайт виглядає так, що центр корабля відійшов від центру червоної лінії. Можливо, достатньо намалювати корабель на один-два пікселі вище від початкової точки червоної лінії. Чи змінюється видима помилка, коли корабель відходить від вашого світового походження? Тоді масштабування X-Axis може виправити це.
Стівен

1

Я думаю, що тут у вас є просто те, як виглядає ізометрична. Ви маєте рацію в тому, що, візуально кажучи, існує більша різниця між 0 і 10 градусів, ніж між 90 і 100 градусів. . . але це тому, що ізометричне внутрішньо стискає одну вісь. Якщо ви не хочете такого вигляду, ви не хочете ізометричного.

З цього приводу, я думаю, що проблеми, що виникають у вас, - це відсутність візуальної точки відліку. Ваш мозок припускає, що ви дивитесь на нього зверху вниз - ей, це простір, чому б вам не бути - і так трактує це як стандартний погляд зверху вниз. Для тестування спробуйте додати кілька плаваючих голографічних орієнтирів. Наприклад, кутова сітка під кутом 45 градусів або набір кіл навколо дальності. Переконайтесь, що вони належним чином спотворені, як якщо б вони знаходилися на тій же ізометричній площині, на якій зображений космічний корабель. Я б загрожував, що ваш мозок з'ясує перспективу, і він раптом виглядатиме правильно.

Тепер з’ясуємо, як донести це до своїх користувачів. . . це взагалі інша справа.


Чи не потрібно мені також обертати вісь світу, щоб виконати ілюзію за допомогою цього методу (метод №1 у питанні)?
Джон Макдональд

Наскільки я можу сказати, судно вже візуалізується правильно - бокові види показують його під кутом, який повинен бути для ізометричної, щоб він виглядав «правильним». Я думаю, я не впевнений, що ви маєте на увазі під "обертанням світової осі".
ZorbaTHut

Під "обертанням осі світу" я маю на увазі поворот світу по відношенню до камери на 45 градусів, щоб "Північ" знаходився вгорі праворуч або вліво від екрана по діагоналі, а не "Північ" була прямо вгору у верхній частині екрана.
Джон Макдональд


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