что такое скрипты в играх

Что такое скрипты в играх

При создании игры скрипты используются во многом так же, как кинорежиссер использует сценарий — для контроля каждого аспекта вашего «произведения». Игровые скрипты подобны программному коду, который вы пишете, когда создаете игру, за исключением того, что скрипты являются внешними по отношению к игровому движку. Поскольку они внешние, вы можете быстро изменить скрипт не компилируя заново весь игровой движок. Вообразите себе проект, в котором больше миллиона строк кода, и вам надо компилировать весь этот проект заново только для того, чтобы изменить одну строку в диалоге!

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

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

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

Поскольку моей целью было как можно быстрее предоставить вам работающий скриптовый движок, я выбрал использование второго типа скриптовой системы. Эта система, которую я назвал Mad Lib Scripting, работает используя набор предопределенных команд, называемых действия (actions), с каждым из которых связана игровая функция. Возьмем, для примера, действия из таблицы 10.1 — у каждого действия есть конкретная выполняемая функция.

Таблица 10.1. Примеры команд действий

ДействиеФункция
PrintПечатает строку текста на экране.
EndЗавершает выполнение скрипта.
Move CharacterПеремещает указанный персонаж в заданном направлении.
Play SoundВоспроизводит указанный звуковой эффект.

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

Для примера скажем, что действию Play Sound соответствует номер 4, и действие требует единственного параметра — номера воспроизводимого звука. В скрипте вам потребуется сохранить только два числа: одно для действия, и одно, представляющее звук. Использование чисел для представления действий (вместо текста) делает обработку скриптов такого типа быстрой и простой.

Источник

Что такое скрипты и с чем их едят — Lua & C++

Добрый день, Хабрахабр!
Решил написать этот топик на тему скриптов

что такое скрипты в играх. Смотреть фото что такое скрипты в играх. Смотреть картинку что такое скрипты в играх. Картинка про что такое скрипты в играх. Фото что такое скрипты в играх

Что нужно знать?

Но есть способ, на голову выше — использование скриптов.

Решение проблемы

«Окей, для таких дел хватает обычного файла с описанием характеристиков игрока. Но что делать, если в бурно развивающемся проекте почти каждый день приходится немножко изменять логику главного игрока, и, следовательно, много раз компилировать проект?»
Хороший вопрос. В этом случае нам на помощь приходят скрипты, держащие именно логику игрока со всеми характеристиками либо какой-либо другой части игры.
Естественно, удобнее всего держать, логику игрока в виде кода какого-нибудь языка программирования.
Первая мысль — написать свой интерпретатор своего скриптового языка, выкидывается из мозга через несколько секунд. Логика игрока определенно не стоит таких жутких затрат.
К счастью, есть специальные библиотеки скриптовых языков для С++, которые принимают на вход текстовый файл и выполняют его.

Об одном таком скриптовом языке Lua пойдет речь.

Как это работает?

Прежде чем начать, важно понимать, как работает скриптовый язык. Дело в том, что в скриптовых языках есть очень мало функций, при наличии конструкций for, while, if, прочих.
В основном это функции вывода текста в консоль, математические функции и функции для работы с файлами.
Как же тогда можно управлять игроком через скрипты?

Мы в С++-программе делаем какие-либо функции, «регистрируем» их под каким-нибудь именем в скрипте и вызываем в скрипте. То есть если мы зарегистрировали функцию SetPos(x,y) для определения позиции игрока в С++-программе, то, встретив эту функцию в скрипте, «интерпретатор» из библиотеки скриптового языка вызывает эту функцию в С++-программе, естественно, с передачей всех методов.
Удивительно, да? 🙂

UPD: Внимание! Один юзер обратился мне с мейлом, что, когда я заливал код, я не полностью устранил все ошибки — habrahabr.ru/post/196272/#comment_6850016
В коде с позволения хабра проникли жучки
Замените участки кода вроде

И еще вместо lua_CFunction проскакивает lua_cfunction
Спасибо!

Я готов!

Когда вы поняли преимущества скриптовых языков программирования, самое время начать работать!
Скачайте из репозитория на гитхабе (низ топика) lib’у и includ’ы Lua, либо возмите их на официальном сайте.

Создаем консольный проект либо Win32 (это неважно) в Visual Studio (у меня стоит версия 2012)

Заходим в Проект->Свойства->Свойства конфигурации->Каталоги VC++ и в «каталоги включения» и «каталоги библиотек» добавьте папку Include и Lib из репозитория соответственно.

Теперь создаем файл main.cpp, пишем в нем:

