Как мне создать уровни в игре с автоматической прокруткой? - PullRequest
0 голосов
/ 08 января 2012

Я работаю над 2D Shmup, и идея в том, что уровень непрерывно прокручивается автоматически, и ваш персонаж может перемещаться по экрану.

Теперь у меня проблемы с выяснением, как бы я это реализовал, и Google не помог. Прямо сейчас у меня есть фон прокрутки (положение фона просто уменьшается для каждого кадра), и игрок может свободно перемещаться по окну, но как мне будет создавать объекты на уровне? Буду ли я использовать таймер для запуска объектов и врагов или есть способ сделать это на основе положения / ширины фона (я бы предпочел второй метод ... Но я понятия не имею, как это будет сделано)

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

Ответы [ 2 ]

2 голосов
/ 08 января 2012

Я бы порекомендовал либо:

  • Использовать физические триггеры
  • Использовать список синхронизированных событий

Физические триггеры

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

Это было бы проще поддерживать в редакторе уровней, посколькуфизическая природа очень проста для визуализации.

Временные события

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

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

Комбинация обоих

Вы также можете сделать какое-то их сочетание, чтобы получить преимущества обоих стилей: Более простая визуализация / уровеньредактирование и поддержка секций без прокрутки или событий на основе времени.

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

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

Как определить, что на экране отображается триггер

Сначала следует реализовать прокрутку.

Если у вас есть прокрутка, вычислите прямоугольник, который соответствует расположению экрана в вашей системе координат пиксель / мир.Это даст вам «ограничивающую рамку» экрана.

Отсюда выполните тест пересечения между «ограничительной рамкой» вашего триггера событий и экраном.

Вот тест, чтобы увидетьесли есть любое перекрытие между двумя прямоугольниками.Это не зависит от заказа:

rect1.left < rect2.right && rect1.right > rect2.left
    && rect1.top < rect2.bottom && rect1.bottom > rect2.top

Если касания касаются вообще, то вернется true.

Вот тест, чтобы убедиться, что rect1 содержит rect2.Порядок важен:

rect1.left <= rect2.left && rect1.right >= rect2.right
    && rect1.top <= rect2.top && rect1.bottom >= rect2.bottom

Если rect2 полностью содержится в rect1 (он полностью отображается на экране), он вернет true.

Как реализовать простые таймеры

Просто получите какое-то значение часов (может быть SDL_GetTicks) и сохраните это значение.

Чтобы узнать, сколько времени прошло с момента запуска таймера, позвонитефункцию снова и вычтите.Сравните значения с <, чтобы увидеть, больше ли разница, чем целевое время.

0 голосов
/ 08 января 2012

К сожалению, здесь вы должны использовать указатели. Что-то вроде:

vector<BadGuy*> Listofbaddies;

//Place enemy just off screen
newYposition = SCREEN_HEIGHT + 20;

//an infinite (almost) amount of badguys can be created with this code:
Listofbaddies.push_back(new Badguy(newXposition,
                                   newYposition,
                                   EnemyType,
                                   blahblah);

Это означает, что злоумышленнику понадобится такой конструктор, как:

Badguy::Badguy(float newX, float newY, string Type, whateverelseyouwant){

actualSpritePartOfBadguyClass.setPosition(newX, newY);
}

Это имеет смысл? Я уточню, если вы спросите: D Сейчас я делаю игру, в которой используется нечто подобное:

...