Контролы, или объектно-событийная модель игрового мира
Каждый миг жизни наполнен какими-то событиями. События происходят вокруг нас,
они могут происходить, на первый взгляд, сами по себе, а могут быть явным следствием
каких-то причин. Однако, как бы не казалось "на первый взгляд", все
события имеют какую-либо причину. Даже если вспомнить теорию "Большого
взрыва", то можно предположить, что все, что происходит с нами сейчас,
есть не что иное, как следствие этой самой "первопричины". Существует
такая умозрительная теория, что если знать состояние всех частиц в какой-то
момент времени, то можно предсказывать будущее…
Итак, что, исходя из этого, можно придумать применительно к нашей задаче, а
именно, к написанию игр?
Сделаем предположение, что всю игровую ситуацию можно описать как набор неких
событий, многие из которых уже произошли, а возможно - еще только собираются
произойти. Также сделаем предположение, что в нашей игре все возможные основные
события уже заложены в память компьютера, так что будет несложно прийти к выводу,
что в игре все события наступают вследствие "наступления" неких "родительских"
событий. И всю игровую логику можно представить именно в этих терминах. Вообще
текущее положение дел в игре можно условно разделить на две части - низкоуровневую,
куда будут входить, скажем, положения спрайтов на экране, текущие настройки
пользовательского интерфейса, характеристики персонажей, и высокоуровневую,
то есть, общее логическое состояние сюжетной линии игры, по которой можно сказать,
где игрок находится в данный момент - в середине игры, или же в ее начале, в
самом конце ее или же еще только осваивается с первыми игровыми заданиями.
Вот тут мы подошли к одному из ключевых понятий, к "квесту". Что
это такое? Это одновременно и жанр игры типа "приключение", и понятие
помельче, означающее некое игровое задание, например, принести из Очень Темного
Леса Очень Сладкое Яблочко игровому персонажу. При написании игры этого жанра
необходимо решать непростую задачу - каким-то образом учитывать исполнение заданий
и выдача очередных поручений на основании уже решенных головоломок. Для этого
и можно воспользоваться понятием "событие".
Каждый раз, когда игрок делает что-либо, происходит череда событий. Вот он
нажал на клавишу - событие. Вот он убил страшного монстра - событие. Вот пошевелил
мышью - тоже событие! Так какие же из них нам надо учитывать? Будь у нас Абсолютный
Суперкомпьютер, способный заменить Реальность, мы бы на каждый квант времени
"повесили" бы ярлык "событие" и со скоростью света обрабатывали
бы все их, получив результате еще одну, вполне реальную Вселенную. Однако у
нас всего лишь жалкий третий Пентиум! Очевидно, что нас не интересуют мелочи!
Мы собрались писать игру, а это значит, что мы умеем выделять главное и не обращать
внимания на частности (или должны уметь…). Поэтому под событием будем
понимать нечто значительное, например, выполнение квеста.
Для того чтобы работать в подобном, событийном мире, надо иметь возможность
оперировать некими объектами, как и в любой подобной ситуации. Само собой напрашивается
решение - объекты будут являться событиями. То есть, это некие control-object-ы,
или, попросту. "контролы".
Для этого введем класс объектов, которые содержат в себе два основных метода
- int control_activate() и int control_run(). Идея состоит в том,
чтобы контрол мог "сработать" в определенной ситуации, то есть выполнить
функцию control_run(). Для того чтобы контрол выполнил эту функцию, необходим
"положительный" ответ от функции control_activate(). Функция control_activate()
содержит в себе логическое выражение от некоего набора контролов, каждый из
которых может возвращать количество срабатываний . А функция control_run()
в ответ увеличит на 1 счетчик собственных срабатываний и выполнит какие-либо
действия, предусмотренные сюжетом.
Пример:
Надо выполнить квест - убить хотя бы десять монстров в лесу, тогда старейшина
деревни даст амулет.
int control_activate0000()
{
return TRUE;
}
int control_run0000()
{
return TRUE;
}
int control_activate0001()
{
if(Control(0) >= 10) return TRUE;
return FALSE;
}
int control_run0001()
{
Say("Молодец, ты справился с заданием!");
GiveItToPlayer(ARTEFACT_AMYLET);
return TRUE;
}
Как видно, для каждого контрола надо писать отдельные функции. Их лучше всего
исполнить в виде скрипт-модулей, благо на сегодняшний день в интернете есть
множество бесплатных и свободно распространяемых скрипт-интерпретаторов. Генерировать
функции контролов лучше всего автоматически в редакторе локации, разве что потом
дополнять их вручную.
С помощью контролов можно решать самые разные задачи - от выполнения квестов
до управления всевозможными триггерами/ловушками, дверьми и т.д., все, работу
чего можно рассматривать как событие.
Жанровая принадлежность игры тут не играет особой роли, так как выполнение заданий
есть в любом жанре - в квестах, аркадах, РПГ. 3D-action…
Фролов Андрей ака FAL.
falinc@yahoo.com
2000-12-25
|
 |
 |
|