Как вы догадались, у меня консольное приложение.

Теперь переходим к кодингу

Обещаю, что буду тщательно объяснять каждый момент

У нас за скрипты будет отвечать класс Script. Я буду объявлять и одновременно реализовывать функции в Script.h/.cpp
Создаем Script.cpp и пишем в нем

Создаем Script.h и пишем в нем

После 2 строчки и перед #endif мы определяем класс скриптов
Этот код пишется для предотвращения взаимного включения файлов. Допустим, что файл Game.h подключает Script.h, а Script.h подключает Game.h — непорядок! А с таким кодом включение выполняется только 1 раз

Теперь пишем внутри этого кода вот это

Первая строчка подключает сам lua.lib из архива.
Для чего нужен extern «C»? Дело в том, что lua написан на С и поэтому такой код необходим для подключения библиотек.

Дальше идет подключение хорошо известных многим файлов для работы с консолью

Теперь приступим к определению класса

Самый главный объект библиотеки Lua для C++ — lua_State, он необходим для выполнения скриптов

Дальше идут публичные функции

Эта функция инициализирует lua_State

Его определение в Script.cpp

Первой строчкой мы инициализируем наш lua_State.
Потом мы объявляем список «подключенных библиотек». Дело в том, что в «чистом» виде в луа есть только функция print(). Для математических и прочих функций требуется подключать специальные библиотеки и потом вызывать их как math.foo, base.foo, io.foo. Для подключения других библиотек добавьте в lualibs, например, <«math», luaopen_math>. Все названия библиотек начинаются с luaopen_. в конце lialibs должен стоять

Просто используем lua_close()

А эта функция выполняет файл. На вход она принимает название файла, например, «C:\\script.lua».
Почему она возвращает int? Просто некоторые скрипты могут содержать return, прерывая работу скрипта и возвращая какое-нибудь значение.

Как вы видите, я выполняю скрипт и возвращаю int. Но возращать функция может не только int, но еще и bool и char*, просто я всегда возвращаю числа (lua_toboolean, lua_tostring)

Теперь мы сделаем функцию, регистрирующую константы (числа, строки, функции)

Мы действуем через шаблоны. Пример вызова функции:
Ее определение

Для каждого возможного значения class T мы определяем свои действия.
*Капитан* последнее определение — регистрация функции
Функции, годные для регистрации, выглядят так:

Где n — количество возвращаемых значений. Если n = 2, то в Луа можно сделать так:

Читайте мануалы по Луа, если были удивлены тем, что одна функция возвращает несколько значений 🙂

Следующая функция создает таблицу для Луа. Если непонятно, что это значит, то тамошная таблица все равно что массив

Следующая функция регистрирует элемент в таблице.

Если вы не знаете Lua, вы, наверное, удивлены тем, что в один массив помещается столько типов? 🙂
На самом деле в элементе таблицы может содержаться еще и таблица, я так никогда не делаю.

Наконец, заполненную таблицу нужно зарегистрировать

Ничего особенного нет

Следующие функции предназначены в основном только для функций типа int foo(lua_State*), которые нужны для регистрации в Луа.

Первая из них — получает количество аргументов

Эта функция нужна, например, для функции Write(), куда можно запихать сколь угодно аргументов, а можно и ни одного
Подобную функцию мы реализуем позже

Следующая функция получает аргумент, переданный функции в скрипте

Можно получить все типы, описывавшиеся ранее, кроме таблиц и функций
index — это номер аргумента. И первый аргумент начинается с 1.

Наконец, последняя функция, которая возвращает значение в скрипт

Боевой код

Пора что-нибудь сделать!
Изменяем main.cpp

Компилируем. Теперь можно приступить к тестированию нашего класса

Помните, я обещал сделать функцию Write? 🙂
Видоизменяем main.cpp

А в папке с проектом создаем файл script.lua

что такое скрипты в играх. Смотреть фото что такое скрипты в играх. Смотреть картинку что такое скрипты в играх. Картинка про что такое скрипты в играх. Фото что такое скрипты в играх

Компилируем и запускаем проект.

что такое скрипты в играх. Смотреть фото что такое скрипты в играх. Смотреть картинку что такое скрипты в играх. Картинка про что такое скрипты в играх. Фото что такое скрипты в играх

Теперь изменяем script.lua

Теперь программа будет выводить по 2 строки («\n» — создание новой строки), ждать нажатия Enter и снова выводить строки.

что такое скрипты в играх. Смотреть фото что такое скрипты в играх. Смотреть картинку что такое скрипты в играх. Картинка про что такое скрипты в играх. Фото что такое скрипты в играх

