Я роблю 2D вуличну винищувальну гру, яка не заснована на плитці. Зазвичай люди рекомендують, щоб сутності були надані рендерінгу, який робить їх, а не вони самі, але здається, що обернено краще,
Чому один кращий за іншого?
Спасибі
Я роблю 2D вуличну винищувальну гру, яка не заснована на плитці. Зазвичай люди рекомендують, щоб сутності були надані рендерінгу, який робить їх, а не вони самі, але здається, що обернено краще,
Чому один кращий за іншого?
Спасибі
Відповіді:
Кілька міркувань:
як ви вже згадували, кожен спрайт повинен був би "натякати" про те, яку растрову карту використовувати, але якщо суб'єкт повинен виводити себе. Що це за натяк? Якщо це посилання на інший растровий малюнок, аркуш спрайт тощо тощо для кожного спрайту, ви можете в кінцевому рахунку використовувати більше пам'яті, ніж потрібно, або мати проблеми з керуванням цією пам'яттю. Перевагою окремого рендерінга є те, що у вас є лише один клас, відповідальний за будь-яке управління активами. Однак, у бойовій грі, схожій на SF2, у вас можуть бути лише два спрайти;)
як уже згадувалося в іншому місці, коли ви хочете змінити свій графічний API, ви повинні змінити код для всіх своїх спрайтів.
візуалізація рідко робиться без посилання на якийсь графічний контекст. Отже, або існує глобальна змінна, яка представляє цю концепцію, або кожен спрайт має інтерфейс з візуалізацією (GraphicalContext ctx). Це поєднує графічний API та логіку вашої гри (яку деякі люди вважають неелегантною) і може спричинити проблеми з компіляцією.
Я особисто вважаю, що відокремлення візуалізації від окремих сутностей є цікавим першим кроком у напрямку перегляду вашої гри як системи, яка зовсім не обов'язково потребує графіки. Я маю на увазі те, що коли ви виводите рендерінг, ви усвідомлюєте, що багато ігрових процесів відбувається в "не графічному світі", де важливі координати сутностей, їх внутрішні стани тощо. Це відкриває двері до автоматизованого тестування, більш відокремленої системи тощо ...
Загалом, я, як правило, віддаю перевагу системам, де рендерінг здійснюється окремим класом. Це не означає, що у ваших спрайтів не може бути атрибутів, "графічно пов'язаних" (назва анімації, анімаційний кадр, висота x ширина, ідентифікатор спрайт тощо), якщо це полегшує запис або більш ефективний рендерінг.
І я не знаю, чи застосовуватиметься це до 3D (де поняття сіток та змінної координат, яке ви використовуєте, можливо, буде пов'язане з вашим 3D API; тоді як x, y, h, w майже не залежать від будь-якого 2D API).
Сподіватися, що це допомагає.
Ви хочете, щоб система візуалізації контролювала те, що отримується, коли. Якщо замість цього спрайти контролюють рендерінг, ви втрачаєте велику ефективність та гнучкість. Я вважаю, що використання системи візуалізації в контролі призводить до отримання більш чистого коду.
Деякі переваги централізованої візуалізації:
Те, як я реалізую це в своїх іграх, щоб ігрові об’єкти реєстрували потрібні спрайти в системі візуалізації. Коли об’єкт більше не хоче, щоб об'єкт намальовано, він реєструє спрайт або позначає його неактивним.
Все, що говорили. Якщо ваші ігрові об’єкти простіше зробити, всі способи роблять це так. Набагато важливіше досягти прогресу і отримати щось / що-небудь намальоване, ніж це мати досконалу архітектуру.
Відмова: Ваше запитання не містить багато деталей, тому я відповідаю загальним принципом. Вибачте, будь ласка, якщо я неправильно зрозумів ваше використання чи «візуалізацію».
Як правило, я використовую зовнішній об'єкт для відображення різних акторів на сцені як спосіб інкапсуляції властивостей і методів рівня сцени поза окремими "акторськими об'єктами". Об'єкти в сцені повинні містити лише внутрішні методи та властивості; вони повинні знати лише про те, що вони самі є і що роблять. Імовірно, на них впливатимуть інші об’єкти в грі, а також введення користувачів. Це вплине на те, як / чи відображаються вони на екрані. Наприклад, "об’єкт режисера" може, наприклад, перекласти клавішу "w", щоб перейти, а потім сказати об'єкту актора .jump (). Така логіка режисерського рівня також може підказати акторам повністю вийти на сцену або вийти з неї.
Ура, Давид
Що робити, якщо колись ви захочете перенести гру в іншу роздільну здатність (наприклад, iPhone та друзів). Таким чином, глобальна властивість щодо надання змін, як ви легко оновлюєте свій код?
Я використовував дизайн, заснований на спостерігачах. Коли я створив екземпляр класу, який хотів рендерувати, тоді вказівник на нього зберігався в центральному класі Renderer. Коли ви телефонуєте RenderFrame()
, тоді рендерінг вже має всі існуючі об'єкти, які йому потрібні для візуалізації, і доступ до їх властивостей отримав для цього. Самі заняття не мали поняття, що їх взагалі збирають робити. Цей API був приємним, чистим та простим у використанні.
Загалом, завжди про те, як легко підтримувати і розширювати код. Завтра ви зрозумієте, що графічний API, який ви використовуєте зараз, вам не подобається, і хочете переключитися. Чи доведеться вам зараз пройти всі ваші класи об’єктів і все змінити, чи вам все одно просто потрібно змінити код в одній центральній точці проекту?
Це залежить від того, що справді роблять ваші об'єкти, коли ви викликаєте render (). Поки вони просто обмотують виклики методу навколо вашого графічного движка, це абсолютно добре, оскільки логіка <-> графіки все одно буде надана.
Наприклад, якщо ваші методи render () в основному є зручними методами і виглядають приблизно так:
void MyClass::render(const Graphics &g)
{
g.draw(this);
}
або
void MyClass::render()
{
mySprite->render();
}
або
void MyClass::render()
{
mySprite->UseShader(thatshader);
mySprite->render();
}
або близько до цього, я не думаю, що це взагалі проблема.