Я пытаюсь разработать старую школьную видеоигру в стиле NES с мерцанием спрайтов и графическим замедлением. Я думал о том, какой тип логики я должен использовать для включения таких эффектов.
Я должен учитывать следующие ограничения, если я хочу пойти в стиле старой школы NES:
- Не более 64 спрайтов на экране за раз
- Не более 8 спрайтов на строку сканирования или для каждой строки по оси Y
- Если на экране происходит слишком много действий, система замерзает изображение для кадра, чтобы процессор мог догнать действие
Из того, что я прочитал, если на экране было больше 64 спрайтов, разработчик будет рисовать только высокоприоритетные спрайты, игнорируя при этом низкоприоритетные. Они также могут чередовать, рисуя каждый четный спрайт на противоположных кадрах из нечетных номеров.
Вопрос о сканировании интересен. Из моего тестирования невозможно получить хорошую скорость на XBOX 360 XNA, рисуя пиксели по пикселям, как это сделала NES. Вот почему в школьных играх, если в одной строке было слишком много спрайтов, некоторые появлялись бы, если бы их сокращали вдвое. Для всех целей для этого проекта я делаю сканированные линии высотой 8 пикселей и группирую спрайты на каждой линии сканирования по их позиционированию Y.
Чтобы уточнить, я бы рисовал спрайты на экране партиями размером 8x8 пикселей, а не 1x1.
Итак, ошарашенный, мне нужно найти решение, которое...
- 64 спрайтов на экране сразу
- 8 спрайтов на 'scanline'
- Может рисовать спрайты на основе приоритета
- Может чередоваться между спрайтами на кадр
- Эмуляция замедления
Вот моя нынешняя теория
Прежде всего, основная идея, которую я придумал, - это приоритет спрайта. Если предположить, что значения между 0-255 (0 являются низкими), я могу назначить уровни приоритетов спрайтов, например:
- От 0 до 63
- От 63 до 127 - средний.
- От 128 до 191
- Максимум от 192 до 255
В моих файлах данных я могу назначить каждый спрайт определенным приоритетом. Когда родительский объект создается, спрайт произвольно получает назначенное число между его назначенным диапазоном. Затем я рисую спрайты по порядку от высокого к низкому, с конечной целью рисования каждого спрайта.
Теперь, когда спрайт нарисован в кадре, я тогда произвольно сгенерировал бы его новое значение приоритета в пределах его начального уровня приоритета. Однако, если спрайт не получается рисоваться в кадре, я мог бы добавить 32 к его текущему приоритету. Например, если система может только рисовать спрайты до уровня приоритета 135, тогда спрайт с начальным приоритетом 45 может быть нарисован после того, как 3 кадра не будут оттянуты (45 + 32 + 32 + 32 = 141)
Это теоретически позволило бы спрайтам чередовать кадры, разрешать уровни приоритетов и ограничивать спрайты до 64 на экран.
Теперь интересный вопрос заключается в том, как ограничить спрайты только 8 на строку сканирования?
Я думаю, что если я сортирую приоритеты спрайтов с низким приоритетом, перебираю цикл, пока не удалю 64 спрайта. Однако я не должен просто взять первые 64 спрайтов в списке.
Прежде чем рисовать каждый спрайт, я мог бы проверить, сколько спрайтов было нарисовано в соответствующей строке с помощью счетных переменных. Например:
- Значения Y от 0 до 7 относятся к Scanline 0, scanlineCount [0] = 0
- Значения Y от 8 до 15 относятся к Scanline 1, scanlineCount [1] = 0
- и др.
Я мог бы reset значения для каждой строки сканирования для каждого кадра. При смене списка спрайтов добавьте 1 к соответствующему счетчику scanline, если спрайт будет нарисован в этой строке сканирования. Если он равен 8, не рисуйте этот спрайт и перейдите к спрайту со следующим низким приоритетом.
Slowdown
Последнее, что мне нужно сделать, это эмулировать замедление. Моя первоначальная идея заключалась в том, что если я рисую 64 спрайта на кадр и еще больше спрайтов, которые нужно нарисовать, я могу приостановить рендеринг на 16 мс или около того. Тем не менее, в играх NES, которые я играл, иногда наблюдается замедление, если не происходит мерцания спрайтов, в то время как игра прекрасно перемещается, даже если есть какое-то мерцание спрайтов.
Возможно, дайте значение каждому объекту, который использует спрайты на экране (например, значения приоритета выше), и если объединенные значения всех объектов w/спрайтов превышают порог, введите замедление?
В ЗАКЛЮЧЕНИИ...
Разве все, что я написал, на самом деле звучит законно и может работать, или это мечта? Какие улучшения вы можете подумать с этой теорией программирования игр?