Экспериментируйте со скриптами!

Вот пример main.cpp с функциями и пример script.lua

Полезные советы
Вопросы и ответы

Источник

Игровое программирование. Уроки скриптописания

Для многих начинающих игростроевцев, которые уже собирают свою команду, чтобы слепить на коленке очередной шедевр, программирование часто видится жутким монстром, с которым непонятно как бороться. Вроде и в 3D уже рисовать умеют, и в Photoshop кисточкой сноровисто работают, и другие полезные программы неплохо знают. Но как только дело доходит до кода, начинается паника и неразбериха: “ Кто спрограммирует? Кто напишет заветные строчки? А если и напишет, то как в них потом разобраться?! ”.

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

Установка среды разработки

Классы игры и иерархия

Распаковка игровых скриптов

Настройка среды разработки

В ООП существуют три основных принципа, на которых строятся практически все логические манипуляции с объектами.

Инкапсуляция — объединение внутри объекта данных с методами для их обработки. Например, если рассматривается класс “Лампочка”, то у него должны быть методы “включить свет” и “выключить свет”.

Наследование — создание класса объектов на основе уже существующего класса. При этом создаваемый класс будет не только содержать все данные и методы базового класса, но и обладать своими собственными. Методы базового класса могут быть переопределены. Примеры наследования и переопределения: если класс “Пегас” наследуется от класса “Лошадь”, то у первого появляется новое свойство — “крылья” и соответствующий метод “махать крыльями”. Все остальное у этих двух классов одинаковое. Если мы рассмотрим класс “Русалка”, основанный на классе “Человек”, то в данном случае будет иметь место переопределение свойства “ноги” на “рыбий хвост”, а метод “двигаться” будет вместо движения ног отвечать за перемещение хвоста.

Полиморфизм — что это такое, проще всего рассмотреть на конкретном примере. Рассмотрим два класса объектов — “Пегас” и “Лошадь”. Полиморфизм заключается в том, что мы можем рассматривать любого пегаса как лошадь и, например, у обоих объектов выполнять метод “кушать траву” или “бежать галопом”.

Многие начинающие программисты не различают понятия “класс” и “объект”. Но при этом эти два понятия различаются примерно так же, как и, скажем, чертеж устройства и готовое устройство в магазине. В жизни их спутать трудно.

Создание проекта

К сожалению, в UDE кнопка “Создать новый проект” отсутствует. Поэтому создаем в корневой папке UT2004 файл CreateNewClass.bat с командами:

echo class %pkg% extends //base class>> %pkg%\Classes\%pkg%.uc

Значение переменной pkg — это имя нашего проекта (в данном случае — Megakiller ). Остальные строки генерируют “пустой” скрипт.

Идея модификации

Перед изучением нижеследующей информации настоятельно рекомендуется изучить текстовый блок “ Анатомия Unreal-класса ”.

Внимание! Читая нижеследующие абзацы, смотрите соответствующие строки в листинге кода, приведенном на отдельной странице (номера строк указаны слева от кода).

Класс оружия

Рис. 1. Диалог создания дерева классов и архивов.

Класс альтернативной стрельбы

Рис. 2. Окна с деревом классов и списком архивов.

В начале файла объявляем несколько новых свойств для объектов класса ( строки 2-5 ): визуальный тип взрыва ( ExplosionClass ), визуальный тип следа от взрыва, например на стенах ( ExplosionDecalClass ). Тип луча при альтернативной стрельбе ( BeamEffectClass ) и радиус поражения при взрыве ( DamageRadius ).

Рис. 3. Диалог создания подкласса.

Классы повреждения

Рис. 4. Окно компиляции.

Класс игрового мутатора

— просто лежать на карте ( строка 15 ). Тут нам помогает класс WeaponPickup ( строка 15 ). Подмена осуществляется функцией ReplaceWith ( строка 19 ).

Рис. 5. Сообщение об ошибке и справка.

Дуэли на «Мегакиллерах» иногда превращают обычный бой в феерическое зрелище.

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

Местные леди способны просто-таки заряжать вас энергией!

Каждый Чебурашка мечтает о большой пушке!

Компиляция и тестирование

Для того чтобы вы сразу могли оценить действие мутатора и поиграть в него, мы выкладываем полную версию “Мегакиллера” на наш диск.

Принципы объектно-ориентированного программирования

Класс игры имеет унифицированную архитектуру. Структура файла следующая.

— Заголовок, содержащий объявление класса:

