Планирование 2D-движка плиток - проблемы производительности - PullRequest
1 голос
/ 15 июля 2009

Как следует из названия, я разработал дизайн для 2D-платформерного движка. Это все еще на стадии проектирования, но я беспокоюсь, что у меня возникнут проблемы с рендерером, и я хочу избежать их, если они будут проблемой.

Я использую SDL для своей базовой библиотеки, и игра будет настроена на использование одного большого массива Uint16 для хранения плиток. Эти индексы превращаются во второй массив «определений листов», которые используются всеми частями движка, от обработки столкновений до графической процедуры, что является моей самой большой проблемой.

Графический движок разработан для работы с разрешением 640x480 и плиткой 32x32. На слой на кадр приходится 21x16 плиток (для обработки дополнительной плитки, отображаемой при прокрутке), и можно нарисовать до четырех слоев. Слои - это просто отдельные массивы плиток, но массив определения плиток является общим для всех четырех слоев.

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

Мой целевой FPS - это плоские 60 кадров в секунду, и при рисовании всех четырех слоев я смотрю на 21x16x4x60 = 80,640 отдельных плиток 32x32px, которые нужно рисовать каждую секунду, плюс сколько блит нечетного размера необходимо для спрайты, и это кажется немного чрезмерным. Итак, есть ли лучший способ приблизиться к настройке рендеринга карты тайла, которая у меня есть? Я смотрю на возможности использования аппаратного ускорения для рисования карт листов, если это поможет значительно повысить производительность. Я также хотел бы надеяться, что смогу хорошо запустить эту игру и на немного более старых компьютерах.

Если я ищу слишком много, то не думаю, что об уменьшении возможностей двигателя не может быть и речи.

Ответы [ 7 ]

4 голосов
/ 15 июля 2009

Я думаю, что проблема будет заключаться в количестве вызовов отрисовки, а не в общей «скорости заполнения» всех пикселей, которые вы рисуете. Помните - это более 80000 звонков в секунду, которые вы должны сделать. Я думаю, что вашим самым большим улучшением будет как-то их объединить.

Одной из стратегий снижения скорости заполнения плиток и слоев является комбинирование статических областей вместе. Например, если вы знаете, что область не нуждается в обновлении, ее можно кэшировать. Многое зависит от того, прокручиваются ли слои независимо (стиль параллакса).

Кроме того, посмотрите в Google «грязные прямоугольники» и посмотрите, могут ли какие-либо схемы соответствовать вашим потребностям.

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

2 голосов
/ 15 июля 2009

Обязательно используйте альфа-прозрачность только для плиток, которые фактически используют альфа, и пропустите рисование пустых плиток. Убедитесь, что глубина цвета поверхности плитки соответствует глубине цвета экрана, когда это возможно (на самом деле это не вариант для плиток с альфа-каналом), и сохраняйте плитки в видеопамяти, чтобы sdl использовал аппаратное ускорение, когда это возможно. Прозрачность цветовых клавиш будет быстрее, чем наличие полного альфа-канала, для простых плиток, где частичная прозрачность или смешивание сглаженных краев с фоном не требуется.

В системе с частотой 500 МГц вы получите около 6,8 тактов процессора на пиксель на слой или 27 на пиксель экрана, чего (я считаю) будет недостаточно, если у вас есть полные альфа-каналы на каждом тайле каждого слоя , но должно быть хорошо, если вы берете ярлыки, подобные упомянутым, где это возможно.

1 голос
/ 07 декабря 2009

Можете ли вы просто буферизовать каждый полный слой в его вид плюс дополнительный размер плитки для всех четырех концов (если у вас вертикальная прокрутка), снова используйте буфер, чтобы создать новый буфер минус первый столбец и рисовать на новом конечном столбце ? Это уменьшит много ненужных перерисовок.

Кроме того, если вы хотите 60 кадров в секунду, вы можете найти способы создания методов пропуска кадров для более медленных систем, пропуская каждую другую или каждую третью фазу рисования.

1 голос
/ 15 июля 2009

Я согласен с Комбува. Если это простая 2D-игра на основе тайлов, вам действительно следует немного снизить стандарты, поскольку это не Crysis. 30FPS очень плавный (исследуй Command & Conquer 3, который ограничен 30FPS). Тем не менее, я написал программу для просмотра на удаленном рабочем столе, которая работала со скоростью 14FPS (1900 x 1200) с использованием GDI +, и она все еще была довольно гладкой. Я думаю, что с вашей 2D-игрой у вас, вероятно, все будет в порядке, особенно с использованием SDL.

0 голосов
/ 15 июля 2009

Вы можете рассмотреть возможность объединения соседних плиток с одинаковой текстурой в более крупный многоугольник с мозаичным размещением текстуры (что-то вроде процесса сборки).

0 голосов
/ 15 июля 2009

Я думаю, вы будете приятно удивлены тем, сколько таких плиток вы можете нарисовать за секунду. Современное графическое оборудование может заполнять кадровый буфер 1600x1200 много раз за кадр с частотой 60 кадров в секунду, поэтому кадровый буфер 640x480 не будет проблемой. Попробуйте и посмотрите, что вы получите.

Вы обязательно должны воспользоваться аппаратным ускорением. Это даст вам 1000-кратную производительность при минимальных усилиях с вашей стороны.

Если вам все-таки нужно оптимизировать, то самый простой способ - перерисовать только те области экрана, которые изменились со времени последнего кадра. Похоже, вам нужно знать о любых анимационных плитах и ​​любых плитах, которые изменили состояние каждого кадра. В зависимости от игры это может быть где угодно, от какой-либо выгоды до огромной экономии - это действительно зависит от того, сколько экрана меняет каждый кадр.

0 голосов
/ 15 июля 2009

Как насчет уменьшения частоты кадров до 30 кадров в секунду. Я думаю, что это будет достаточно для 2D-игры.

...