Просмотр
Материал из DoomDev
Страница «
ThingCount, использование
»
Перейти к:
навигация
,
поиск
[[Изображение:thingcount1.jpg|frame|center|Рисунок 1: Эти ужасные сержанты!]] На рисунке 1 показано, что произойдет, когда вы возьмете ружье на уровне-примере [http://zdoom.org/zdkb/thingcnt.zip thingcnt.wad] – в комнате появляются четыре сержанта. Чтобы немного помочь игроку, неплохо бы дать ему здоровья, после того как он разберется с ними. Это можно сделать при помощи функции thingcount. [[Изображение:thingcount2.gif|frame|center|/##<br> Monster Spawn Points = Точки появления монстров<br> Special Spawn Point = Точка появления аптечки<br> Shotgun w/ special = Ружье, имеющее спецификатор<br> ##/<br> Рисунок 2: План карты в WadAuthor]] На рисунке 2 показан план карты. Взятие ружья приводит к появлению сержантов. На рисунке 3 показаны настройки ружья. [[Изображение:thingcount3.gif|frame|center|Рисунок 3: Ружье, вызывающее скрипт]] Когда игрок берет ружье, вызывается скрипт 1, создающий четырех сержантов. На рисунке 4 показаны настройки точек появления сержантов (предметов-меток). [[Изображение:thingcount4.gif|frame|center|Рисунок 4: Настройки предмета-метки]] Каждый предмет-метка должен иметь собственное значение поля tag. Чтобы не усложнять пример, я сделал эти значения равными 1, 2, 3 и 4. Это упрощает написание скрипта. Основная же работа выполняется скриптом: #include “zcommon.acs” /* Эта переменная карты, то есть она доступна из всех его функций */ int cdone; /* Эти скрипты создают сержантов и заставляют код следить за количеством предметов. Код этого скрипта лишний раз подтверждает, что ACS является самым настоящим языком программирования. */ script 1 (void) { inti; // Переменная скрипта. Она видна только из этого скрипта. /* Далее написано: начать со значения 1 переменной i и выполнить Thing_Spawn для предмета-метки, имеющего tagi. Увеличить i на 1 (i++) и продолжать, пока i не достигнет 5. Затем выйти. */ i=1; while (i < 5) { Thing_Spawn(i, T_SHOTGUY, 192); i++; } // Теперь запускаем скрипт 2 следящий за количеством предметов. ACS_Execute(2, 0, 0, 0, 0); } //Этот скрипт будет работать непрерывно. script 2 (void) { int cc; // Если cdone не равен нулю, то мы закончили. if (cdone) Terminate; /* Пересчитывает сержантов, игнорируя их tag-и. */ cc = ThingCount(T_SHOTGUY, 0); // Если все сержанты мертвы, создаем аптечку. if (cc==0) { Thing_Spawn(5, T_MEDKIT, 0); cdone=1; } /* Так как мы хотим зациклить этот скрипт, то создаем задержку, чтобы избежать ошибки runaway script error (неконтролируемый скрипт). */ Delay (70); // 2 секунды. // Начинаем сначала, друг :) пока cc = 0. Restart; } Первое, что нам нужно – создать сержантов в скрипте 1. Следующий код перебирает предметы-метки и в их местоположении создает сержантов: i=1; while (i < 5) { Thing_Spawn(i, T_SHOTGUY, 192); i++; } Именно поэтому предметы-метки пронумерованы последовательно. Так как мы использовали #include “zcommon.acs”, мы можем использовать легкочитаемое имя для сержанта: T_SHOTGUY. Вспомним предыдущие уроки: первым параметром [[Thing_Spawn]] является id предмета-метки, а вторым – ориентация предмета. Поэтому, конечно, сержанты будут смотреть на игрока. В данном коде начальное значение i равно 1. Функция Thing_Spawn создает сержанта в местоположении предмета-метки, имеющей tag 1. i++ увеличивает переменную i на 1, а затем все начинается сначала. Как движок узнает, что именно повторять? Повторно выполняющаяся часть заключена между фигурными скобками ({}). Пока i меньше пяти, выполняются все команды между фигурными скобками. Когда i становится равным 5, программа выходит из цикла [[while]]. Затем скрипт 1 вызывает скрипт 2: ACS_Execute(2, 0, 0, 0, 0); Теперь скрипт 1 сделал свою работу и сделал её до конца. J Цель скрипта 2 очень проста – ждать, когда будут убиты все сержанты. Когда это произойдет, скрипт создаст аптечку в местоположении предмета-метки 5. Этот скрипт будет работать безостановочно, каждые несколько секунд проверяя, сколько осталось сержантов. Он выглядит сложнее, чем есть на самом деле. // Если cdone не равен нулю, то мы закончили. if (cdone) Terminate; Этот код проверяет, не создал ли скрипт уже аптечку. Когда создается аптечка, устанавливается флаг. Если бы этой проверки не было, то скрипт создавал бы аптечку каждые две секунды после смерти сержантов. cc = ThingCount(T_SHOTGUY, 0); Этот код возвращает количество сержантов, находящихся в данный момент на карте. [[ThingCount]](Тип, Tag) * Тип – Что пересчитывать. Это те же id, что используются в [[Thing_Spawn]]. * Tag – Пересчитывать предметы имеющие данный tag. Один из этих параметров может быть равен нулю. В этом случае движок игнорирует соответствующий параметр подсчета. Например, чтобы пересчитать всех сержантов, параметр tag должен быть равен нулю. Если тип равен нулю, но указан tag, то пересчитываем все предметы, имеющие указанный tag, вне зависимости от их типа. if (cc==0) { Thing_Spawn(5, T_MEDKIT, 0); cdone=1; } Когда число сержантов становится равным нулю, выполняет приведенный выше код. Скрипт создает аптечку в местоположении предмета-метки 5. Так как ориентация в данном случае не имеет значение, то соответствующий параметр равен нулю. Когда аптечка создана, работа скрипта заканчивается и устанавливается соответствующий флаг. Вспомните, в начале скрипта проводилась проверка на неравенство нулю переменной cdone. Когда cdone становится равной 1, скрипт завершается. Delay (70); // 2 секунды. Restart; Однако, пока количество сержантов не равно нулю, мы продолжаем считать. Приведенный отрывок просто создает задержку в две секунды, а затем перезапускает скрипт. Задержка (при помощи оператора Delay) очень важна. Без нее произойдет ошибка run away script (неконтролируемый скрипт), и движок завершит скрипт. Эта задержка позволяет другим скриптам получить время процессора (как DoEvents в VB). Randy прислал мне упрощенную версию моего скрипта: script 1 (void) { // Thing_Spawn создает сержантов в местоположении всех предметов-меток, имеющих id 1. Thing_Spawn (1, T_SHOTGUY, 192); while (thingcount (T_SHOTGUY, 0)) { delay (70); } Thing_Spawn (5, T_MEDKIT, 0); } Как видете, все выполняется одним скриптом. Обратите внимание, что все предметы-метки (кроме 5-ой) имеют одинаковый tag 1 и, следовательно, нужна только одна команда Thing_Spawn. Кроме того, в цикл while помещена задержка; до тех пор, пока thingcount возвращает значение большее 0, цикл выполняется. Когда thingcount вернет 0, цикл while завершится и будет создана аптечка. Очень лаконично. Спасибо Randy. {{RCTutorial}}
Шаблон:RCTutorial
Возврат к странице
ThingCount, использование
.
Просмотры
Статья
Обсуждение
Просмотр
История
Личные инструменты
Представиться системе
Навигация
Заглавная страница
Сообщество
Текущие события
Свежие правки
Случайная статья
Справка
Поиск
Инструменты
Ссылки сюда
Связанные правки
Загрузить файл
Спецстраницы