class ClassName extends BaseClass config(user); где ClassName — название нашего класса, BaseClass — базовый класс, на основе которого создается новый класс, config(user) — пример параметра в объявлении класса — указывает, что используются конфигурационные параметры из файла User.ini. Все игровые классы имеют в качестве родительского класс Object или любой из его классов-потомков. Лексемы class и extends являются зарезервированными обязательными атрибутами объявления игрового класса. Важно запомнить, что корректным является только тот uc-файл, имя которого совпадает с названием объявленного в нем класса. И в одном uc-файле должен быть описан только один класс.

— Объявления новых переменных (свойств класса) в следующем формате:

PropertyName; или var() SimpleType PropertyName; где PropertyClass — название класса создаваемого свойства, SimpleType — элементарный тип, такой как byte (байтовое значение от 0 до 255), int (знаковый целый тип), bool (логический тип), float (знаковый вещественный тип), string (символьная строка) и т.д. (полный список элементарных типов можно посмотреть в справке UDE), PropertyName — имя нового свойства.

— Объявления новых методов или переопределение унаследованных от базового класса имеют следующий вид:

— Задание параметров (свойств) по умолчанию класса:

defaultproperties где defaultproperties — лексема, указывающая начало блока свойств, Variable1Name — название свойства, представляющего собой некоторый другой объект класса ClassName, содержащегося в u-файле с именем Package. Параметр Variable2Name имеет элементарный тип, поэтому и присваиваемое значение Variable2Value должно иметь тот же тип. Символ «=» означает операцию присвоения значения справа переменной слева. Фигурные скобки обособляют в коде блок присвоений.

Вот и подошел к концу наш первый экскурс в мир игрового программирования. Мы не только сделали интересный мутатор, но и научились читать несложный программный код. В одном из ближайших номеров “Мании” мы продолжим разбираться в азах программирования и, изучив более продвинутые строки кода, создадим более сложный мутатор.

Источник

Что такое скрипт в играх

При создании игры скрипты используются во многом так же, как кинорежиссер использует сценарий — для контроля каждого аспекта вашего «произведения». Игровые скрипты подобны программному коду, который вы пишете, когда создаете игру, за исключением того, что скрипты являются внешними по отношению к игровому движку. Поскольку они внешние, вы можете быстро изменить скрипт не компилируя заново весь игровой движок. Вообразите себе проект, в котором больше миллиона строк кода, и вам надо компилировать весь этот проект заново только для того, чтобы изменить одну строку в диалоге!

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

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

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

Поскольку моей целью было как можно быстрее предоставить вам работающий скриптовый движок, я выбрал использование второго типа скриптовой системы. Эта система, которую я назвал Mad Lib Scripting, работает используя набор предопределенных команд, называемых действия (actions), с каждым из которых связана игровая функция. Возьмем, для примера, действия из таблицы 10.1 — у каждого действия есть конкретная выполняемая функция.

Таблица 10.1. Примеры команд действий

Анатомия Unreal-класса
ДействиеФункция
PrintПечатает строку текста на экране.
EndЗавершает выполнение скрипта.
Move CharacterПеремещает указанный персонаж в заданном направлении.
Play SoundВоспроизводит указанный звуковой эффект.

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

Для примера скажем, что действию Play Sound соответствует номер 4, и действие требует единственного параметра — номера воспроизводимого звука. В скрипте вам потребуется сохранить только два числа: одно для действия, и одно, представляющее звук. Использование чисел для представления действий (вместо текста) делает обработку скриптов такого типа быстрой и простой.

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

Коротенькая справочка или напоминание, это для кого как. Языки программирования делятся на две большие группы – компилируемые и интерпретируемые.

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

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

Основное преимущество компилируемых программ по сравнению с интерпретируемыми, это скорость работы. Иногда эта скорость может быть выше на несколько порядков! Интерпретаторы, безусловно, будут работать медленнее, так как им приходится делать много побочной работы помимо выполнения основной программы. А ведь скорость выполнения программы для нас очень важна, особенно если мы создаем игру! Мы ведь не хотим видеть дергающихся и тормозящих персонажей, тем более слайд-шоу! Для нас ведь важно, будет созданный нами персонаж реагировать через 1 миллисекунду или только через 10 секунд.

Зачем нам вообще использовать интерпретируемый язык программирования для создания игр? И можно ли его использовать в принципе? Дело в том, что у интерпретируемых языков тоже есть свои преимущества, и одно из них то, что программу можно быстро отлаживать (т.е. исправлять ошибки), дополнять и изменять. Ведь программа хранится на диске в том виде, как её написал программист и её не нужно каждый раз перекомпилировать после исправления маленькой ошибки. Кстати, поэтому и разобраться в чужих программах проще – языки программирования, особенно ориентированные на написание скриптов, очень просты для понимания, а вот разобраться в машинных кодах без отличного знания ассемблера (что дано далеко не каждому) практически невозможно…

