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

Существуют различные методы создания программ. При разработке сверху вниз сначала намечают структуру программы, определяют набор процедур, распределение их по модулям и только потом переходят к программированию. Так, как правило, делают все крупные проекты, причем можно заранее распределить весь объем работ между несколькими программистами. Однако при таком подходе требуется написать немало текста, прежде чем может быть откомпилирована первая исполняемая программа, ведь для каждой процедуры к данному моменту уже должна быть написана как минимум заглушка:

Procedure ProcName;
Begin
End;

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

До сих пор все операции, выполняемые над спрайтами, находились в теле основной программы. Пора наконец вынести их в отдельный модуль. В предыдущих статьях в основном были приведены не полные листинги, а только их изменения (подробные тексты есть по адресу www.pcworld.ru). Если же изменения затрагивают почти весь текст модуля, то, конечно, следует привести его целиком. Поэтому целесообразно совместить переделку программы на вывод нескольких спрайтов с ее декомпозицией, а также привести полные листинги довольно сильно сократившейся основной программы (листинг 1) и нового модуля, названного sprites и выполняющего все действия над спрайтами (листинг 2).

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

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

Цикл 1 по спрайтам от дальнего до ближнего:

  • cохранить фон;
  • вывести спрайт;
  • конец цикла.

Последующее восстановление фона должно происходить в обратном порядке.

Цикл 2 по спрайтам от ближнего до дальнего:

  • восстановить фон;
  • конец цикла.

Зритель должен видеть экран со спрайтами, а не пустой фон, поэтому следует минимизировать время от начала цикла 2 до конца 1-го. Другими словами, все дополнительные операции (вычисление координат спрайтов, реакция на органы управления и т. п.), а также обеспечение синхронизации следует располагать в теле основного цикла между концом цикла 1 и началом цикла 2.

Вместо единственного спрайта введен массив, и кроме того, изменен способ обращения ко всем процедурам работы со спрайтом. Теперь необходимо указать процедуре, с каким именно спрайтом мы хотим работать.

Перед тем как запускать новую программу, требуется нарисовать с помощью графического редактора изображение еще одного спрайта и сохранить его на диске под именем sprt02.bmp.

Итак, на экране присутствуют два спрайта. А можно больше? Да!

Чтобы для работы этой демонстрационной программы не пришлось рисовать несколько сотен спрайтов, применена маленькая хитрость. Вы, наверное, обратили внимание, что в листинге при определении имен файлов спрайтов переменная NumSprites «закомментирована», а вместо нее указано число 2. Сами же спрайты создаются в цикле:

for i := 1 to NumSprites do
CreateSprite(NameSprt[(i mod 2)+1],random(320
-Xsize),random(200-Ysize),1,1,Sprt[i]);
где вместо i используется (i mod 2)+1.

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

Теперь можно увеличить количество спрайтов и посмотреть, что же произойдет. Здесь надо быть внимательным, ведь программа написана для среды DOS и может использовать примерно 450—500 Кбайт памяти, причем независимо от того, сколько ее установлено в ПК. Сейчас спрайт занимает два поля по 400 байт, т. е. около 0,78 Кбайт. В зависимости от производительности компьютера советую установить от 100 до 500 спрайтов.

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


Листинг 1

Листинг 2