В общем, программистам всегда хотелось совместить скорость работы компилируемых языков и простоту отладки интерпретируемых. Результатом стал своеобразный гибрид, так называемый прекомпилируемый метод работы интерпретаторов. При этом программа хранится на диске в том виде, как её написал программист, но в момент загрузки в оперативную память компьютера она переводится (специальной программой, часто называемой препроцессором) или непосредственно в машинные коды или в более удобный для дальнейшей обработки промежуточный формат. Вот! Это как раз и есть наш вариант со скриптами в Мафии, да и в огромном количестве других игр Имеем хорошую скорость работы и простоту отладки, в частности моддинга.
Игра Mafia: The City of Lost Heaven написана на объектно-ориентированном языке С++, программисту это уже о многом говорит! Для непрограммистов поясню, что в соответствии с логикой этого языка, всё, что мы видим и многое из того, что не видим, описано в виде отдельных объектов. Каждый человек, каждая машина или здание, каждая коробка или телефонная будка, каждая дорога или выезд из города и т.д… в общем всё это объекты! Каждый объект относится к какому-нибудь классу, например, машины, друзья, полицейские и т.д. Чуть позже мы поговорим об этом подробнее, а сейчас нам важно только усвоить, что игра Мафия, вернее наш городок Лост Хэвен, весь состоит из объектов, он из них построен.

Теперь о скриптах. Скрипт, это сценарий, от английского слова «Script». Точно такой же сценарий или роль, как в театральной пьесе! На форуме Вебгеймера, как выяснилось, есть много театралов, людей, которые любят театр и разбираются в нем. Вот им-то должно быть понятно, о чем я веду речь. Вы никогда не обращали внимания, не задумывались, почему разработчики назвали игровые файлы сценами (scene.4ds, scene2.bin и т.д.), а объекты, из которых состоят эти файлы актерами (actors)? Или откуда пошло такое понятие как «игровая сцена»? Дело в том, что игровые скрипты-сценарии, особенно для игр типа «action» (кстати, еще одно словечко из шоу-бизнеса), очень похожи на сценарии и пьесы театральные, можно сказать, что они близкие родственники. И в том и в другом случае у нас есть сцена с расставленными декорациями и актерами (мизансцена), при этом у некоторых актеров есть свой сценарий, своя роль, свой экшен, а у некоторых этого нет, они как бы играют в массовке. Но ведь и массовка тоже важна, без нее у нас не получится целостности, полноты впечатления от спектакля.

Актер, в любом случае актер, независимо есть у него роль со словами и экшеном (свой скрипт) или он играет бессловесную статую. Как я говорил выше, все из чего состоит город, это объекты. Это верно и понятно любому программисту! Но в то же время любой объект является актером на нашей сцене, по терминологии программистов Illusion Softworks, и с точки зрения «театрального» подхода к скриптам, о чем я говорил выше. Позже попробуем разобраться с этим поподробнее, а пока просто запомним, что объект и актер, это одно и то же – называйте как вам удобнее. Главное, чтобы вы понимали, что бутылка и чашка, стоящие в баре у Луиджи, и сам Луиджи, это и объекты, и актеры одновременно.

Итак, мы построили сцену, расставили актеров и раздали им их роли (scripts), теперь они могут сыграть нам спектакль, а мы насладиться зрелищем, НО очень скоро это нам наскучит, ведь мы делаем игру, то есть хотим сами принять участие в спектакле, самому стать актером, а не только наблюдать за другими актерами. Тут есть один интересный момент! Все актеры имеют свои роли, в соответствии с которыми они выполняют какие-то действия, причем так, что со стороны может показаться, что актеры разумны. Создается впечатление, что актеры могут думать и принимать решения, что они обладают некоторым, достаточно убогим, но все-таки подобием искусственного интеллекта (Artificial Intelligence a.k.a. AI), для простоты часто и говорят, что игровые персонажи обладают AI. Закономерный вопрос, а если игрок выступает в качестве одного из актеров, то нужен ли игроку управляющий его поведением скрипт? У игрока ведь есть своя голова на плечах, часто и не пустая! Игрок сам может и должен принимать решения, в этом и заключается суть игрового процесса, зачем для игрока создавать дополнительный скрипт и AI. В простейшем случае для взаимодействия с AI других актеров, например: чтобы контролировать уровень здоровья игрока, чтобы он не залез куда не просят, чтобы отслеживать корректность прохождения миссии игроком (читы, например), чтобы завершить миссию, когда она пройдена. Таким образом, получается, что если для других актеров скрипты играют в основном управляющую роль, они думают и принимают решения за актеров, то в случае с игроком, скрипты больше ориентированы на контроль его поведения и взаимодействия с другими актерами.

А думать и принимать решения игроку предлагается самому.

Итак, определение скрипта.

Скрипт (script), это сценарий, описывающий и определяющий роль одного актера, его свойства, характеристики, поведение и взаимодействие с другими актерами.

Вы можете спросить, а как же, например, скрипт банды из Alive mod? Ведь не один актер составляет банду? Действительно, в банде несколько человек, у каждого из которых свой скрипт и свои функции, например, водитель… Все верно, каждый из членов банды является отдельным актером и имеет свой отдельный скрипт, описывающий его поведение и свойства. НО, в то же время, вместе члены банды составляют новый объект или актера, что одно и тоже. Если вам трудно это представить, то попробуйте представить, например, кирпич! Кирпич является объектом и относится к классу «Стройматериалы», из нескольких десятков или сотен кирпичей мы можем построить стену, которая тоже будет являться одним объектом, несмотря на то, что построена из множества других объектов, тех самых кирпичей. А из нескольких стен мы построим дом, который тоже является одним объектом, просто другого, более крупного класса «Дома», и так далее, до района и города в целом. В то же самое время наш маленький кирпич никуда не делся, он как был, так и остался объектом.

Точно так же преобразуются и скрипты, поскольку каждому объекту соответствует один скрипт, а объекты могут объединять в себе множество других объектов. Вот и получается, что каждый член банды имеет свой отдельный скрипт, у банды свой скрипт, а у миссии свой. Сложно представить? Ничего, в процессе работы будет понятнее, я надеюсь. А пока запомним, что одним актером могут управлять несколько различных скриптов, это зависит от того, к какому классу объектов он относится, и насколько сложные роли ему предстоит исполнять в этих классах.

что такое скрипты в играх. Смотреть фото что такое скрипты в играх. Смотреть картинку что такое скрипты в играх. Картинка про что такое скрипты в играх. Фото что такое скрипты в играх

Серия контента:

Этот контент является частью # из серии # статей: 30 игровых скриптов, которые можно написать на языке PHP

Этот контент является частью серии: 30 игровых скриптов, которые можно написать на языке PHP

Следите за выходом новых статей этой серии.

Начало работы

В качестве гейммастера/ведущего и разработчика игр мне часто приходится писать небольшие утилиты и скрипты, которые помогают мне при руководстве играми, а также при планировании игр и при непосредственном участии в них. Иногда мне необходима быстрая подсказка. В другой раз мне может потребоваться большое количество имен для NPC-персонажей (Non-Player Character – персонаж, не управляемый игроком). Время от времени мне приходится работать с числами, подсчитывать некоторые шансы или интегрировать в игру те или иные головоломки. Реализация многих из этих задач существенно упрощается, если заблаговременно приложить определенные усилия к написанию соответствующего скрипта.

В этой статье анализируется 10 фундаментальных скриптов, которые могут применяться в играх различного типа. Прилагаемый к данной статье архив программного кода (далее – Архив) содержит полный исходный текст для каждого описываемого в ней скрипта. Кроме того, вы можете увидеть все эти скрипты «в действии» на Web-сайте: chaoticneutral.

Мы «пробежимся» по этим скриптам достаточно быстро. Такие темы как поиск хостинга или настройка сервера в данной статье рассматриваться не будут. Сегодня существует множество Web-хостов, которые предлагают PHP-дистрибутивы; в частности, инсталлятор XAMPP удобен в том случае, если вы хотите сформировать свою собственную среду. Мы не будем тратить много времени на разговоры о наилучших методиках PHP-разработки или о принципах проектирования игр. При создании рассматриваемых скриптов к ним предъявлялись несколько иные требования – эти скрипты должны были быть простыми для понимания, легкими в использовании и быстрыми в усвоении.

Базовый «кидатель кубика» (die roller)

Листинг 1. Использование функции с генератором случайных чисел mt_rand()

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

Листинг 2. Передача типа кубика как параметра

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

Генератор случайных имен

Если вам приходится руководить играми, сочинять сюжеты или одновременно создавать группу персонажей, то иногда у вас могут возникать трудности с придумыванием новых имен. Рассмотрим простой генератор случайных имен, который вы сможете использовать для решения этой задачи. Для начала создадим два простых массива — один с именами, другой с фамилиями (листинг 3).

Листинг 3. Два простых массива с именами и с фамилиями
Листинг 4. Перемешивание массивов имен и фамилий

Приняв эту базовую концепцию, мы сможем создавать текстовые файлы для хранения наших имен и фамилий. Если в каждую строку своего текстового файла мы помещаем по одному имени (фамилии), то мы сможем легко секционировать содержимое этого файла с помощью символов «разрыв строки» с целью последующего построения наших исходных массивов (листинг 5).

Листинг 5. Создание текстовых файлов для имен и фамилий

Создайте или найдите файлы с набором подходящих имен/фамилий (два таких файла включены в Архив), после чего все потенциальные проблемы с именами будут решены.

Генератор сценариев

Используя те же базовые принципы, на которых построен генератор имен, мы можем создать так называемый генератор сценариев. Такой генератор полезен в ролевых играх и в других ситуациях, где необходимо придумать псевдослучайный набор обстоятельств, который может использоваться для разыгрывания ролей, импровизации, написания сюжета и т.д. Одна из моих любимых игр, Paranoia, сопровождается пакетом GM Pack, в состав которого входит инструмент Mission Blender. Инструмент Mission Blender позволяет быстро скомпоновать полную миссию по результатам «кидания кубика». Давайте создадим свой собственный генератор сценариев.

Точно так же, как мы создавали текстовые файлы для наших имен и фамилий, начните с создания отдельного текстового файла для каждого аспекта – исходного положения, цели, противников и осложнений. Соответствующие эталонные файлы включены в Архив. После того как мы будем располагать этими файлами, код для генерации сценария будет выглядеть почти так же, как код для генерации имен/фамилий (листинг 6).

Листинг 6. Генерация сценария

Мы можем вводить в наши сценарии новые элементы посредством добавления новых текстовых файлов или вводить многочисленные осложнения. Чем больше компонентов мы добавляем к своим базовым текстовым файлам, тем более разнообразными будут становиться наши сценарии с течением времени.

Построитель карточной колоды и тасователь карточной колоды

Если вы играете в карточные игры и интересуетесь созданием соответствующих скриптов, мы можем соединить «построитель» карточной колоды со встроенным «тасователем» этой колоды. Для начала построим базовую колоду из стандартных игральных карт. Мы должны создать два массива, один из которых предназначен для хранения мастей, а второй – для хранения достоинств карт. Это обеспечит нам необходимую гибкость впоследствии, если мы захотим добавить другие масти или типы карт (листинг 7).

Листинг 7. Построение базовой карточной колоды

Теперь построим массив, который будет содержать все карты колоды. Мы можем сделать это достаточно просто – с использованием двух циклов foreach foreach (листинг 8).

Листинг 8. Построение массива карточной колоды

После того как мы построили массив карточной колоды, мы можем легко перетасовать колоду и вытянуть карту случайным образом (листинг 9).

Листинг 9. Перемешивание карточной колоды и вытаскивание случайной карты

Теперь мы можем с легкостью составлять наборы из заданного количества карт или строить комплекты из нескольких карточных колод.

Калькулятор шансов: вытягивание карты

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

Листинг 10. Комплектование двух рук по пяти карт в каждой
Листинг 11. Вычисление шансов на вытягивание определенной карты

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

Листинг 12. Поиск определенной карты

Мы также можем искать карту с определенным достоинством или определенной масти (листинг 13).

Листинг 13. Поиск карты с определенным достоинством или определенной масти

Простой дилер для игры в покер

Теперь, когда у нас есть построитель карточной колоды и механизмы для определения шансов на вытягивание определенных карт, мы можем создать простого дилера (раздатчика карт), чтобы попрактиковаться в наборе руки. В этом примере мы построим дилера для варианта покера с пятью картами и заменой (так называемый Five Card Draw Poker). Дилер сдает игроку пять карт из колоды. Вы указываете, от каких карт хотите отказаться (по номеру карты), после чего дилер заменяет эти карты другими картами из колоды. В данном примере мы не будем устанавливать пределы на количество заменяемых карт или правила взаимоотношений между участниками игры, хотя для вас это может оказаться полезным упражнением.

Сгенерируйте и перетасуйте карточную колоду (как было описано в предыдущем разделе), после чего сформируйте одну руку из пяти карт. Отобразите эти карты по их индексу в массиве таким образом, чтобы можно было указать, какие карты требуется заменить. Для указания на заменяемые карты можно также использовать флажки (checkbox) (листинг 14).

Листинг 14. Использование флажков (checkbox) для указания на заменяемые карты
Листинг 15. Просмотр входного массива

С помощью этого скрипта вы сможете «набить руку» — намеренная игра слов — на оптимальные действия при определенных комбинациях карт.

Игра «Виселица»

Игра «Виселица» (или «Палач») – это, по существу, игра в отгадывание слов. Ведущий («палач») задумывает слово определенной длины, а игрок должен отгадать это слово, поочередно предлагая по одной букве (ограниченное число раз). Если игрок предложил букву, которая встречается в загаданном слове, то ведущий заполняет все местоположения этой буквы. После заданного количества неправильных догадок (как правило, шести), игрок проигрывает. Чтобы скомпоновать шаблон для игры в «Виселицу», мы сначала должны создать список слов. Сделаем этот список его в виде простого массива (листинг 16).

Листинг 16. Создание списка слов

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

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

Создайте массив для хранения букв и правильных/неправильных догадок. Для правильных догадок мы будем заполнять массив буквами в качестве идентификаторов и точками в качестве значений (листинг 17).

Листинг 17. Построение массивов для хранения букв и догадок

Теперь нам нужно написать небольшой фрагмент программного кода для оценки догадок и демонстрации слова по ходу игры (листинг 18).

Листинг 18. Оценка догадок и демонстрация хода игры

В Архиве демонстрируется сериализация массивов догадок и их продвижение от догадки к догадке.

Помощник для разгадывания кроссвордов

Листинг 19. Прохождение по списку слов

При условии достаточно высокого качества нашего списка слов и достаточной точности наших догадок мы сможем получить приемлемый список слов для последующей проверки на возможные совпадения. После этого вам останется решить, какое из слов – «chest» (грудная клетка) и «cheat» (жульничество) – лучше подходит на роль слова из пяти букв, означающего «нарушение правил игры».

Механизм для игры Mad Libs

Mad Libs – это игра в слова, в которой игрок берет короткий рассказ и заменяет ключевые типы слов другими словами того же типа, чтобы создать новую, более глупую версию той же истории. Возьмем следующий текст: «I was walking in the park when I found a lake (Я шел по парку и нашел озеро). I jumped in and swallowed too much water (Я нырнул в озеро и проглотил слишком много воды). I had to go to the hospital (Мне пришлось пойти в больницу)». Начните заменять типы слов различными токенами. Начинайте и завершайте каждый токен подчеркиванием, чтобы предотвратить случайные совпадения строк (листинг 20).

Листинг 20. Замена типов слов символами слов

После этого создайте несколько списков базовых слов. В этом примере мы не будем давать большую волю своей фантазии (листинг 21).

Листинг 21. Создание нескольких списков базовых слов

Теперь мы можем многократно оценивать текст на предмет возможной замены токенов по мере необходимости (листинг 22).

Листинг 22. Оценка текста

Вполне очевидно, что это простой и достаточно сырой пример. Чем точнее будут наши списки слов и чем больше времени мы потратим на создание нашего базового текста, тем лучше будут наши результаты. Мы уже использовали текстовые файлы для создания списков имен и списков базовых слов. Используя тот же самый принцип, мы можем создавать списки слов, разбитые по типам, и использовать их для создания более разнообразных игр типа Mad Libs.

Механизм для игры в лото

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

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

Мы сохраняем выигрышные номера в текстовом файле. Мы отделяем номера запятыми и помещаем каждый набор номеров на отдельную строку. Содержимое этого файла, разделенное на строки с помощью символов-разделителей строк, а в пределах каждой строки разделенное с помощью запятых, будет выглядеть примерно следующим образом (листинг 23).

Листинг 23. Сохранение выигрышных номеров лото в текстовом файле

Вполне очевидно, что этого недостаточно для выявления статистических закономерностей. С другой стороны, этого вполне достаточно для иллюстрации основных принципов.

Листинг 24. Прохождение по выпавшим значениям

И, наконец, отсортируйте массив по возрастанию значений. В результате наименее выбираемые числа должны попасть в начало массива (листинг 25).

Листинг 25. Сортировка чисел по частоте их выпадения

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

Заключение

Эта статья является полезным ресурсом для всех, кто хотел бы приступить к использованию языка PHP для обогащения своих игровых возможностей. Во второй статье серии под названием «30 игровых скриптов, которые можно написать на языке PHP» мы на базе описанного в этой статье кода создадим более совершенные скрипты, которые предоставят нам дополнительные возможности.

Ресурсы для скачивания

Похожие темы

Комментарии

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

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *