Вы находитесь на странице: 1из 156

+Министерство науки и высшего образования Российской Федерации

Федеральное государственное бюджетное образовательное учреждение


высшего образования
«Сибирский государственный индустриальный университет»

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
выпускной квалификационной работы:
Разработка игрового приложения в жанре «survival-horror» для снятия
психофизического напряжения
(тема)

ОБУЧАЮЩИЕСЯ _____________ Хлуднев Андрей Сергеевич


(подпись) (фамилия, имя, отчество)
_____________ Тырышкин Никита Дмитриевич
(подпись) (фамилия, имя, отчество)
_____________ Лоншаков Сергей Михайлович
(подпись) (фамилия, имя, отчество)

допущен к защите в государственной экзаменационной комиссии «__» _____ 20__ г.

Руководитель _________________ ___________ ____________________


(уч. степень, звание) (подпись) (фамилия, имя, отчество)

Заведующий кафедрой _________________ ___________ ____________________


(уч. степень, звание) (подпись) (фамилия, имя, отчество)

Директор института
___________________ _________________ ___________ ____________________
(наименование института) (уч. степень, звание) (подпись) (фамилия, имя, отчество)

Новокузнецк
2021 г.
Министерство науки и высшего образования Российской Федерации

Федеральное государственное бюджетное образовательное учреждение


высшего образования
«Сибирский государственный индустриальный университет»

Кафедра ________________________________________________________________

УТВЕРЖДАЮ
Заведующий кафедрой
_________ ___________________
(подпись) (ФИО)
«____» _________________ 20__г.

ЗАДАНИЕ
на выпускную квалификационную работу
обучающегося ___________________________________________________________
(фамилия, имя, отчество)
группы ________________

Тема работы ________________________________________________________


_________________________________________________________________________
_________________________________________________________________________
_________________________________________________________________________
Утверждена приказом от ___________________________ №________________
Характер работы ____________________________________________________
________________________________________________________________________
(прикладное научное исследование, экспериментальная разработка, аналитическая работа, ОКР)
________________________________________________________________________
Срок сдачи обучающимся законченной работы «____» ___________ 20_____г.
Исходные условия и данные к работе ___________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
Цель, задачи работы _________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
Содержание работы_________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
_______________________________________________________________________
________________________________________________________________________
_______________________________________________________________________
________________________________________________________________________
_______________________________________________________________________
Предполагаемое использование результатов_____________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
_______________________________________________________________________
Перечень графического материала ____________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
Консультанты по работе с указанием относящихся к ним разделов работы
______________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
________________________________________________________________________
Нормоконтроль _____________________________________________________
________________________________________________________________________

Руководитель ___________________
(подпись)

Задание к исполнению принял ________________ «____» ___________ 20___г.


АННОТАЦИЯ

Тырышкин Никита Дмитриевич, Хлуднев Андрей Сергеевич, Лоншаков


Сергей Михайлович, игровое приложение в жанре «survival-horror» для снятия
психофизического напряжения, выпускная квалификационная работа по
направлению подготовки «Информатика и вычислительная техника» (09.03.01). –
Новокузнецк, 2021. – 154 с., табл. 9, ил. 88, источников 20.
В процессе выполнения выпускной квалификационной работы «Разработка
игрового приложения в жанре «survival-horror» для снятия психофизического
напряжения» был разобран программный продукт под названием «Old Estate».
Произведен обзор и анализ существующих игр в подобном жанре, среди них
выбрана система-прототип, по которой в дальнейшем и производилась разработка. В
работе представлен алгоритм работы самой программы в целом и приведено
описание информационного обеспечения для программы-прототипа. Объектом
исследования является процесс снятия психофизического напряжения пользователя
в процессе игры.
В результате разработки «игрового приложения в жанре «survival-horror» для
снятия психофизического напряжения» обоснована целесообразность данной
работы.
Результаты работы могут быть использованы на любой персональном
компьютере с достаточными характеристиками мощности, для помощи в снятии
эмоционального напряжения у пользователей.
ANNOTATION

Nikita Dmitrievich Tyryshkin, Andrey Sergeevich Khludnev, Sergey Mikhailovich


Lonshakov, game application in the genre of "survival-horror" for relieving
psychophysical stress, final qualification work in the direction of training "Informatics and
Computer Engineering" (09.03.01). – Novokuznetsk, 2021. – 154 p., table 9, ill. 88,
sources 20.
In the course of the final qualification work "Development of a game application in
the genre of" survival-horror "to relieve psychophysical stress", a software product called
"Old Estate" was disassembled.
A review and analysis of existing games in this genre was made, among them a
prototype system was selected, according to which development was carried out in the
future. The paper presents the algorithm of the program itself as a whole and provides a
description of the information support for the prototype program. The object of the study
is the process of removing the psychophysical tension of the user during the game.
As a result of the development of "a game application in the genre of "survival-
horror" to relieve psychophysical stress", the expediency of this work is justified.
The results of the work can be used on any personal computer with sufficient power
characteristics to help relieve emotional stress in users.
СОДЕРЖАНИЕ

ВВЕДЕНИЕ..........................................................................................................................8
1 Общая часть......................................................................................................................9
1.1 Характеристика объекта информатизации...............................................................9
1.2 Обзор и анализ известных разработок....................................................................10
1.2.1 Knock knock.........................................................................................................10
1.2.2 Limbo....................................................................................................................14
1.2.3 Creaks...................................................................................................................17
1.2.4 Little Nightmares..................................................................................................21
1.2.5 Darkest Dungeon..................................................................................................24
1.3 Сравнительный анализ существующих разработок..............................................27
1.4 Система-прототип по видам обеспечения..............................................................28
1.4.1 Информационное обеспечение системы-прототипа.......................................28
1.4.2 Алгоритмическое обеспечение системы-прототипа.......................................31
2 Специальная часть..........................................................................................................34
2.1 Техническое задание: создание игрового приложения в жанре «survival-horror»
для снятия психофизического напряжения..................................................................34
2.1.1 Введение.............................................................................................................34
2.1.2 Назначение разработки.....................................................................................34
2.1.3 Требования к функциональным характеристикам.........................................34
2.1.3.1 Состав выполняемых функций....................................................................34
2.1.3.2 Требования к надёжности............................................................................36
2.1.3.3 Требования к мобильности..........................................................................36
2.1.3.4 Условия эксплуатации..................................................................................36
2.1.3.5 Требования к составу и параметрам технических средств.......................37
2.1.3.6 Требования к информационной и программной совместимости.............37
2.1.3.7 Требования к маркировке и упаковке.........................................................37
2.1.3.8 Требования к информационной и программной совместимости.............37
2.1.4 Требования к программной документации......................................................38
2.1.5 Требования к дизайну игрового продукта........................................................38
2.1.6 Технические показатели.....................................................................................39
2.1.7 Стадии и этапы разработки................................................................................40
2.1.8 Порядок контроля и приемки............................................................................41
2.1.9 Экономическое обоснование.............................................................................41
2.2 Описание разработанного продукта по видам обеспечения................................45
2.2.1 Информационное обеспечение..........................................................................45
2.2.1.1 Модульная структура работы программы..................................................45
2.2.1.2 Модульная структура работы искусственного интеллекта......................49
2.2.2 Алгоритмическое обеспечение..........................................................................52
2.2.2.1 Алгоритмы работы программы и ее основных составляющих объектов52
2.2.2.2 Алгоритмы работы искусственного интеллекта........................................80
2.2.3 Техническое обеспечение................................................................................107
2.2.4 Программное обеспечение...............................................................................107
2.2.4.1 Используемые программы.........................................................................107
2.2.4.2 Разработка графического интерфейса.......................................................110
2.2.4.3 Создание анимации.....................................................................................116
2.2.4.4 Создание саундтреков и звуковых эффектов...........................................123
2.2.5 Концептуальное обеспечение..........................................................................132
2.2.6 Лингвистическое обеспечение........................................................................143
2.3 Тестирование продукта..........................................................................................144
2.3.1 Тест-план...........................................................................................................144
2.3.2 Тест-комплекты.................................................................................................146
2.3.3 Результаты выполнения...................................................................................149
ЗАКЛЮЧЕНИЕ................................................................................................................153
БИБЛИОГРАФИЧЕСКИЙ СПИСОК............................................................................155
ВВЕДЕНИЕ

Для человека нашего времени проведение досуга с использованием


компьютерных технологий, а в частности компьютерных игр, это неотъемлемая
часть жизни, поэтому создание подобных программных продуктов является делом
востребованным.
Кроме того современный и быстрый темп жизни часто приводит к
возникновению стрессовых ситуаций, которые при длительном воздействии могут
усугубить психическое состояние человека.
Создаваемое приложение, в первую очередь, ставит перед собой цель
избавления человека от психофизического напряжения с помощью игрового
процесса и главным образом рассчитано на молодую, подростковую аудиторию 14-
20 лет.
Объектом исследования является процесс снятия психофизического
напряжения пользователя в процессе игры.
Для реализации поставленной цели необходимо выполнить следующие
задачи:
 изучить характеристики объекта информатизации;
 провести обзор существующих разработок программного обеспечения
подобного типа;
 провести сравнительный анализ существующих разработок;
 выбрать систему прототип;
 рассмотреть систему прототип по видам обеспечения;
 разработать собственную систему;
 разобрать собственную систему по видам обеспечения;
 составить план тестирования;
 провести тестирование;
 проанализировать результаты тестирования.

8
1 Общая часть

1.1 Характеристика объекта информатизации

Как уже говорилось ранее, быстрый темп современной жизни зачастую


приводит к тому, что у людей возникают различные стрессовые ситуации, которые
обладают сильным накопительным эффектом.
Для нейтрализации подобного воздействия на психику человека создаваемый
игровой продукт должен обладать определёнными характерными чертами. Поэтому
для проекта были выделены следующие особенности:
 оригинальная история, которая позволит пользователю на время игрового
прохождения «абстрагироваться» от повседневных проблем и забот;
 реализация игры на базе, всем известного и понятного, двухмерного
пространства позволит намного шире разнообразить геймплейную составляющую
путем организации множества различных и интересных процедурно генерируемых
уровней;
 авторская двухмерная графика в мрачном стиле, в совокупности с
соответствующей музыкой, за счет сочетания определенных цветовых гамм и
звуковых мотивов, будет способствовать «погружению» в игровой мир, что,
несомненно, важно для любой игры;
 добавление некоторых, знакомых почти каждому человеку, элементов
квестовых аркад удержит заинтересованность на высоком уровне в течение всего
прохождения.
Стоит также помнить, что одной из уникальных черт жанра «survival-horror»
является определение в большей степени общей атмосферой игры, чем игровой
механикой. А сюжет типичной игрового представления включает в себя
расследование неких тайн и столкновение с пугающими силами, часто взятыми на
основе образов из фильмов и литературы ужасов.

9
1.2 Обзор и анализ известных разработок

Прежде чем приступать к созданию собственного программного обеспечения


необходимо рассмотреть уже существующие варианты подобного типа,
проанализировать их достоинства и недостатки, сделать некоторые выводы, которые
впоследствии лягут в основу будущих решений по разработке.
Для обзора и анализа было выбрано пять игр в жанре «survival-horror»,
созданных независимыми игровыми студиями.

1.2.1 Knock knock

«Knock-knock» является компьютерной игрой, созданной российскими


разработчиками, студией «Ice-Pick Lodge». Данное игровое приложение вышло 4
октября 2013 года.
Одной из главной особенностей игры, резко выделяющей ее среди других,
является то, что эффект страха достигается не с помощью скримеров, а атмосферой
самого игрового процесса. Для создания мрачного и напряженного окружения,
разработчики использовали специально подобранную музыку, особый стиль
графического оформления, а также нелогичный сюжет, который призван запутать
пользователя и заставить его вдумываться в то, что происходит в игре, тем самым
еще сильнее «погружая» его в историю.
Суть игрового процесса, заключается в том, что пользователю необходимо
помочь главному герою дождаться рассвета. Для этого необходимо вкручивать,
периодически гаснущие, лампы в комнатах дома, а также, при возможности,
использовать часы, для ускорения хода времени. Стоит отметить, что только при
включенном свете главный герой может взаимодействовать с предметами в комнате,
ввиду того, что в темноте он их попросту не видит. Внезапное же выключение света
может свидетельствовать о появлении в доме «гостя», так в этой игре называют
врагов главного героя. [1]

10
Еще одним отличием данной игры от подобных является то, что она
фактически не даёт возможности пользователю взаимодействовать с врагами. Это
означает, что главный герой никак не сможет остановить «гостя», и чтобы спастись
ему необходимо либо искать укрытие, либо починить освещение в проблемной
комнате до того, как враг настигнет его.
Врагов в игре можно условно разделить на три категории:
 неподвижные. Самые безобидные враги, использующиеся лишь в целях
нагнетания пугающей атмосферы;
 подвижные. Основной тип врагов, в основном занимающийся
патрулированием закрепленных за ними территорий, либо преследованием игрока;
 редкие (подвижные) враги, обладающие специальными возможностями.
Самый опасный подвид противников, ввиду их исключительных способностей,
таких как обыскивать укрытия, перемещаться по совершенно неожиданным
траекториям и тому подобное.
Примеры врагов в игре представлены на рисунках 1 и 2.

Рисунок 1 – Подвижный враг в «Knock-knock»

11
Рисунок 2 – Неподвижный враг в «Knock-knock»

Локация представляют собой дом с множеством комнат. В целом, можно


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

Рисунок 3 – Комната в «Knock-knock» (вариант 1)

12
Рисунок 4 – Комната в «Knock-knock» (вариант 2)

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


в том, что при особом стечении обстоятельств главный герой может попасть в некий
временной «разлом», представляющий собой коридор, и, пройдя его до конца, он
или проиграет уровень, или же сразу пройдёт его. При чём исход определяется
случайным образом и никак не связан с действиями самого игрока.
Если рассматривать плюсы, то можно выделить следующие моменты:
 уникальный и запоминающийся геймплей, некоторые механики которые не
встречаются ни в одной игре подобного жанра;
 необычный ход повествования с элементами абсурда и фантасмагории,
который позволяет удерживать пользователя за игрой;
 авторское графическое и звуковое оформление игры, которое создает
необходимую атмосферу в игре.
К минусам игры стоит отнести следующие нюансы:
 игра не даёт внятного ответа на то, что происходит с главным героем по
ходу сюжета и какой финал у всей истории;
 геймплей игры быстро надоедает и становиться монотонным и рутинным.
Анализируя данную игру можно сделать вывод, что её разработчики делали
большой упор на сюжетную составляющую, а также на создание определенной
атмосферы используя графические и звуковые элементы. Однако такая

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

1.2.2 Limbo

«Limbo» – это игра в жанре «survival-horror», созданная независимыми


разработчиками из Дании, студией «Playdead». Вышла 21 июля 2010 года.
Игра была создана на физическом движке «Box2D», который позволяет
управлять объектами окружающей среды и персонажем.
Фабула игры заключается в попытке маленького мальчика (главного героя)
спасти свою сестру из лимба. По мере прохождения главный герой будет всё больше
узнавать о месте, в котором он оказался. Финал игры остаётся открытым, до конца
не понятно, что произошло с главным героем и смог ли он выполнить свою главную
миссию – спасение сестры. В игре отсутствует текстовое повествование, весь сюжет
подается только визуально, через действия главного героя и события в окружающем
его мире.
Графическая составляющая игры выполнена в монохромном стиле и в целом
придерживается принципа минимализма. Звуковая составляющая при этом делает
больший упор не на саундтрек, который играет на фоне, а на звуки объектов
окружающей среды и врагов. И именно это, по задумке разработчика, должно
создавать пугающую и тревожную атмосферу. [2]

14
Геймплей же представляет собой метод «проб и ошибок». Пользователю
предстоит путем исследования мира, выбрать правильный вариант прохождения
определенной локации, однако в процессе, как правило главный герой несколько раз
умирает из-за ошибок пользователя. Игра никак не наказывает игрока за смерти и
даже поощряет такой подход к прохождению.
Мир лимбо наполнен большим количеством ловушек, поэтому эту игру часто
сравнивают с классическими платформерами из-за схожести геймплея. Как и в
большинстве проектов данного типа, игровой процесс строится на физическом
взаимодействии главного героя с окружением. Игрок может идти вправо, влево,
прыгать, взбираться на небольшие уступы, карабкаться по верёвкам или лестницам,
а также толкать и тянуть предметы.
Примеры игровых локаций представлены на рисунках 5 и 6.

Рисунок 5 – Локация в «Limbo» (вариант 1)

15
Рисунок 6 – Локация в «Limbo» (вариант 2)

Среднее время прохождения игры – от трех до шести часов. Во многом это


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

16
Анализируя данную игру, можно прийти к нескольким важным выводам. Во-
первых, ставка на геймплей в играх жанра «survival-horror» является скорее
ошибкой, так как для удержания внимания пользователя этого недостаточно. Игрок
должен следовать за сюжетом, который увлекал бы его, мотивируя и дальше
проходить игру. В «Limbo» решили оставить сюжет на заднем плане, в итоге
получился скорее типичный платформер с элементами головоломки, а не
полноценное хоррор произведение.
В отличие от рассмотренной ранее «Knock-knock», игровой процесс в «Limbo»
занимает не более 6 часов, однако именно из-за отсутствия повествования,
пользователи отмечают, что после второй половины игры, интерес к ней резко
падает, пользователь не видит прогресса при продвижении к финалу.
Однако пример данной игры, показывает то, насколько важно создавать
оригинальный авторский графический и звуковой стиль, ведь именно из-за него,
многим так понравилась и запомнилась «Limbo».
В целом, можно сказать, что данный игровой продукт является
противоположностью рассматриваемой ранее игры, но при этом некоторые
типичные проблемы жанра «survival-horror» присутствуют в двух этих играх. Чтобы
избежать их, следует прежде всего соблюдать баланс геймплейной и
концептуальной составляющей.

1.2.3 Creaks

«Creaks» – платформенная приключенческая хоррор-игра, разработанная


компанией «Amanita Design».
О разработке было объявлено 9 октября 2018 года. Впервые игровой продукт
был выпущен 10 июля 2020 года в онлайн-сервисе цифрового распространения
компьютерных игр «Apple Arcade».
Геймплей игры представляет собой решение головоломок путём
взаимодействия с окружающим миром. Главными врагами являются, так
называемые «скрипы». Игроку необходимо избегать этих чудовищ и, по

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

Рисунок 7 – Враги в «Creaks»

Как и в предыдущей рассмотренной игре, в Creaks нет чётко выраженной


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

18
Графическая составляющая игры представляет собой фирменный стиль
студии Amanita Design. Характерной особенностью этого стиля является
проработанность деталей окружения, при этом все локации и персонажи
нарисованы вручную. Именно такой стиль принес успех студии в прошлом. [3]
Примеры локаций представлены на рисунках 8 и 9.

Рисунок 8 – Локация в «Creaks» (вариант1)

Рисунок 9 – Локация в «Creaks» (вариант 2)

19
Звуковая составляющая в игре также хорошо проработана и представляет
собой ритмичный «ambient», который заставляет пользователя концентрироваться, и
находится в напряжении при встрече с врагами. Однако нельзя сказать, что данная
музыка является типичной для жанра, разработчики, понимая это, добавили в игру
резких, пугающих звуков игрового окружения, которые и выполняют требуемую
функцию, а именно создание пугающей, тревожной атмосферы.
В данном проекте нельзя выявить новых уникальных механик, все
головоломки в игре представляются типичными для подобных платформенных игр
и по мнению некоторых игровых критиков не отличаются разнообразием.
Подводя итоги, можно выявить следующие плюсы игры:
 музыкальная составляющая и в целом звуковой дизайн на достаточно
высоком уровне и хорошо выполняют свои функции;
 уникальная графическая составляющая, все детали которой сделаны
вручную и впоследствии обработаны специализированным программным
обеспечением;
 множество различных деталей, которые может исследовать игрок,
например, коллекция картин, которые главный герой находит по ходу игры. В
каждой из таких картин имеется своя уникальная головоломка.
Из минусов же можно отметить следующее:
 плохо проработанный сюжет и история мира, в который попадает главный
герой игры;
 однообразные головоломки, которые могут оттолкнуть от прохождения;
 непривычное управление и анимации главного героя.
Проанализировав данную игру, можно заметить, что некоторые её проблемы
схожи с игрой «Limbo», рассмотренной ранее, а именно плохая проработка сюжета
и истории игрового мира. Также явно видна проблема однотипности геймплея, что
характерно для многих проектов в данном жанре.
Разработчики явно делали акцент на графической и звуковой составляющих,
однако при всей уникальности и необычности решений в этих областях, только эти
два аспекта не могут долго удержать внимание пользователя.
20
Делая выводы по данной и предыдущим играм, можно прийти к заключению,
что следует большое внимание уделять не только графической и звуковой
составляющей, но и чётко построенному сюжету, который раскрывал бы мысли и
поступки персонажей, описывал окружающий мир и мотивировал бы игрока в
дальнейшем прохождении.

1.2.4 Little Nightmares

«Little Nightmares» - компьютерная игра в жанре платформера с элементами


квеста и хоррора, разработанная шведской компанией «Tarsier Studios» и
выпущенная компанией «Bandai Namco Entertainment». Вышла 28 апреля 2017 года.
По своему геймплею данная похожа на рассмотренные ранее игровые
проекты. Игроку даётся возможность управлять действиями персонажа, такими как:
ходить, прыгать, хватать, использовать предметы, принимать пищу и
взаимодействовать с персонажами. Основной задачей, которую игра ставит перед
пользователем, является решение головоломок различной сложности либо для того,
чтобы просто пройти в следующую локацию, либо для нейтрализации врагов. [4]
Нельзя сказать, что головоломки и загадки отличаются высокой
вариативностью, однако для их решения игроку придется детально изучить локацию
и проанализировать возможные варианты взаимодействия с объектами на ней.
В игре присутствуют враги, однако они представлены в виде «боссов»
нескольких локаций, это означает, что герой не может сражаться с такими
противниками на равных, для победы над ними придется их перехитрить и заманить
в ловушки.
Примеры локации и одного из боссов в игре представлены на рисунках 10 и
11.

21
Рисунок 10 – Локация в «Little Nightmares»

Рисунок 11 – Босс в «Little Nightmares»

В отличие от многих 2D платформеров, в которых графика персонажей


представляет собой двухмерные спрайты, анимированные с помощью техники
скелетной анимации, в игре «Little Nightmares» использовались трёхмерные модели
персонажей. Анимация была сделана в стиле кукольной мультипликации. Благодаря

22
этим приёмам игра сильно запомнилась многим и получила множество
положительных отзывов от критиков.
Звуковой дизайн также был детально проработан. Чаще всего саундтрек
определенной локации представляет собой музыку в стиле мрачного эмбиента с
добавлением партий пианино и женского вокала. На фоне периодически можно
услышать плач, вой и стоны. Всё это в совокупности привносит ощущения
тревожности и мрачности, характерные для игр в жанре хоррор.
Основные плюсы данной игры:
 интересные и сложные головоломки;
 хорошо проработанный игровой мир, выдержанный в единой атмосфере;
 уникальное звуковое оформление и авторские саундтреки.
Из минусов можно отметить:
 множество бесполезных, пустых локаций;
 плохо проработанная система ключевых точек для сохранения игрового
процесса;
 плохая оптимизация.
Проанализировав данный игровой проект, можно сделать вывод, что в плане
подхода к сюжету он является типичным представителем жанра платформера с
элементами «survival-horror» и все недостатки такого подхода, а именно
постепенное уменьшение заинтересованности пользователя в дальнейшем
прохождении, также присутствуют в игре.
В «Little Nightmares» была сделана большая ставка на графику и звук и даже
геймплей отходит на второй план в игровом процессе рассматриваемого
приложения. При этом, несмотря на то, что геймплей не был так старательно
проработан, он всё-таки остается на достаточно высоком уровне, так как он тесно
связан с графической составляющей игры. Это связь проявляется, например, в том,
что одна и та же головоломка, которую должен решить игрок, в различных локациях
предстаёт по-разному, что для конечного пользователя выглядит привлекательнее,
чем решение однотипно сделанных головоломок.

23
В заключении можно сделать вывод, что «Little Nightmares» является
достаточно хорошо проработанной с точки зрения визуальной, звуковой и
геймплейной части игрой, однако из-за типичного пренебрежения сюжетной
составляющей, заинтересованность человека в полном прохождении резко падает.

1.2.5 Darkest Dungeon

«Darkest Dungeon» - компьютерная ролевая игра в жанре «survival-horror» с


roguelike-элементами, разработанная и выпущенная независимой канадской студией
«Red Hook Studios». 19 января 2016 года состоялся выпуск приложения на ПК.
Геймплей игры заключается в периодических походах группы персонажей в
различные игровые локации, целью этих походов является добыча различных
ресурсов, которые позже можно использовать для улучшения навыков и оружия
своих юнитов. Для похода игроку следует покупать необходимое количество еды и
факелов, а также различные лечебные компоненты, снимающие негативные
эффекты. Во время самих походов на пути будут встречаться множество опасных
врагов, каждый из которых обладает уникальными умениями. Битвы в игре
представляют собой пошаговую боевую систему, очередность ходов в которой
определяется некоторыми характеристика персонажей (например,
инициативностью).
Находясь в боевых локациях, пользователь никогда не знает в каком месте
начнется битва и будет ли он готов к ней, поэтому многие такие сражения
заканчиваются не в пользу игрока. Создатели данной игры ещё в начале
прохождения предупреждают о том, что периодически персонажи будут гибнуть в
боях или в ловушках, это добавляет в игру roguelike–элемент и заставляет игрока
возвращаться в одни и те же локации десятки раз, чтобы увеличить уровень своего
персонажа. [5]
Пример битвы в игре представлен на рисунке 12.

24
Рисунок 12 – Битва в игре «Darkest Dungeon»

В игровом продукте присутствует свой авторский стиль рисовки и анимации,


его основной особенностью является использование черного цвета для прорисовки
теней объекта, такой приём при создании рисунков локаций и персонажей создает
своеобразный эффект мрачности. Также можно заметить, что в игре практически не
используются яркие цвета, чаще всего можно встретить тёмные пастельные тона.
Примеры локаций представлены на рисунках 13 и 14. Анимация в игре сделана
покадрово, а не с помощью скелетной анимации, как во многих других проектах
подобного жанра.
Музыкальный фон в игре крайне разнообразный и представлен как жанром
«dark ambient» с преобладанием низких частот, так и органной музыкой в сочетании
с партиями струнных инструментов. Во время боёв начинает играть ритмичная
музыка с использованием ударных инструментов, как правило в сочетании низким
мужским вокализом. Такой непостоянный музыкальный фон обуславливается тем,
что каждая локация в игре подразумевает наличие собственной уникальной
атмосферы, передать которую и стремится звуковой дизайн.
Сюжет в игре основывается на мифах, созданных Говардом Лавкрафтом, и
повествует о том, как старый наследник средневекового замка старается избавиться
от потусторонних существ и мутантов, которые появились в его землях. Для этого
25
он нанимает различных авантюристов, которые в конечном итоге должны очистить
земли от «скверны». Игроку же предстоит выяснить причину странных явлений и
докопаться до сути в этом деле. Базирование сюжета на так называемых
«лавкрафтовский ужасах» обусловлено не только наличием конкретных образов, но
и общими темами повествования характерными для творчества Лавкрафта – страх
перед неизвестностью, потеря рассудка и ничтожество человека перед лицом
космических сил.

Рисунок 13 – Локация в игре «Darkest Dungeon» (вариант 1)

Рисунок 14 – Локация в игре «Darkest Dungeon» (вариант 2)


26
Из положительных сторон следует отметить следующее:
 наличие большого количества врагов, персонажей, предметов и локаций;
 продуманная пошаговая боевая система;
 большая вариативность прохождения.
Из минусов же игры следует выделить следующие аспекты:
 сложность и затянутость прохождения;
 не всегда логичные способы решения различных задач;
 недостаточная сбалансированность персонажей и врагов.
Анализируя данную игру, можно заметить, что она отличается от типичных
представителей жанра. В игре хорошо проработан геймплей, хотя имеются большие
проблемы с балансом.
Также представлен вполне детально прописанный сюжет, который раскрывает
мотивацию главных героев и даёт игроку чёткие ответы на загадки происходящих
событий. Сюжет здесь даёт игроку цель и подпитывает его интерес, постепенно
раскрываю историю игрового мира и историю каждого отдельного персонажа.
Графика также заслужила высоких оценок критиков, так как она полностью
выполняет свою функцию в игре, а именно передачу необходимой атмосферы.
При этом, несмотря на то, что почти все звуковое сопровождение неплохо
вписывается в общую концепцию игрового мира, некоторые композиции и звуковые
эффекты не вполне подходят для подобного жанра.
Помимо этого, присутствует проблема, которая была также обнаружена в
«Knock – knock», а именно затянутость и сложность прохождения. И хотя данный
проект способен долгое время удерживать внимание пользователя, эти два фактора
могут заставить пользователя прекратить прохождение, что в итоге плохо отразится
на репутации студии в целом.

1.3 Сравнительный анализ существующих разработок

В таблице 1 представлены результаты сравнения характеристик всех


рассмотренных выше игровых приложений. Исходя из сформированной таблицы, в
27
качестве системы-прототипа была выбрана игра «Knock-knock» как наиболее
подходящий вариант.

Таблица 1 – Результаты сравнительного анализа по трехбалльной шкале

Название Геймплейная Графическая Звуковое Сюжетная


игры составляющая составляющая окружение составляющая
Knock-
2 3 3 2
knock
Limbo 3 2 2 1
Creaks 2 3 3 1
Little
2 3 2 1
Nightmares
Darkest
2 3 2 2
Dungeon

1.4 Система-прототип по видам обеспечения

1.4.1 Информационное обеспечение системы-прототипа

Для обзора данной системы была составлена модульная структура игрового


приложения «Knock-knock». Данная схема отражена на рисунке 15.
В данной модульной структуре представлены следующие основные элементы:
 Модуль «Игровое меню»;
 Подмодуль «Играть»;
 Модульная единица «Новая игра»;
 Модульная единица «Продолжить»;
 Подмодуль «Участники»;
 Подмодуль «Выход»;
 Модуль «Операции пользователя»;

28
 Подмодуль «Обработка нажатия на кнопку»;
 Модуль «Игровой процесс»;
 Подмодуль «UI/UX интерфейс»;
 Подмодуль «Скрипты»;
 Модульная единица «Сохранение игрового процесса»;
 Модульная единица «Обеспечение интерактивного взаимодействия»;
 Модульная единица «ИИ врагов».
Рассмотрим каждый из них подробнее.
В модуле игрового меню содержатся три подмодуля и две модульные
единицы, которые отвечают за непосредственное начало нового игрового процесса,
при этом модульная единица «Продолжить» появляется только при наличии уже
существующего сохранения, или загрузки уже сохраненного ранее, за просмотр
имен создателей приложения и за выход из данного игрового приложения с
сохранением текущего игрового прогресса.
В модуле операций пользователя содержится только один подмодуль, который
отвечает за обработку нажатий определенных клавиш на игровых манипуляторах и
вызов соответствующих им методов из кода игры.
В модуле «Игровой процесс» представлены два важнейших подмодуля,
отвечающих за непосредственно работу игрового приложения.
Первый из них, подмодуль «UI/UX интерфейс», включает в себя всю
графическую составляющую, а именно такие элементы, как: анимированные
спрайты, бэкграунды локаций, информационные элементы.
Следующим рассматриваемым компонентом является подмодуль «Скрипты».
Он отвечает за автоматическое сохранение игрового прогресса пользователя в
определенные моменты, а также за логику поведения враждебных персонажей и за
обеспечение интерактивного игрового взаимодействия.

29
Рисунок 15 – Модульная структура система-прототипа

30
1.4.2 Алгоритмическое обеспечение системы-прототипа

Алгоритм работы программы можно представить следующим образом:


 пользователь заходит в игру и выбирает «Продолжить» или «Новая игра»;
 происходит загрузка выбранного события;
 вместе с нужным событием загружаются спрайт игрового поля, героя,
монстры, а также все необходимые графические элементы;
 для прохождения уровня необходимо выполнить главное задание –
продержаться в доме до рассвета. Этого можно добиться, обходя все комнаты дома
и включая в них свет, закручивая лампочки на потолке. Только включив свет в
комнате, вы сможете видеть и, следовательно, взаимодействовать с предметами в
ней. Это могут быть часы, позволяющие «ускорить» время, места, в которых можно
спрятаться в случае опасности, или просто элементы интерьера;
 каждый обозначенный промежуток времени (по стандарту, каждый кадр)
проверяется текущее значение игрового времени;
 если наступил рассвет, и игрок не потерял данные ему в начале очки
рассудка, то происходит:
 сохранение текущего прогресса;
 переход к следующему уровню.
 если рассвет еще не наступил, а игрок потерял данные ему очки рассудка
полностью, то:
 игрок попадает в главное меню, где может начать новую игру, при
этом весь сохраненный до этого прогресс будет утерян.
В самом начале игрового прохождения персонаж имеет максимальные очки
рассудка. Однако при столкновениях с монстрами, долгих блужданиях по темному
лесу вне дома и прочих действиях, которые пугают главного героя, он постепенно
будет терять рассудок, который впоследствии не может быть восполнен и является
единым для каждого из уровней.
На рисунках 16 и 17 представлена блок-схема работы алгоритма.

31
Рисунок 16 – Блок-схема алгоритма работы системы-прототипа (часть 1)

32
Рисунок 17 – Блок-схема алгоритма работы системы-прототипа (часть 2)

33
2 Специальная часть

2.1 Техническое задание: создание игрового приложения в жанре


«survival-horror» для снятия психофизического напряжения

2.1.1 Введение

Настоящее техническое задание (ТЗ) устанавливает технические требования


на игровое приложение в жанре «survival-horror», которое помогало бы
пользователю избавиться от накопленного психофизического напряжения.
Продукт предполагает последовательное развитие игрового сюжета и мира.
Планируется разработка адаптивного дизайна пользовательского интерфейса,
портирование на различные игровые платформы.
Игра предназначена для личного пользования. Состав и содержание
настоящего технического задания разработаны в соответствии с требованиями
ГОСТ 19.201-78.

2.1.2 Назначение разработки

Данная разработка дает возможность пользователю снять стресс и


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

2.1.3 Требования к функциональным характеристикам

2.1.3.1 Состав выполняемых функций

Настоящее ТЗ устанавливает следующие требования к составу выполняемых


программой функций:

34
 программа должна иметь «простой» графический интерфейс, содержащий
минимальное количество, интуитивно понятных любому пользователю, кнопок,
осуществляющих основные функции взаимодействия с игровым миром;
 программа должна работать под операционными системами Windows,
начиная с Windows 7, и Android;
 программа должна предоставить возможность осуществление управлением
игрой с помощью манипуляторов – клавиатуры, мыши и тачпада;
 программа должна вести статистику: после прохождения каждого уровня
игрок может наблюдать за временем, потраченным на уровень, а также за тем с
какого раз он прошел уровень (количеством проигрышей);
 программа должна показывать пользователю в ходе игрового процесса
сообщение о проигрыше («Безумие») прямо посередине экрана;
 программа должна содержать в игровом поле кнопку «Пауза», по нажатию
которой игровой процесс на время приостанавливался и позволял бы пользователю
при желании выйти в главное меню;
 программа должна содержать раздел главного меню «Об игре», где
пользователю должна предоставляться возможность прочитать краткую
информацию об игре и правила игры;
 программа должна содержать разнообразный ИИ для врагов, управляемых
компьютером и препятствующему персонажу в прохождении;
 компьютерный ИИ будет представлен в виде нескольких алгоритмов: когда
игрок не контактирует с монстрами, последние двигаются по определенной заранее
траектории (патрулируют местность) или ждут определенных событий, при
контакте с персонажем каждый вид врагов начинает следовать своему собственному
алгоритму поведения. Также существуют специальные враги, которые, например,
могут: просто появиться перед игроком из ниоткуда и стоять на месте, при
преследовании обыскивать «укрытия», ходить сквозь стены и другие препятствия,
стрелять в игрока различными снарядами;
 программа должна в определенные заранее моменты времени
автоматически сохранять текущий процесс прохождения.
35
2.1.3.2 Требования к надёжности

 программа должна отслеживать существование файлов в папке с игрой при


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

2.1.3.3 Требования к мобильности

 программа должна корректно работать на двух популярных платформах


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

2.1.3.4 Условия эксплуатации

Стандартные условия эксплуатации программных продуктов и технических


средств:
 отсутствие экстремальных температур;
 бесперебойное питание компьютера и при необходимости периферийных
устройств;
 стабильная и приемлемая влажность воздуха;
 соблюдение мер безопасности при работе с электричеством.
36
2.1.3.5 Требования к составу и параметрам технических средств

Для корректной работы игрового приложения необходимы:


 стандартный монитор или смартфон;
 стандартная клавиатура, мышь.
Минимальные системные требования:
 компьютер с процессором Intel Core 2 Duo или совместимым;
 оперативная память не менее 2 Гб;
 видеокарта с 512 Мб памяти;
 700 Мб на жестком диске.
Рекомендуемые системные требования с указанием конкретных моделей
устройств будут рассмотрены в техническом обеспечении игрового приложения.

2.1.3.6 Требования к информационной и программной совместимости

Для функционирования программного продукта необходимо наличие


операционной системы Win 7, 8, 10 или совместимой, либо системы Android 2.3+
(для смартфонов). Язык интерфейса – русский.

2.1.3.7 Требования к маркировке и упаковке

Не предъявляются.

2.1.3.8 Требования к информационной и программной совместимости

Не предъявляются.

37
2.1.4 Требования к программной документации

Предварительный состав программной документации, необходимый для


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

2.1.5 Требования к дизайну игрового продукта

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


преимущественно темно-зеленные и темно-синие оттенки. Программы должен быть
выполнен с использованием таких программ, как SAI paint tool и Dragon Bones. Все
графические изображения следует хранить в формате PNG.
Игровое приложение должно корректно отображаться на любом экране.
Пользовательский интерфейс должен включать в себя следующие разделы:
 главное меню:
 раздел «настройки»;
 раздел «играть»;
 интерфейс игрового процесса:
 анимированные спрайты врагов;
 анимированный спрайт главного героя;
 графические показатели процесса прохождения;
 область для отображения диалогов;
 фоновые анимации;

38
 предметы взаимодействие;
 спрайты игровой локации.
 интерфейс при переходах на новые уровни.
Прототип интерфейса игрового процесса представлен на рисунке 18.

Рисунок 18 – Схематичное представление интерфейса

2.1.6 Технические показатели

Визуальная составляющая игры будет представлена в стиле «Dark Fantasy»


(темное фэнтези), с использованием растровой графики; с помощью встроенной
функции Unity – создание префабов можно будет исключить необходимость
создания множества копий различных объектов; использование скриптов в качестве
объектов, не привязанных к чему-либо по умолчанию, уменьшит количество
программного кода, все это позволит увеличить быстродействие выполнение игры и
отрисовку ее графики;

39
2.1.7 Стадии и этапы разработки

Стадии и этапы разработки представлены в таблице 2.

Таблица 2 – Стадии и этапы разработки

Содержание работы Срок Исполнитель этапа разработки


Разработка устава 3 дня Тырышкин Н.Д., Хлуднев А.С.
Разработка технического Лоншаков С.М., Тырышкин Н.Д.,
11 дней
задания Хлуднев А.С.
Выбор и обоснование методов Лоншаков С.М., Тырышкин Н.Д.,
10 дней
решения поставленных задач Хлуднев А.С.
Разработка сценария
Лоншаков С.М., Тырышкин Н.Д.,
взаимодействия и игрового 15 дней
Хлуднев А.С.
баланса
Лоншаков С.М., Тырышкин Н.Д.,
Описание игровых уровней 5 дней
Хлуднев А.С.
Описание игровых персонажей Лоншаков С.М., Тырышкин Н.Д.,
4 дней
и предметов Хлуднев А.С.
Изучение материалов по
5 дней Лоншаков С.М., Тырышкин Н.Д.
программированию на Unity
Изучение материалов по
разработке графического 3 дня Хлуднев А.С.
дизайна и левел-дизайна
Изучение материалов по
проектированию и созданию 2 дня Лоншаков С.М., Хлуднев А.С.
игрового баланса
Создание игровых спрайтов и
60 дней Хлуднев А.С.
бэкграундов

40
Продолжение таблицы 2

Содержание работы Срок Исполнитель этапа разработки


Создание и интегрирование
20 дней Хлуднев А.С.
звуковых компонентов
Создание физического движка 60 дней Лоншаков С.М., Тырышкин Н.Д.
Написание скриптов по
5 дней Лоншаков С.М., Тырышкин Н.Д.
взаимодействию компонентов
Сборка прототипа игры 20 дней Лоншаков С.М., Тырышкин Н.Д.
Портирование игры на Android 5 дней Лоншаков С.М., Тырышкин Н.Д.
Лоншаков С.М., Тырышкин Н.Д.,
Тестирование 5 дней
Хлуднев А.С.
Лоншаков С.М., Тырышкин Н.Д.,
Доработка игры 10 дней
Хлуднев А.С.

2.1.8 Порядок контроля и приемки

После написания всей необходимой перечисленной выше документации и


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

2.1.9 Экономическое обоснование

Первое, что нужно отметить, рынок видеоигр в России растет с каждым годом.
И по данным 2018 года, представленных на рисунке 19, Россия входит в 20 стран с
крупнейшими доходами с создания и сбыта игровых продуктов, занимая 11 место.

41
Рисунок 19 – Рейтинг стран с крупнейшими доходами с видеоигр

Самой популярной платформой в стране на данный момент являются


мобильные устройства, но помимо этого также остается востребованный
персональный компьютер. Данные статистики представлены на рисунке 20.
А так как портирование игр с ПК на Android и обратно является достаточно
легкой и распространённой практикой, то было принято решение выбрать их в
качестве основных устройств, для последующей реализации игрового продукта на
их основе.
В связи с предъявляемыми онлайн-магазинами высокими требованиями и
трудностями в разработке, было решено не импортировать игровое приложение на
консольные платформы, несмотря на их высокую популярность.

42
Рисунок 20 – Рейтинг популярности платформ для игровых приложений

Выбор же жанра для будущего игрового приложения, был обусловлен


несколькими факторами.
Первым фактором стал анализ популярности различных жанров и сеттингов в
видеоиграх. Стоит отметить, что в большинстве случаев при сборе и анализе
статистики «Хоррор» является поджанром «Шутеров», «Приключений» и
«Стратегий», поэтому стоит обратить внимание на популярность именно этих
жанров. По данным с сайта mail.ru, самыми популярными во многих странах
жанрами являются «Приключения», «Шутеры» и «RPG». Данные о популярности
видеоигр по жанрам представлены на рисунке 21. Таким образом, можно сделать
вывод, что «Хорроры» являются популярным видом видеоигр.
Также, исходя из данных взятых с сайта habr.com, довольно большой
популярностью обладают игры с сеттингом заброшенных домов и с наличием
приведений. Данные о популярности различных сеттингов в видеоиграх
представлены на рисунке 22.
Вторым фактором стало ограниченное количество ресурсов. Для выхода из
положения было решено создать небольшой инди-проект в жанре «survival-horror»,
так, как только в данном жанре, при минимально возможном количестве ресурсов,

43
можно получить качественный продукт, имеющий возможность заинтересовать
пользователей.
На основе всего вышеперечисленного, можно сделать вывод, что при наличии
текущего количества ресурсов и возможностей, самым экономически выгодным
решением будет создание 2D игры в жанре «survival-horror», для последующего
выпуска на ПК и Android.

Рисунок 21 – Рейтинг популярности жанров видеоигр

Рисунок 22 – Рейтинг популярности сеттингов в видеоиграх

44
2.2 Описание разработанного продукта по видам обеспечения

2.2.1 Информационное обеспечение

2.2.1.1 Модульная структура работы программы

Для обеспечения работоспособности игры необходимы следующие объекты,


изображенные на рисунке 24. При соблюдении перечисленных требований будет
выполняться решение тех задач, выполнение которых находится в компетенции
соответствующих элементов структуры.
В данной модульной структуре представлены следующие основные элементы:
 Модуль «Игровое меню»;
 Подмодуль «Играть»;
 Модульная единица «Начало игры»;
 Модульная единица «Продолжить»;
 Подмодуль «Параметры»;
 Модульная единица «Изменение звуков»;
 Модульная единица «Изменение музыки»;
 Подмодуль «Об игре»;
 Подмодуль «Выход из игры»;
 Модуль «Операции пользователя»;
 Подмодуль «Обработка нажатия на кнопку»;
 Модуль «Игровой процесс»;
 Подмодуль «UI/UX интерфейс»;
 Подмодуль «Скрипты»;
 Модульная единица «Сохранение игрового процесса»;
 Модульная единица «Обеспечение интерактивного взаимодействия»;
 Модульная единица «ИИ врагов».
Рассмотрим структуру подробнее.

45
Всю программу условно можно разделить на три больших модуля «Игровое
меню», «Операции пользователя» и «Игровой процесс», которые включают в себя
множество подмодулей и модульных единиц, отождествляемых с операциями,
данными (объектами) и преобразованиями внутри приложения.
Модуль игрового меню содержит четыре подмодуля и три модульных
единицы.
Подмодуль «Играть» включает в себя две модульные единицы, отвечающие за
начало новой игры, либо за продолжение уже сохраненной ранее, если такая
присутствует (в противном случае кнопка «Продолжить» будет заблокирована). В
случае начала новой игры, при наличии некоторого прогресса прохождения,
полученного ранее, сохранение будет перезаписано. Иными словами, с точки зрения
«движения» информации в игровом приложении этот элемент структуры отвечает
либо за ее загрузку из памяти жесткого диска компьютера, либо за ее полную
перезапись.
Подмодуль «Параметры», аналогично предыдущему, включает в себя две
модульные единицы, отвечающие непосредственно за настройку звуков окружения
и музыки в игре. Стоит отметить, что полученные данные о выставленных
пользователем значениях с помощью слайдеров, как на рисунке 23, также будут
подвергнуты сохранению и при последующих запусках игры удобные для игрока
настройки будут подгружены сразу без его непосредственного участия.
Последний же из подмодулей внутри первого блока отвечает за выход из игры
с сохранением текущего прогресса игрока в прохождении, при этом сам процесс
записи информации о прохождении будет выполняться в автоматическом режиме
даже при условии аварийного выхода – отключения питания от компьютера,
закрытия приложения через диспетчер задач и тому подобное.
В модуле операций пользователя содержится только один подмодуль, который
отвечает за обработку нажатий пользователем определенных клавиш на игровых
манипуляторах и вызов соответствующих им методов из кода игры.
Связь между фиксациями нажатий и их программной реализацией через
алгоритмы осуществляется с помощью встроенных средств самого Unity, среди

46
которых можно выделить многочисленные методы покадровых проверок, в
частности, на заранее выделенные и записанные программистом условия и на
некоторые физические взаимодействия, предусмотренные самим движком
(столкновения, триггеры или пересечения объектов).
В последнем модуле «Игровой процесс» представлены два самых важных
подмодуля, отвечающих за непосредственно работу игрового приложения.
Первый из них, подмодуль «UI/UX интерфейс», включает в себя все
графические компоненты, а именно такие элементы, как: спрайты главного героя,
противников и игровых объектов, бэкграунды локаций, информационные элементы,
предоставляющие пользователю сведения о текущем прогрессе по уровню. Каждая
из этих структурных частей программы хранится в папке с игрой на жестком диске.
Вторым рассматриваемым компонентом является подмодуль «Скрипты». Он
отвечает за автоматическое сохранение игрового прогресса пользователя в
определенные моменты, а также за искусственный интеллект враждебных
персонажей и за обеспечение интерактивного игрового взаимодействия:
возможность перемещения главного героя по локации и взаимодействия с
определенными объектами, проигрывание катсцен после некоторых
предопределенных действий пользователя.

Рисунок 23 – Слайдеры настройки звука и музыки

47
Рисунок 24 – Модульная структура программы

48
2.2.1.2 Модульная структура работы искусственного интеллекта

Для обеспечения работоспособности игры и правильного


взаимодействия игрока с врагами, последние должны включать в себя
следующие объекты:
 Sprite – текстура врага, как на рисунке 25, для визуального отображения
местоположения и текущего действия персонажа;

Рисунок 25 – Sprite врага

 BoxCollider2D – прямоугольная область по периметру спрайта, как на


рисунке 26, для выполнения условия – враг поймал главного героя, которое
выполняется, когда коллайдер соприкасается с таким же коллайдером у главного
героя;

49
Рисунок 26 – BoxCollider2D

 CircleCollider2D – окружность вокруг спрайта, для выполнения условия –


враг видит главного героя, которое выполняется, когда коллайдер, как на рисунке
27, соприкасается с прямоугольным коллайдером главного героя и между ними нет
непроходимых препятствий;

Рисунок 27 – CirlceCollider2D
50
Rigidbody – объект движка, который управляет положением объекта
через имитацию физики. Причем значения данного объекта у врагов должны
быть следующими:
 Body Type = Dynamic;
 Simulated = true;
 Use Auto Mass = false;
 Mass = 1;
 Linear Drag = 0;
 Angular Drag = 0.05;
 Gravity Scale = 3;
 Collision Detection = Discreate;
 Sleeping Mode = Start Awake;
 Interpolate = None;
 Freeze Rotation X = false;
 Freeze Rotation Y = false;
 Freeze Rotation Z = true. [6]
 Animator – определяет структуру скелета объекта, но контроллер аниматора
(AnimatorController) также требуется для применения анимаций к скелету.
Контроллер аниматора создается Unity и позволяет руководить набором анимаций
для персонажа и переключаться между ними, когда выполняется некоторое условие;
 AudioSource – звуковой файл, который будет использоваться данным
объектом;
 Script – файл с алгоритмами на языке C#, по которым происходит
управление данных объектом;
 RectTransform - используются для графического интерфейса, но также могут
использоваться для других целей. Он используется для хранения и управления
положением, размером и привязкой прямоугольника и поддерживает различные
формы масштабирования.

51
2.2.2 Алгоритмическое обеспечение

2.2.2.1 Алгоритмы работы программы и ее основных составляющих


объектов

Алгоритм работы программы можно представить следующим образом:


 пользователь заходит в игру и выбирает «Продолжить» или «Начать игру»;
 происходит загрузка первого уровня, если начинается новая игра, в
противном случае загружается последнее сохранение;
 вместе с нужным уровнем загружаются спрайт игрового поля, героя,
“генератор” монстров, предметов и прочих элементов игрового процесса, а также
стандартные элементы UI интерфейса;
 для прохождения уровня необходимо выполнить квесты, заданные в его
начале (найти определенное количество фрагментов записок или какой-то ключевой
предмет), для этого в коде программы присутствует счетчик (который также
отображается в виде элемента UI);
 каждый обозначенный промежуток времени (по стандарту, каждый кадр)
счетчик проверяется на заполнение (либо проверяется выполнение ключевого
условия прохождения локации);
 в самом начале уровня персонаж имеет максимальные очки здоровья.
Однако при столкновениях с монстрами и прочих действиях, которые пугают
главного героя, он постепенно будет их терять. Поэтому, если все условия уровня
выполнены, и игрок не потерял данные ему в начале очки здоровья полностью, то
происходит:
 сохранение текущего прогресса;
 переход к следующему уровню.
 если же условия не выполнены, и (или) игрок потерял данные ему в начале
очки здоровья полностью, то:
 игрок попадает в главное меню, где может загрузить последнее
«удачное» сохранение.
52
Все загрузки уровней, спрайтов и элементов интерфейса выполняются
посредством программного кода и некоторого поверхностного управления
пользователем. То есть каждый обозначенный промежуток времени
происходит проверка заранее заданных условий в коде. А затем программа
начинает что-то «делать» (загружать следующие сцены, возвращать героя в
главное меню в случае проигрыша). На рисунках 28 и 29 представлена блок-
схема работы алгоритма.

53
Рисунок 28 – Блок-схема работы алгоритма (часть 1)

Рисунок 29 – Блок-схема работы алгоритма (часть 2)

54
Однако помимо основного алгоритма работы самой программы,
представленного взаимодействием всех элементов, в игре присутствуют множество
других алгоритмов, присущих исключительно определенным объектам.
Рассмотрим каждый из них подробнее в привязке к соответствующим
сущностям.
Объект «Character» (здесь и далее имена идентичны тем, что имеют объекты
на форме визуального редактора Unity 3D).
В игровом процессе обозначает главного героя, за которого
пользователю предстоит пережить всю историю заброшенного особняка.
Управление персонажем будет происходить посредством таких игровых
манипуляторов, как клавиатура или тачпад, в зависимости от выбранной
платформы. Как объект алгоритмизации у него имеется несколько встроенных
алгоритмов, которые условно можно разделить на две группы:
 явные;
 неявные.
Главное отличие между ними заключается в том, что работа алгоритмов
первой группы зачастую управляется пользователем и явно ему видна, то есть
имеет в своем составе какой-либо анимационный эффект, а второй – скрыта
от его глаз и происходит вне его ведома.
В соответствие с описанными выше различиями к первой группе будут
отнесены следующие алгоритмы.
Алгоритм «Run».
Отвечает за передвижение персонажа по карте игрового мира,
регистрируя нажатия на игровых манипуляторах от пользователя. Так как в
игре присутствуют не только горизонтальные поверхности (пол, земля), но и
вертикальные (лестницы), то алгоритм был составлен таким образом, чтобы в
зависимости от текущего местоположения героя вычислялась его возможность
передвижения во всех плоскостях. Сам же выбор направления движения
осуществляет игрок. Код алгоритма представлен в листинге 1.
Листинг 1 – Алгоритм передвижения

55
private void Run(bool isSpider)
{
speed = !isSpider ? 5f:5f;
if ((!audio.isPlaying)) { audio.clip =
Resources.Load<AudioClip>(isSpider?
(ColliderLadderTriger?"st1":"st2") : "st1"); audio.Play(); }
Vector3 direction = (!isSpider ? transform.right :
transform.up) * Input.GetAxis(!isSpider ? "Horizontal" : "Vertical") *
2;
transform.position = Vector3.MoveTowards(transform.position,
transform.position + direction, speed * Time.deltaTime);
sprite.flipX = direction.x < 0.0f;
animator.SetFloat("Multy", !isSpider ? 0.68f:1f);
if (isSpider)
animator.SetInteger("State",ColliderLadderTriger ? 1 : 3);
else
animator.SetInteger("State", 1);
}
Представленный выше алгоритм реализует следующие функции:
 устанавливает скорость передвижения персонажа в зависимости от
направления движения (горизонтально или вертикально);
 устанавливает определенную аудиодорожку – либо звук ходьбы по полу,
либо звук карабканья по лестнице;
 реализует считывание направления движения с игровых манипуляторов
игрока;
 в зависимости от выбранной плоскости передвижения происходит
перемещение персонажа с заданной ранее скоростью;
 в процессе ходьбы по горизонтальной поверхности определяется
направление взгляда главного героя (зависит от направления);
 устанавливается нужная анимация и ее скорость проигрывания. [7]
На рисунках 30 и 31 можно увидеть два различных режима работы
алгоритма «Run».

56
Рисунок 30 – Работа алгоритма «Run» (ходьба)

Рисунок 31 – Работа алгоритма «Run» (лазанье)


Алгоритм «Opening».

57
Отвечает за взаимодействие персонажа с дверьми на карте игрового
мира, регистрируя нажатия на игровых манипуляторах от пользователя. Так
как в игре присутствуют препятствия не только в виде вертикальных стен, но
и в виде закрытых дверей, соединяющих различные комнаты в
горизонтальной плоскости и, по сути, организующие проходы между стенами,
то алгоритм для их открытия необходим для продвижения по уровням. Запуск
алгоритма осуществляет игрок по нажатию клавиши при условии
непосредственной близости персонажа и двери. Код алгоритма представлен в
листинге 2.
Листинг 2 – Алгоритм открытия дверей
private IEnumerator Opening(float t,GameObject Door)
{
Stop = true;
animator.SetInteger("State",2);
yield return new WaitForSeconds(t);
Door.GetComponent<Animator>().Play("Opening");
Door.GetComponent<BoxCollider2D>().enabled = false;
Stop = false;
}
Представленный выше алгоритм реализует следующие функции:
 устанавливает ограничение на любые действия персонажа во время
открытия дверей (и соответственно управление данным объектом для пользователя
на это время недоступно);
 устанавливается нужная анимация для главного героя;
 вызывается задержка на время проигрывания анимации персонажа;
 вызывается проигрывание анимации открытия уже самой двери;
 отключается, созданный на старте уровня, коллайдер двери (невидимый
статический осязаемый игровой объект, чаще всего в виде геометрических фигур,
например, прямоугольника или круга, реализованный, в данном случае, как
препятствие);
 отключается ограничение персонажа на посторонние действия, иными
словами, игрок снова может им управлять.
На рисунке 32 можно увидеть работу алгоритма «Opening».

58
Рисунок 32 – Работа алгоритма «Opening»
Алгоритм «Hider».
Отвечает за взаимодействие персонажа с укрытиями на карте игрового
мира, как на рисунке 33, регистрируя нажатия на игровых манипуляторах от
пользователя. Так как в игре присутствуют враги, которые охотятся за
персонажем и далеко не от всех можно просто убежать, а дать им отпор
попросту невозможно ввиду их сверхъестественного происхождения, то
возможность спрятать персонажа по различным урытиям, разбросанным по
уровням, необходима для прохождения. Запуск алгоритма осуществляет игрок
по нажатию клавиши при условии непосредственной близости персонажа и
укрытия. Код алгоритма представлен в листинге 3.
Листинг 3 – Алгоритм взаимодействия с укрытием
private IEnumerator Hider()
{

59
int layer =
gameObject.GetComponentInChildren<SpriteRenderer>().sortingOrder;
GameObject.FindGameObjectWithTag("Shkaf").GetComponent<Anima
tor>().Play(layer == 0 ? "Shk" : "Khf");
if (layer == 0) EventManager.CallDarkness("Тьма"); else
EventManager.CallDarkness("Свет");
yield return new WaitForSeconds(layer == 0 ? 0f : 1f);
if (layer == 0) Stop = true; else Stop = false;
gameObject.GetComponentInChildren<SpriteRenderer>().sortingOrder =
layer == 0 ? -10 : 0;
gameObject.GetComponentInChildren<Light>().enabled = layer ==
0 ? false : true;
gameObject.tag = layer == 0 ? "HiddenPlayer" : "Player";
}
Представленный выше алгоритм реализует следующие функции:
 запоминается текущее положение персонажа на структуре слоев (для
последующего возращения); [8]
 устанавливается нужная анимация для укрытия в зависимости от того
выходит или входит в него главный герой;
 вызывается сторонний метод, который затемняет все окружение, кроме
небольшого пространства вокруг, для создания ощущения нахождения внутри
укрытия, в случае, если персонаж выходит из него, то происходит ровно
противоположный эффект (через тот же метод, но с другими аргументами);
 вызывается задержка перед «выходом» персонажа, для того чтобы анимация
укрытия успела закончиться (при входе никакой задержки нет);
 включается (или выключается) ограничение персонажа на различные
действия, иными словами, игрок не может (может) им управлять (главный герой не
должен иметь возможность передвигаться или делать что-либо посторонее внутри
укрытия);
 сам персонаж при входе в укрытие перемещается на другой слой (эффект
сокрытия), у него отключается область видимости (в виде тусклого ореола около
головы), изменяется тег объекта (используемый для его определения на игровой
сцене, то есть, например, монстры больше не смогут его преследовать, так как
попросту перестанут его «видеть»).

60
Рисунок 33 – Работа алгоритма «Hider» (для демонстрации специально увеличена
яркость освещения)
Алгоритм «Send».
Отвечает за визуальное отображение мыслей главного героя в виде
сообщений, как на рисунке 34, при взаимодействии с различными объектами
на карте игрового мира, регистрируя нажатия на игровых манипуляторах от
пользователя, столкновения или вхождения в радиус действия триггера
(неосязаемый объект на базе коллайдера, при пересечении которого
происходит какое-либо действие). Так как в игре присутствует множество
разных элементов, не все назначения которых элементарно ясны, то требуется
неким образом доносить до игрока информацию об этих объектах, например в
виде диалоговых сообщений. В отличие от прошлых методов, здесь
реализация алгоритма осуществляется не напрямую, а посредством других
методов (часто неявных), которые будут рассмотрены позже. Код алгоритма
представлен в листинге 4.
Листинг 4 – Алгоритм вывода диалоговых сообщений
private IEnumerator Send(string c, float t,float z)
{
yield return new WaitForSeconds(z);
61
EventManager.CallDialog(c, true);
Timer = t;
reachTimer = false;
}
Представленный выше алгоритм реализует следующие функции:
 вызывается задержка в определенное число секунд перед выводом
сообщения;
 через систему событий сторонним методом вызывается метод вывода текста
на экран через диалоговую компоненту (этому методу сразу же передается строка с
сообщением);
 устанавливается время для таймера и происходит его запуск (таймер
определяет время отображения текста на экране, после истечения которого другой
неявный метод отключает визуальный показ сообщения).

Рисунок 34 – Работа алгоритма «Send»

Ко второй группе неявных алгоритмов будут отнесены следующие.


Алгоритм «Update».

62
Отвечает за проверку выполнения игровых условий или методов каждый
кадр, независимо от нажатий на игровых манипуляторах, столкновений
объектов или их вхождений в радиус действия триггеров. В работе программы
он предсталвен связующим звеном для работы других методов и отличается
от последних тем, что является встроенным методом Unity. Код алгоритма
представлен в листинге 5.
Листинг 5 – Алгоритм «Update»
private void Update()
{
if (!reachTimer && Timer >= 0) Timer -= Time.deltaTime;
else { reachTimer = true; EventManager.CallDialog("", false);}
if (!Stop)State = CharState.Idle;
SenAnimationHero();
if (Input.GetButton("Horizontal")&&!Stop) Run(false);
else if (Input.GetButton("Vertical") && isClimbing&& !Stop)
Run(true);
else if (Hide && Input.GetKeyUp(KeyCode.Space))
{
StartCoroutine("Hider");
}
else if (Open &&!Stop&& Input.GetKeyUp(KeyCode.E))
{
StartCoroutine(Opening(2f, NearDoor));
}
}
Представленный выше алгоритм реализует следующие функции:
 реализует сокрытие диалоговой компоненты с сообщением в течение
некоторого времени после ее появления;
 регистрирует нажатия пользователя на манпуляторах и вызывает
соответствующие методы: движение по горизонтали или вертикали, открытие двери,
использование укрытий; [9]
 вследствие вызова других методов происходит переключение анимации
главного героя (а в случае отсутствия воздействия со стороны пользователя
начинает проигрываться анимация стояния на месте у персонажа);
 каждый кадр вызывается метод «SenAnimationHero», который будет
рассмотрен далее.
Алгоритм «SenAnimationHero».

63
Отвечает за проверку такого игрового условия, как нахождение главного
героя на вертикальной лестнице (каждый кадр). Данный метод в зависимости
от текущего положения персонажа на лестнице опосредованно вызывает
проигрывание соответствующей анимации. По сути, является расширением
метода «Run», в котором прописано движение по вертикали, и предоставляет
для этого метода более четкие границы смены анимации ходьбы и лазанья.
Код алгоритма представлен в листинге 6.
Листинг 6 – Алгоритм «SenAnimationHero»
private void SenAnimationHero()
{
float NewPositionOnY = transform.position.y;
bool up;
up = NewPositionOnY - OldPositionOnY > 0;
OldPositionOnY = NewPositionOnY;
RaycastHit2D[] hit = new RaycastHit2D[5];
int hitcount = Physics2D.RaycastNonAlloc(new
Vector2(transform.position.x, transform.position.y), Vector2.right,
hit, 10f);
bool check1=false, check2=false;
for (int i = 0; i < hitcount; i++)
{
if (hit[i].collider != null &&
hit[i].collider.gameObject.tag == "Pol1")
check1 = true;
if (hit[i].collider != null &&
hit[i].collider.gameObject.tag == "Pol2")
check2 = true;
}
if (up)
{
if(check1)
ColliderLadderTriger = true;
if (check2)
ColliderLadderTriger = false;
}
else
{
if (check1)
ColliderLadderTriger = false;
if (check2)
ColliderLadderTriger = true;
}
}
Алгоритмы «OnTriggerEnter2D», «OnTriggerStay2D»,
«OnTriggerExit2D».

64
Встроенные методы Unity, которые отвечают за проверки таких игровых
условий, как вхождение (коллайдера привязанного к главному герою) в
область триггера, перемещение внутри и выход из нее (каждый кадр)
соответственно. При выполнении данных условий могут напрямую или
опосредовано вызывать другие методы, например, вывод текстового
сообщения на экран или переключение состояния главного героя, при котором
он способен спрятаться за укрытием или карабкаться по лестнице. Ввиду
слишком большого количества различных условий внутри алгоритма блок с
листингом кода приводиться не будет.
Алгоритмы «OnCollisionEnter2D», «OnCollisionExit2D».
Встроенные методы Unity, которые отвечают за проверки таких игровых
условий, как вхождение (коллайдера привязанного к главному герою) в
область столкновения с другим коллайдером и выход из нее (каждый кадр)
соответственно. Оба этих метода отвечают только за одну функцию –
переключение состояния главного героя, при котором он способен открыть
дверь (так как находится рядом с ней), либо нет. При этом первый метод
также вызывает диалоговую компоненту, сообщающую о возможности
действия. Код алгоритмов представлен в листинге 7.
Листинг 7 – Алгоритмы «OnCollisionEnter2D» и «OnCollisionExit2D»
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Door")
{
Open = true;
NearDoor = collision.gameObject;
StartCoroutine(Send("Можно попробовать открыть дверь...",
5f, 0f));
}
}
private void OnCollisionExit2D(Collision2D collision)
{
if (collision.gameObject.tag == "Door")
{
Open = false;
NearDoor = null;
}
}
Алгоритмы «Awake», «Start».

65
Встроенные методы Unity, которые выполняются один раз – «Start» на
старте сцены, «Awake» до старта сцены. При этом первый метод для данного
объекта (персонажа) используется для подключения различных компонентов
(к примеру, «физического тела»), а второй задает главному герою различные
стартовые характеристики (например, скорость, возможность открыть дверь).
Код алгоритмов представлен в листинге 8.
Листинг 8 – Алгоритмы Awake» и «Start»
private void Awake()
{
rigidbody = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
sprite = GetComponentInChildren<SpriteRenderer>();
audio = GetComponent<AudioSource>();
}
private void Start()
{
NearDoor = null;
isClimbing = false;
animator.SetFloat("Multy", 0.68f);
Hide = false;
reachTimer = true;
Timer = 5f;
Open = false;
Stop = false;
OldPositionOnY = transform.position.y;
}
Следующим, не менее важным, объектом является «RoomPlacer».
В игровом процессе обозначает пустой (невидимый и неосязаемый)
объект, существующий на игровой сцене. К его главной функции можно
отнести процедурную генерацию нескольких элементов:
 комнат;
 дверей;
 монстров.
Главными в этом списке являются именно комнаты, все остальное – так
или иначе связано именно с ними (монстры, появившиеся в определенной
комнате, чаще всего будут патрулировать именно ее, а двери непосредственно
привязаны к структурам комнат).

66
Как и персонаж, «RoomPlacer» имеет несколько алгоритмов.
Рассмотрим каждый из них подробнее.
Алгоритм «Start».
Встроенный метод Unity, который выполняется один раз на старте
сцены. Преследует три важные функции – создание пустого массива, куда
впоследствии будут «заноситься» уже созданные комнаты, определение
стартовой комнаты, с которой начнется генерация и собственно запуск самого
алгоритма процедурной генерации. Код алгоритма представлен в листинге 9.
Листинг 9 – Алгоритм старта процедурной генерации
private void Start()
{
spawnedRooms = new Room[10, 4];
spawnedRooms[4, 0] = StartingRoom;
for (int i = 0; i < 10; i++)
{
Placing();
}
}
Алгоритм «Placing».
Отвечает за такую часть процедурной генерации, как
рандомизированное размещение некоторых перечисленных выше в списке
игровых объектов на сцене при старте последней в соответствии с
определенными ограничениями, вызванными размерами массива комнат,
положением стартовой точки и количеством генерируемых элементов,
которые определялись в прошлом алгоритме. При этом реализация метода
осуществляется не полностью напрямую, а частично, так как внутри
вызывается другой основной алгоритм, реализующий оставшую часть
генерации. Код алгоритма представлен в листинге 10.

Листинг 10 – Алгоритм «Placing»


private void Placing()
{
HashSet<Vector2Int> vacantPlaces = new HashSet<Vector2Int>();
for (int x = 0; x < spawnedRooms.GetLength(0); x++)
{
for (int y = 0; y < spawnedRooms.GetLength(1); y++)
{

67
if (spawnedRooms[x, y] == null) continue;
int maxX = spawnedRooms.GetLength(0) - 1;
int maxY = spawnedRooms.GetLength(1) - 1;
if (x > 0 && spawnedRooms[x - 1, y] == null)
vacantPlaces.Add(new Vector2Int(x - 1, y));
if (x < maxX && spawnedRooms[x + 1, y] == null)
vacantPlaces.Add(new Vector2Int(x + 1, y));
if (y > 0 && spawnedRooms[x, y - 1] == null)
vacantPlaces.Add(new Vector2Int(x, y - 1));
if (y < maxY && spawnedRooms[x, y + 1] == null)
vacantPlaces.Add(new Vector2Int(x, y + 1));
}
}
Room newRoom = Instantiate(RoomPrefabs[Random.Range(0,
RoomPrefabs.Length)]);
newRoom.transform.SetParent(C.transform, false);
int r = Random.RandomRange(0, 2);
Monsters ghost=null;
if (r == 1)
{
int c = Random.RandomRange(0, 5);
ghost = Instantiate(GG[с]);
ghost.room = newRoom;
ghost.transform.SetParent(C.transform, false);
}
int limit = 666;
while (limit-- > 0)
{
Vector2Int position =
vacantPlaces.ElementAt(Random.Range(0, vacantPlaces.Count));
if (Connect(newRoom, position))
{
newRoom.transform.position = new Vector3(position.x -
4, position.y ) * 33;
if (r == 1) ghost.transform.localPosition = new
Vector3(newRoom.transform.localPosition.x,
newRoom.transform.localPosition.y, -304f);
spawnedRooms[position.x, position.y] = newRoom;
return;
}
}
Destroy(newRoom.gameObject);
}
Представленный выше алгоритм реализует множество различных
функций:
 организация списка, состоящего из уникальных значений – вакантных мест
для создания комнат;

68
 в цикле проверяются все уже созданные комнаты, занесенные в массив, и
определяются их возможные «соседи» (которые заносятся в соответствующий
список);
 из заранее заготовленных префабов (заготовок) комнат и монстров
выбираются радномные и на их основе создаются уже новые объекты, при этом
положение монстра сразу же соотносят с положением самой комнаты;
 из списка вакантных мест выбирается рандомное и с помощью вызова
метода «Connect» в итеративной форме проверяется возможность подсоединения
новой комнаты к соседней, в случае неудачи выбирается другое место.
Алгоритм «Connect».
Отвечает за такую часть процедурной генерации, как
рандомизированное создание проходов между комнатами. Всего возможны
четыре варианта: два прохода слева и справа в виде проемов (или дверей) и
два прохода вниз и вверх в виде дыр (и лестницы) в полу или в потолке
соответственно. Реализация метода осуществляется не полностью напрямую, а
частично, так как внутри вызывается другой алгоритм «RandDoor»,
отвечающий за создание дверей. Код алгоритма представлен в листинге 11.
Листинг 11– Алгоритм «Connect»
private bool Connect(Room room, Vector2Int p)
{
int maxX = spawnedRooms.GetLength(0) - 1;
int maxY = spawnedRooms.GetLength(1) - 1;
List<Vector2Int> neighbours = new List<Vector2Int>();
if (room.DoorU != null && p.y < maxY && spawnedRooms[p.x, p.y
+ 1]?.DoorD != null) neighbours.Add(Vector2Int.up);
if (room.DoorD != null && p.y > 0 && spawnedRooms[p.x, p.y -
1]?.DoorU != null) neighbours.Add(Vector2Int.down);
if (room.DoorR != null && p.x < maxX && spawnedRooms[p.x + 1,
p.y]?.DoorL != null) neighbours.Add(Vector2Int.right);
if (room.DoorL != null && p.x > 0 && spawnedRooms[p.x - 1,
p.y]?.DoorR != null) neighbours.Add(Vector2Int.left);
if (neighbours.Count == 0) return false;
Vector2Int selectedDirection = neighbours[Random.Range(0,
neighbours.Count)];
Room selectedRoom = spawnedRooms[p.x + selectedDirection.x,
p.y + selectedDirection.y];

if(selectedDirection == Vector2Int.up)
{

69
room.DoorU.SetActive(true);
selectedRoom.DoorD.SetActive(true);
selectedRoom.D.enabled =false;
}
else if (selectedDirection == Vector2Int.down)
{
room.DoorD.SetActive(true);
selectedRoom.DoorU.SetActive(true);
room.D.enabled =false;
}
else if (selectedDirection == Vector2Int.right)
{
room.DoorR.SetActive(true);
selectedRoom.DoorL.SetActive(true);
room.R.enabled =false;
selectedRoom.L.enabled =false;
RandDoor(ref room.DR, ref selectedRoom.DL);
}
else if (selectedDirection == Vector2Int.left)
{
room.DoorL.SetActive(true);
selectedRoom.DoorR.SetActive(true);
room.L.enabled =false;
selectedRoom.R.enabled =false;
RandDoor(ref room.DL, ref selectedRoom.DR);
}
return true;
}
Представленный выше алгоритм реализует следующие функции:
 проверяются все направления вокруг комнаты и организуется список,
состоящий из всех возможных «соседей»;
 рандомно выбирается соседняя комната и к ней в зависимости от
направления прокладывается «маршрут» в виде двух проемов (со стороны самой
комнаты и «соседа»);
 в процессе прокладывания пути вызывается метод «RandDoor», реализация
которого будет описана ниже.
Алгоритм «RandDoor».
Отвечает за рандомное создание двери в просвете между комнатами. Так
как при присоединении комнат по бокам получаются двойные проемы, то
требуется метод, который выбирал бы всего лишь одну из возможных сторон
и создавал там дверь. Код алгоритма представлен в листинге 12.
Листинг 12– Алгоритм «RandDoor»

70
private void RandDoor(ref GameObject DL, ref GameObject DR)
{
int r = Random.RandomRange(0, 2);
switch (r)
{
case 0:
DL.SetActive(true);
DR.SetActive(false);
break;
case 1:
DL.SetActive(false);
DR.SetActive(true);
break;
}
}
На рисунках 35, 36 и 37 приведены возможные примеры генерации
уровня.

Рисунок 35 – Первый вариант генерации уровня (сложный)

71
Рисунок 36 – Второй вариант генерации уровня (средний)

Рисунок 37 – Третий вариант генерации уровня (простой)


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

72
Рисунок 38 – Камера выходит за границы уровня
Именно поэтому для камеры тоже были написаны несколько
алгоритмов, которые будут подробно расписаны далее.
Алгоритм «Clamp».
Отвечает за ограничения движения камеры по уровню во избежание
ситуации, описанной выше (когда ее вид выходит за пределы уровня).
Работает только при приближенном виде, в случае отдаления камеры, для
просмотра всей сцены сразу, метод не производит никаких эффектов. Листинг
алгоритма ввиду наличия большого количества строк кода здесь приводится
не будет, однако будут описаны несколько важных функций, реализуемых
методом:

73
 на основе ширины текущего разрешения настраивается допустимый
«отступ» справа и слева;
 из центра камеры в каждую из сторон (вправо и влево) откладываются два
невидимых луча по длине «отступа», как на рисунке 39;
 лучи каждый кадр «проверяют» выделенный им промежуток на присутствие
какого-либо объекта, в случае нахождения препятствия в виде стены камера
центрируется на ней и прекращает свое движение до тех пор, пока персонаж не
отойдет от стены, или, иными словами, пока луч снова не «сообщит», что на
протяжении его расстояния нет границы уровня (либо другого нежелательного
объекта).

Рисунок 39 – Графическое представление лучей (специально отрисованы желтыми


отрезками для демонстрации)
Алгоритм «Update».
Встроенный метод Unity, который отвечает за вызов работы
предыдущего метода. Кроме того реализует возможность физического
отдаления камеры, как на рисунке 40, от персонажа для просмотра всей
структуры уровня в целом, контролируемую пользователем с помощью
игровых манипуляторов. Код алгоритма представлен в листинге 13.
Листинг 13– Алгоритм работы камеры
private void Update()

74
{
if (Input.GetKeyUp(KeyCode.Tab))
tabbed = !tabbed;
if (tabbed && q < 22f || !tabbed && q > 8f)
{
if (tabbed)
{
q += 0.025f;
vol += 0.5f / 560f;
Vector3 vvv = new Vector3(transform.position.x,
transform.position.y + 0.025f, transform.position.z);
transform.position = vvv;
}
else
{
q -= 0.1f;
vol -= 0.5f / 140f;
Vector3 vvv = new Vector3(transform.position.x,
transform.position.y - 0.1f, transform.position.z);
transform.position = vvv;
}
_camera.orthographicSize = q;
EventManager.SetVolume(vol);
}
else if (!tabbed&& t.GetComponentInChildren<SpriteRenderer>())
Clamp();
Ниже приведены несколько важных реализуемых функций:
 считывается нажатие пользователем клавиши отдаления камеры (в случае,
если она уже отдалена, то наоборот будет произведено приближение);
 в процессе отдаления немного изменяется положение камеры
(центрирование на середине уровня) и звук окружения (становится лучше слышно
звуки вне дома);
 в случае приближенной камеры каждый кадр проверяется необходимость в
вызове метода «Clamp»;
 изменение звука происходит через событийный аппарат посредством
вызова метода «SetVolume».

75
Рисунок 40 – Отдаление камеры
Алгоритм «Start».
Встроенный метод Unity, который выполняется один раз на старте
сцены. Преследует две важные функции – задает камере различные стартовые
характеристики и подключает необходимые для работы приведенных выше
методов компоненты. Код алгоритма представлен в листинге 14.
Листинг 14– Алгоритм работы стартового метода у камеры
private void Start()
{
_camera = GetComponent<Camera>();
tabbed = false;
q = 8f;
vol = 0.5f;
t = GameObject.FindGameObjectWithTag("Player");
}
Последним из рассматриваемых объектов является «Manager».
В игровом процессе обозначает пустой (невидимый и неосязаемый)
объект, существующий в единичном экземпляре на всех игровых сценах, в
отличие от других элементов при запуске новой сцены не пересоздается и не
удаляется. Работает только в связке с другим классом (и соответственно с
другим объектом) «EventManager», который имеет в своем составе различные
предопределённые события и методы для их вызова из любого места кода, в
свою очередь в классе «Manager» эти события связываются с идентичными по
сигнатуре методами (событийный аппарат).

76
Как и любой из объектов выше, «Manager» тоже имеет несколько
алгоритмов. Рассмотрим каждый из них подробнее.
Алгоритм «Awake».
Встроенный метод Unity, который выполняется один раз до старта
сцены. Преследует всего две цели – соединить события из «EventManager» с
методами из «Manager» и указать неразрушаемость, связанного с алгоритмом
объекта. Код алгоритма представлен в листинге 15.
Листинг 15– Алгоритм работы «связующего» метода у менеджера
private void Awake()
{
DontDestroyOnLoad(this.gameObject);
EventManager.Darkness +=Fade;
EventManager.Dialog += Conversation;
EventManager.Volume += EditVolume;
EventManager.Teleporting += Teleport;
EventManager.Dead += Death;
}
Алгоритм «Teleport».
Реализует функцию перехода с одного уровня на другой (путем вызова
этого метода через «EventManager» в другом месте кода при выполнении
каких-то условий). Код алгоритма представлен в листинге 16.
Листинг 16 – Алгоритм перехода между уровнями
private void Teleport()
{
SceneManager.LoadScene(++Count);
}
Алгоритм «Conversation».
Реализует функцию вывода переданного в качестве аргумента текста в
диалоговое окно (нужная строка передается через «EventManager» из другого
места). Код алгоритма представлен в листинге 17.
Листинг 17 – Алгоритм перехода между уровнями
private void Conversation(string c,bool t)
{
GameObject Dial =EventManager.objRefs["Dialog " +
SceneManager.GetActiveScene().buildIndex];
Dial.GetComponentInChildren<Text>().text = c;
Dial.SetActive(t);
}
Ниже приведены две реализуемые функции:
77
 из массива диалоговых компонент выбирается нужная (в зависимости от
сцены);
 на экран выводится сообщение с текстом переданным в качестве аргумента
функции.
Алгоритм «Fade».
Реализует функцию затемнения экрана и включения подсветки в виде
ореола у определенных объектов (к примеру, укрытий). Код алгоритма
представлен в листинге 18.
Листинг 18 – Алгоритм затемнения экрана
private void Fade( string c)
{
switch (c)
{
case "Свет":
foreach (GameObject g in
GameObject.FindGameObjectsWithTag("Lights"))
{
g.GetComponentInChildren<Light>().enabled = false;
}
dark.color = Color.white;
break;
case "Тьма":
foreach (GameObject g in
GameObject.FindGameObjectsWithTag("Lights"))
{
g.GetComponentInChildren<Light>().enabled = true;
}
dark.color = new Color(0.1f, 0.1f, 0.1f, 1f);
break;
}
}
Алгоритм «EditVolume».
Реализует функцию изменения звука (предварительно находит объект на
текущей сцене, связанный со звуковым компонентом). Код алгоритма
представлен в листинге 19.
Листинг 19 – Алгоритм изменения звука
private void EditVolume(float value)
{
GameObject c = GameObject.FindGameObjectWithTag("Canv");
AudioSource audio = c.GetComponent<AudioSource>();
audio.volume = value;
}

78
Алгоритм «Death».
Реализует функцию «смерти» главного героя после физического
столкновения с монстрами или другой опасностью. Код алгоритма
представлен в листинге 20.
Листинг 20 – Алгоритм «смерти» персонажа
private void Death()
{
Character target =
GameObject.FindGameObjectWithTag("Player").GetComponent<Character>();

GameObject.FindGameObjectWithTag("SpriteChar").SetActive(false);
target.Stoping = true;
target.GetComponent<Collider2D>().enabled = false;
target.GetComponent<Rigidbody2D>().gravityScale = 0;
DeadScreen = GameObject.FindGameObjectWithTag("DeadScreen");
DeadScreen.GetComponent<Image>().color = new Color(1f, 1f, 1f,
1f);
}
Ниже приведены две реализуемые функции:
 у персонажа на сцене отключаются практически все компоненты (в
частности, реализующие его отображение, передвижение и физические
взаимодействия);
 на весь экран выводится сообщение (в виде изображения) о проигрыше
(безумном помешательстве) персонажа.

2.2.2.2 Алгоритмы работы искусственного интеллекта

Алгоритм поведения каждого монстра (врага) можно разделить на 2


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

79
Смена значения переменной «patrul» происходит, когда игрок подходит
к врагу и между ними нет непроходимых препятствий (например, закрытой
двери).
На рисунке 41 представлена блок-схема работы данного алгоритма.

Рисунок 41 – Блок-схема работы алгоритма

Код алгоритма представлен в листинге 21.


Листинг 21 – Алгоритм патрулирования монстров
private void OnTriggerStay2D(Collider2D other)
{
if (other.gameObject.tag == "Player")
{
RaycastHit2D[] hit = new RaycastHit2D[7];
int hitcount = Physics2D.RaycastNonAlloc(new
Vector2(transform.position.x, transform.position.y),
transform.position.x > target.transform.position.x ? Vector2.left

80
: Vector2.right, hit, Vector3.Distance(transform.position,
target.transform.position));
bool check = false;

for (int i = 0; i < hitcount; i++)


{
if (hit[i].collider != null &&
hit[i].collider.gameObject.tag == "Door")
{ check = true; break; }
}
if (!check)
{
ExitTrigerTeleport = false;
patrul = false;
sprite.flipX =
gameObject.transform.position.x > target.transform.position.x;
}
}
else if (other.gameObject.tag == "HiddenPlayer")
patrul = true;

}
bool ExitTrigerTeleport = false, GhostBlink=false;
private void OnTriggerExit2D(Collider2D other)
{
if (other.gameObject.tag == "Player")
{
patrul = true;
ExitTrigerTeleport = true;
Return;
}

}
//отдельный метод для призрака распознавания того, что
призрак находится в зоне контакта с игроком. Он использует
Trigger так как, коллайдеры призрака являются триггерами.
private void OnTriggerEnter2D(Collider2D collider)
{
if (collider.gameObject.tag == "Player")
{
if (gameObject.tag == "Ghost")
{
patrul = false;
return;
}
}
Теперь рассмотрим подробнее алгоритмы каждого из врагов при
условии обнаружения персонажа.
Алгоритм врага «Изгой».

81
При патрулировании данный монстр передвигается между двумя
точками – краями комнаты, в которой он был заспавнен (создан). Причем,
когда персонаж доходит до точки, спрайт (текстура персонажа)
разворачивается (зеркально отражается). Алгоритм патруля представлен на
рисунке 42.
При преследовании главного героя, «Изгой» медленно передвигается за
первым, однако раз в 3 секунды противник телепортируется в
противоположную, от главного героя, сторону и продолжает преследовать
игрока. Происходит это следующим образом:
 если переменная TeleportTime <= 0, что значит, что прошло 3 секунды с
момента предыдущего полного исполнения алгоритма, то:
 запускается анимация и звук телепорта, враг остается на том же месте;
 спустя пол секунды, что эквивалентно половине анимации, спрайт
врага разворачивается и меняется местоположение врага за спину игрока,
после чего анимация завершается в течение еще пол секунды;
 враг продолжает преследование игрока, а переменной TeleportTime
присваивается значение 3 (эквивалентно 3 секундам).
 если же переменная TeleportTime > 0, то ей присваивается разница между
ней самой и прошедшим временем DeltaTime (TeleportTime = TeleportTime –
DeltaTime). Сама DeltaTime берется из игрового движка Unity и возвращает время,
прошедшее между кадрами.
Для контроля выполнения перемещения врага в нужный момент
анимации, в программе так же присутствуют две переменный TeleportDelay1 и
teleportDelay2, которым присваиваются значения по аналогии с переменной
TeleportTime.

82
Рисунок 42 – Блок-схема работы алгоритма патруля «Изгоя»

Таким образом, в течение 1 секунды, когда воспроизводится анимация и


звук телепорта, враг не представляет угрозы для игрока и у последнего
появляется возможность «уйти» от преследователя. Однако, стоит заметить,
что если во время телепортации врага, игрок убежит на определенное
расстояние, когда включается патрулирование (patrul = true), переменным
TeleportTime и TeleportDelay присваиваются начальные значения, а анимация
прерывается. [10] Данный алгоритм представлен на рисунке 43.

83
Рисунок 43 – Блок-схема работы алгоритма преследования «Изгоя»

Код алгоритма представлен в листинге 22.


Листинг 22 – Алгоритм «Изгоя»
if (patrul)
{
TeleportDelay = TeleportTime;

84
TeleportDelay2 = 1f;
TeleportDelay3 = 1f;
animator.SetInteger("State", 1);
sprite.flipX =
gameObject.transform.position.x >=
moveSpots[randomSpot].position.x;
transform.position = Vector3.MoveTowards
(new Vector3(transform.position.x,
transform.position.y, transform.position.z), new
Vector3(moveSpots[randomSpot].position.x, transform.position.y,
transform.position.z), speed * Time.deltaTime);
State = CharState.Run;
if (Vector2.Distance(transform.position,
moveSpots[randomSpot].position) < 10f)
{

if (waitTime <= 0)
{
randomSpot = Random.Range(0,
moveSpots.Length);
waitTime = 0.1f;
}

else waitTime -= Time.deltaTime;


}
}
Else{
if (TeleportDelay <= 0)
{
animator.SetInteger("State", 2);
if(Audio != null && !
Audio.isPlaying)Audio.Play();
if (TeleportDelay2 <= 0 &&
TeleportDelay3 >= 1f)
{
Vector3 v = new Vector3();
if (checki != -1)
{
v.x =
hit[checki].collider.gameObject.transform.position.x - 3f *
(sprite.flipX ? -1 : 1);
Vector3 v2 = new Vector3();
v2.x =
target.transform.position.x - 1 * (sprite.flipX ? -1 : 1);
v2.y =
target.transform.position.y;
v2.z =
target.transform.position.z;
target.transform.position = v2;
}
else
v.x =
target.transform.position.x - 6f * (sprite.flipX ? 1 : -1);

85
v.y = transform.position.y;
v.z = transform.position.z;
transform.position = v;

TeleportDelay3 =0.98f;
}
else if(TeleportDelay2 > 0 &&
TeleportDelay3 >= 1f)
{
TeleportDelay2 -= Time.deltaTime;
}

if (TeleportDelay2 <= 0 &&


TeleportDelay3 > 0f && TeleportDelay3 <=0.98f)
{
TeleportDelay3 -= Time.deltaTime;
}
else if (TeleportDelay2 <= 0 &&
TeleportDelay3 <= 0f)
{
TeleportDelay = TeleportTime;
TeleportDelay2 = 1f;
TeleportDelay3 = 1f;
animator.SetInteger("State", 1);
}
}
else
{
transform.position = Vector3.MoveTowards
(new Vector3(transform.position.x,
transform.position.y, transform.position.z), new
Vector3(target.transform.position.x, transform.position.y,
transform.position.z), speed * Time.deltaTime);

TeleportDelay -= Time.deltaTime;
}
}

Алгоритм врага «Главный изгой».


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

86
перед ним находится закрытая дверь. Запускаются анимация и звук
телепортации, на половине проигрывания которых персонаж перемещается в
непроходимую комнату к закрытой двери. После чего он продолжает
движение к контрольной точке, при достижении которой, он разворачивается,
и будет двигаться в противоположную сторону. Если персонаж встретит, и
будет гнаться за игроком, а потом потеряет его, движение продолжится в
заданную контрольную точку. Алгоритм патруля представлен на рисунке 44.
При преследовании главного героя, «Изгой» медленно передвигается за
первым, однако раз в 3 секунды противник телепортируется в
противоположную, от главного героя, сторону и продолжает преследовать
игрока. Происходит это следующим образом:
 если переменная TeleportTime <= 0, что значит, что прошло 3 секунды с
момента предыдущего полного исполнения алгоритма, то:
 запускается анимация и звук телепорта, враг остается на том же месте;
 спустя пол секунды, что эквивалентно половине анимации, спрайт
врага разворачивается и меняется местоположение врага за спину игрока,
после чего анимация завершается в течении еще пол секунды;
 враг продолжает преследование игрока, а переменной TeleportTime
присваивается значение 3 (эквивалентно 3 секундам).
 если же переменная TeleportTime > 0, то ей присваивается разница между
ней самой и прошедшим временем DeltaTime (TeleportTime = TeleportTime –
DeltaTime). Сама DeltaTime берется из игрового движка Unity и возвращает время,
прошедшее между кадрами. [11]
Для контроля выполнения перемещения врага в нужный момент
анимации, в программе так же присутствуют две переменные TeleportDelay1 и
teleportDelay2, которым присваиваются значения по аналогии с переменной
TeleportTime.

87
Рисунок 44 – Блок-схема работы алгоритма патруля «Главного изгоя»

Таким образом, в течение 1 секунды, когда воспроизводится анимация и


звук телепорта, враг не представляет угрозы для игрока и у последнего
появляется возможность «уйти» от преследователя. Однако стоит заметить,

88
что если во время телепортации врага, игрок убежит на определенное
расстояние, когда включается патрулирование (patrul = true), переменным
TeleportTime и TeleportDelay присваиваются начальные значения, а анимация
прерывается. Данный алгоритм кратко представлен на рисунке 45.

Рисунок 45 – Блок-схема работы алгоритма преследования «Главного изгоя»

89
Код алгоритма представлен в листинге 23.
Листинг 23 – Алгоритм «Главного изгоя»
if (patrul)
{
if (gameObject.tag == "Man2")
{
moveSpots = new Transform[2];
RaycastHit2D[] hit1 = new RaycastHit2D[25], hit2 = new
RaycastHit2D[25];
int indexwall1 = -1, indexwall2 = -1;
int hitcount01 = Physics2D.RaycastNonAlloc(new
Vector2(transform.position.x, transform.position.y), Vector2.left,
hit1, Mathf.Infinity);
for (int i = 0; i < hitcount01; i++)
if (hit1[i].collider != null &&
hit1[i].collider.gameObject.tag == "Wall")
{
indexwall1 = i;
break;
}
hitcount01 = Physics2D.RaycastNonAlloc(new
Vector2(transform.position.x, transform.position.y), Vector2.right,
hit2, Mathf.Infinity);
for (int i = 0; i < hitcount01; i++)
if (hit2[i].collider != null &&
hit2[i].collider.gameObject.tag == "Wall")
{
indexwall2 = i;
break;
}
moveSpots[0] =
hit1[indexwall1].collider.gameObject.transform;
moveSpots[1] =
hit2[indexwall2].collider.gameObject.transform;

if (ExitTrigerTeleport)
{
TeleportDelay = TeleportTime;
TeleportDelay2 = 1f;
TeleportDelay3 = 1f;
ExitTrigerTeleport = false;
}
animator.SetInteger("State", 1);
sprite.flipX = gameObject.transform.position.x >=
moveSpots[randomSpot].position.x;
if (!animateteleport) {
transform.position = Vector3.MoveTowards
(new Vector3(transform.position.x,
transform.position.y, transform.position.z), new
Vector3(moveSpots[randomSpot].position.x, transform.position.y,
transform.position.z), speed * Time.deltaTime);
State = CharState.Run;
90
}
if (Vector2.Distance(transform.position,
moveSpots[randomSpot].position) < 12f)
{
if (waitTime <= 0)
{
randomSpot = Random.Range(0,
moveSpots.Length);
waitTime = 0.1f;
}
else waitTime -= Time.deltaTime;
}
else
{
RaycastHit2D[] hit = new RaycastHit2D[15];
int hitcount = Physics2D.RaycastNonAlloc(new
Vector2(transform.position.x, transform.position.y),
transform.position.x > moveSpots[randomSpot].position.x ? Vector2.left
: Vector2.right, hit, 5f);
int checki = -1;
for (int i = 0; i < hitcount; i++)
if (hit[i].collider != null &&
hit[i].collider.gameObject.tag == "Door")
{
checki = i;
break;
}
if (checki != -1)
{
animateteleport = true;
animator.SetInteger("State", 2);
if (Audio != null && !Audio.isPlaying)
Audio.Play();
if (TeleportDelay2 <= 0 && TeleportDelay3 >=
1f)
{
if (checki != -1)
{
Vector3 v = new Vector3();
v.y = transform.position.y;
v.z = transform.position.z;
v.x =
hit[checki].collider.gameObject.transform.position.x - 5f *
(sprite.flipX ? 1 : -1);
transform.position = v;
}
TeleportDelay3 = 0.98f;
animateteleport = false;
}
else if (TeleportDelay2 > 0 && TeleportDelay3
>= 1f)
{
TeleportDelay2 -= Time.deltaTime;

91
}

if (TeleportDelay2 <= 0 && TeleportDelay3 > 0f


&& TeleportDelay3 <= 0.98f)
{
TeleportDelay3 -= Time.deltaTime;
}
else if (TeleportDelay2 <= 0 && TeleportDelay3
<= 0f)
{
TeleportDelay = TeleportTime;
TeleportDelay2 = 1f;
TeleportDelay3 = 1f;
animator.SetInteger("State", 1);
}

}
}
}
else
{
RaycastHit2D[] hit = new RaycastHit2D[7];
int hitcount = Physics2D.RaycastNonAlloc(new
Vector2(transform.position.x, transform.position.y),
transform.position.x > target.transform.position.x ? Vector2.left :
Vector2.right, hit, 10f);

int checki = -1;


for (int i = 0; i < hitcount; i++)
if (hit[i].collider != null &&
hit[i].collider.gameObject.tag == "Wall")
checki = i;
if (TeleportDelay <= 0)
{
animator.SetInteger("State", 2);
if (Audio != null && !Audio.isPlaying)
Audio.Play();
if (TeleportDelay2 <= 0 && TeleportDelay3 >= 1f)
{
Vector3 v = new Vector3();
if (checki != -1)
{

v.x = hit[checki].collider.gameObject.transform.position.x - 3f *
(sprite.flipX ? -1 : 1);
Vector3 v2 = new Vector3();

v2.x = target.transform.position.x - 1 * (sprite.flipX ? -1 : 1);


v2.y = target.transform.position.y;
v2.z = target.transform.position.z;
target.transform.position = v2;

92
}
else
v.x = target.transform.position.x - 6f *
(sprite.flipX ? 1 : -1);
v.y = transform.position.y;
v.z = transform.position.z;
transform.position = v;
TeleportDelay3 = 0.98f;
}
else if (TeleportDelay2 > 0 && TeleportDelay3 >=
1f)
{

TeleportDelay2 -= Time.deltaTime;
}

if (TeleportDelay2 <= 0 && TeleportDelay3 > 0f &&


TeleportDelay3 <= 0.98f)
{

TeleportDelay3 -= Time.deltaTime;
}
else if (TeleportDelay2 <= 0 && TeleportDelay3 <=
0f)
{
TeleportDelay = TeleportTime;
TeleportDelay2 = 1f;
TeleportDelay3 = 1f;
animator.SetInteger("State", 1);
}
}
else
{
transform.position = Vector3.MoveTowards
(new Vector3(transform.position.x,
transform.position.y, transform.position.z), new
Vector3(target.transform.position.x, transform.position.y,
transform.position.z), speed * Time.deltaTime);
TeleportDelay -= Time.deltaTime;
}

Алгоритм врага «Шоггот».


При патрулировании данный монстр передвигается между двумя
точками – краями комнаты, в которой он был заспавнен (создан). Причем,
когда персонаж доходит до точки, спрайт (текстура персонажа)
разворачивается. Данный персонаж наделен умением «Стрелять кислотой», а
также при патрулировании каждые 30 секунд персонаж засыпает на 10 секунд,
что дает возможность игроку обойти данного врага. Происходит это за счет

93
переменной TimerSleep. Если она равна 0, то враг засыпает, а переменной
присваивается значение 30. Если она равна 20, то враг просыпается.
Независимо от значения, переменная уменьшается на 1 каждую секунду.
Данный алгоритм патруля представлен на рисунке 46.
При преследовании главного героя, «Шоггот» очень медленно
передвигается за первым, однако раз в 4 секунды противник «Плюется»
кислотой в игрока. Происходит это следующим образом:
 если переменная VenomTime <= 0, что значит, что прошло 4 секунды с
момента предыдущего полного исполнения алгоритма, то:
 запускается анимация и звук плевка кислотой, враг остается на том же
месте;
 спустя секунду, враг начинает передвигаться;
 враг продолжает преследование игрока, а переменной VenomTime
присваивается значение 4 (эквивалентно 4 секундам);
 кислота летит по прямой траектории от Шоггота по направлению к
игроку, со скоростью, большей скорости шоггота в 2 раза.
 если же переменная VenomTime > 0, то ей присваивается разница между
ней самой и прошедшим временем DeltaTime (VenomTime = VenomTime –
DeltaTime). Сама DeltaTime берется из игрового движка Unity и возвращает время,
прошедшее между кадрами.
Кислота, в свою очередь, летя по прямой траектории, исчезает при
столкновении с любым препятствием, либо по истечении заданного
расстояния. Если игрок соприкоснется с кислотой, то он погибает. Данный
алгоритм представлен на рисунке 47.

94
Рисунок 46 – Блок-схема работы алгоритма патруля «Шоггота»

95
Рисунок 47 – Блок-схема работы алгоритма преследования «Шоггота»

Код алгоритма представлен в листинге 24.


Листинг 24 – Алгоритм «Шоггота»
if (gameObject.tag == "Dog")
{
if (SleepDelay <= 0)
{

96
//спим
animator.SetInteger("State", 0);
SleepDelay = 30f;
}
else
{
SleepDelay -= Time.deltaTime;
if (SleepDelay < 20)
{
//просыпаемся
if (Vector2.Distance(transform.position,
moveSpots[randomSpot].position) < 12f)
{
if (waitTime <= 0)
{
randomSpot = Random.Range(0,
moveSpots.Length);
waitTime = 0.1f;
}
else waitTime -= Time.deltaTime;
}
else
{
transform.position = Vector3.MoveTowards
(new Vector3(transform.position.x,
transform.position.y, transform.position.z), new
Vector3(target.transform.position.x, transform.position.y,
transform.position.z), speed * Time.deltaTime);
}
}
else
{
animator.SetInteger("State", 2);//
//спим
}

}
else
{
VenomTime2 -= Time.deltaTime;
if (VenomTime2 <= 0)//плевок
{
State = CharState.Idle;
ven = Instantiate(MO[0]);
transform.SetParent(transform, false);
Vector3 v = new Vector3();
flipplevok = sprite.flipX;

GameObject.FindGameObjectWithTag("VenomTag").GetComponentInChildr
en<SpriteRenderer>().flipX = !flipplevok;
v.x = transform.position.x - 2 *
(flipplevok ? 1 : -1);
v.y = transform.position.y;

97
v.z = transform.position.z;
ven.transform.position = v;
VenomTime2 = 4f;
VenomTime3 = 1f;
}
else
{
VenomTime3 -= Time.deltaTime;
if (VenomTime3 <= 0)
{
State = CharState.Run;
transform.position =
Vector3.MoveTowards(transform.position,
target.transform.position, speed * Time.deltaTime);
}
}
}
}
if (ven != null)
{
VenomTime1 -= Time.deltaTime;
ven.transform.position = Vector3.MoveTowards
(new Vector3(ven.transform.position.x,
ven.transform.position.y, ven.transform.position.z), new
Vector3(ven.transform.position.x - 5 * (flipplevok ? 1 : -1),
ven.transform.position.y, ven.transform.position.z), speed *
Time.deltaTime * 2f);
if (VenomTime1 <= 0)
{
VenomTime1 = 1.5f;

Destroy(GameObject.FindGameObjectWithTag("VenomTag"));
ven = null;
}
}
if (ven != null)
{
If(ven.destroy)

VenomTime1 = 1.5f;

Destroy(GameObject.FindGameObjectWithTag("VenomTag"));
ven = null;

}
Алгоритм врага «Гуль».
При патрулировании данный монстр передвигается между двумя
точками – краями комнаты, в которой он был заспавнен, однако эти точки
98
могут меняться во время игры в зависимости от результатов погони за
игроком. Причем, когда персонаж до ходит до точки, спрайт (текстура
персонажа) разворачивается (зеркально отражается). [12] Алгоритм патруля
представлен на рисунке 48.

Рисунок 48 – Блок-схема работы алгоритма патруля «Гуля»

Данный противник отличается большой скоростью передвижения (в 1,5


раза быстрее игрока), а так же изменением точек патрулирования. Для
балансированной системы поведения, персонаж раз в 3 секунды, гонясь за
99
игроком, рычит и не двигается на протяжении 1 секунды, в течение которой
игрок может убежать либо обойти (используя систему укрытий). Происходит
это следующим образом:
 если переменная GrowlTime <= 0, что значит, что прошло 3 секунды с
момента предыдущего полного исполнения алгоритма, то:
 запускается анимация и звук рычания, враг остается на том же месте;
 спустя секунду, что эквивалентно завершению анимации, враг
продолжит преследования игрока;
 враг продолжает преследование игрока, а переменной GrowlTime
присваивается значение 3 (эквивалентно 3 секундам);
 если левая точка патрулирования находится правее, чем точка
нахождения в данный момент, то левой точке патрулирования присваивается
координаты точки нахождения в данный момент;
 если правая точка патрулирования находится левее, чем точка
нахождения в данный момент, то правой точке патрулирования присваивается
координаты точки нахождения в данный момент;
 переменной GrowlTime присваивается разница между ней самой и
прошедшим временем DeltaTime (GrowlTime = GrowlTime – DeltaTime);
 если GrowlTime = 2, анимация рычания сменяется анимацией бега, и
персонаж продолжает движение.
Таким образом, в течение 1 секунды, когда воспроизводится анимация и
звук рычания, враг не представляет угрозы для игрока и у последнего
появляется возможность «уйти» от преследователя. Данный алгоритм
представлен на рисунке 49.

100
Рисунок 49 – Блок-схема работы алгоритма преследования «Гуля»

101
Код алгоритма представлен в листинге 25.
Листинг 25 – Алгоритм «Гуля»
If(patrul)
{
//поворот спрайта
sprite.flipX = gameObject.transform.position.x >=
moveSpots[randomSpot].position.x;
//устанвока анимации бега
animator.SetInteger("State", 1);
if(GrowlTime < 2)
GrowlTime = 3f;
//если дошли до контрольной точки
if (Vector2.Distance(transform.position,
moveSpots[randomSpot].position) < 5f)//
{
if (waitTime <= 0)
{
randomSpot = Random.Range(0,
moveSpots.Length);
waitTime = 0.1f;
}
else waitTime -= Time.deltaTime;
}
else
{
transform.position = Vector3.MoveTowards
(new Vector3(transform.position.x,
transform.position.y, transform.position.z), new
Vector3(moveSpots[randomSpot].position.x, transform.position.y,
transform.position.z), speed * Time.deltaTime);
}
}
Else
{
//переопределние точек движения
if (moveSpots[0].position.x >
target.transform.position.x)
moveSpots[0] = target.transform;
if (moveSpots[1].position.x <
target.transform.position.x)
moveSpots[1] = target.transform;
//вычитание прошедшего времени от переменной GrowlTime
GrowlTime -= Time.deltaTime;
if (GrowlTime <= 0)
{
//установление анимации рычания
animator.SetInteger("State", 2);//
//воиспроизведение звука рычания
if (Audio != null && !Audio.isPlaying)
Audio.Play();
GrowlTime = 3f;
}
102
else
{
if(GrowlTime <= 2)
{
//установление анимации движения
animator.SetInteger("State", 1);
//движение за игроком
transform.position = Vector3.MoveTowards
(new Vector3(transform.position.x,
transform.position.y, transform.position.z), new
Vector3(target.transform.position.x, transform.position.y,
transform.position.z), speed * Time.deltaTime);
GrowlTime-= Time.deltaTime;
}
}

}
Алгоритм врага «Призрак».
В отличие от других, у данного персонажа количество точек
патрулирования равно количеству комнат на уровне. То есть призрак
беспрепятственно передвигается по всему уровню. Алгоритм патруля
представлен на рисунке 50.
По сюжету призрак не является врагом для главного героя, однако до
раскрытия сюжета, он пугает главного героя, тем, что при появлении вблизи
игрока, он со страшным звуком и огромной скоростью летит на главного
героя. Однако при контакте с игроком, призрак исчезает (переносится в
другую комнату). Происходит это следующим образом:
 если patrul = ложь, призрак передвигается по всему дому, между своими
контрольными точками, которые находятся в каждой комнате; [13]
 если расстояние между игроком и призраком меньше заданного,
воспроизводится звук призрака, и он быстро летит к игроку;
 когда призрак достигает игрока, случайно выбирается следующая
контрольная точка и призрак переносится туда.
Таким образом, призрак не представляет угрозы для главного героя, а
присутствует просто, чтобы пугать игрока. Алгоритм представлен на рисунке
51.

103
Рисунок 50 – Блок-схема работы алгоритма патруля «Призрака»

Код алгоритма представлен в листинге 26.


Листинг 26 – Алгоритм «Призрака»
//установка начального значения скорости, а также установка
контрольных точек, которым приравниваются все комнаты
case "Ghost":
speed = 6f;
GameObject[] rms =
GameObject.FindGameObjectsWithTag("Room");
moveSpots = new Transform[rms.Length];
for(int i=0;i< rms.Length;i++)
moveSpots[i] = rms[i].transform;
break;
if (patrul)
{
//если призрак долетел до игрока
if(GhostBlink)
{
randomSpot = Random.Range(0, moveSpots.Length);
104
transform.position =
moveSpots[randomSpot].position;
GhostBlink = false;
}
speed = 5f;
//поворот спрайта
sprite.flipX = gameObject.transform.position.x >=
moveSpots[randomSpot].position.x;
//установка анимации бега
animator.SetInteger("State", 1);
if (Vector2.Distance(transform.position,
moveSpots[randomSpot].position) < 6f)//
{
if (waitTime <= 0)
{
randomSpot = Random.Range(0,
moveSpots.Length);
waitTime = 0.1f;
}
else waitTime -= Time.deltaTime;
}
else
{
transform.position = Vector3.MoveTowards
(new Vector3(transform.position.x,
transform.position.y, transform.position.z), new
Vector3(moveSpots[randomSpot].position.x,
moveSpots[randomSpot].position.y, transform.position.z), speed *
Time.deltaTime);
}
}
Else
{
speed = 9f;
if (Vector2.Distance(new Vector2(transform.position.x,
transform.position.y), new Vector2(target.transform.position.x,
target.transform.position.y)) < 4f)
{
GhostBlink = true;
patrul = true;
}
//воспроизведение звука рычания
if (Audio != null && !Audio.isPlaying) Audio.Play();
//установление анимации движения
animator.SetInteger("State", 1);
//движение за игроком
transform.position = Vector3.MoveTowards
(new Vector3(transform.position.x,
transform.position.y, transform.position.z), new
Vector3(target.transform.position.x, target.transform.position.y,
target.transform.position.z), speed * Time.deltaTime);
}

105
Рисунок 51 – Блок-схема работы алгоритма преследования «Призрака»

106
2.2.3 Техническое обеспечение

Рекомендуемые технические требования к персональному компьютеру,


необходимому для функционирования программного обеспечения:
 процессор Intel Core 2 Duo с тактовой частотой 2.0 ГГц или лучше;
 2 Гб оперативной памяти, например, Patriot Signature (DDR3);
 HDD и 700 MB свободного места на нем;
 видеокарта с 1 Гб памяти, например, INNO3D GeForce GT 710 Silent LP;
 звуковая карта совместимая с DirectX;
 DirectX 9.0c;
 игровые манипуляторы: клавиатура, мышь, тачпад;
 любой монитор, например, HP V20 (19.5").
Также следует учитывать информационные требования:
 операционная система Windows 7 или выше;
 операционная система Android 2.3 или выше.

2.2.4 Программное обеспечение

2.2.4.1 Используемые программы

В создание данного игрового проекта помимо Unity3D были


задействованы еще несколько программных продуктов. Рассмотрим их
подробнее.
SAI paint tool – программа, предназначенная для цифрового рисования в
среде Microsoft Windows, разработанная японской компанией SYSTEMAX.
Данная программа является хорошей заменой Adobe Photoshop, так она
распространяется бесплатно, при этом в ней присутствуют все необходимые
функции и инструменты для работы с графикой, например, возможность
работы со слоями, возможность изменения цветовых параметров

107
изображения, возможность использовать текстуры для кистей, гибкая
настройка кистей и так далее.
Dragon Bones Pro – является программой для создания скелетной
анимации от китайских разработчиков. Самый значимый плюс этой
программы, это её бесплатное распространение и интуитивно понятный
интерфейс.
В качестве основного формата анимационных и статических спрайтов
был выбран PNG как наиболее подходящий формат для экспорта цифровой
графики. Он является растровым графическим форматом, разработанным в
качестве альтернативы GIF, который обладал коммерческой лицензией. В его
основе находятся лучшие возможности предшественника, в том числе сжатие
без потерь и поддержка прозрачного фона. Технология PNG обеспечивает
сохранение всех этапов редактирования и восстановление шага с сохранением
качества.
FL studio – это среда для создания и записи звука с его последующей
обработкой в новое музыкальное произведение, использование для
одновременных записей сигнала с внутренних дорожек программного
обеспечения (ресемплинг), либо с других доступных внешних источников.
При помощи данной программы можно создавать отдельные саундтреки при
помощи встроенных инструментов (например, синтезатора пианино), а также
редактировать уже существующие музыкальные произведения, накладывая
эффект реверберации, изменяя частотный диапазон, добавляя новые звуковые
дорожки и так далее.
Плагин DarkKZ32 – данный плагин подходит для различных звуковых
станций (в том числе и для FL studio) и позволяет использовать различные
музыкальные пресеты для написания композиций к фильмам ужасов. Так как
разрабатываемый игровой проект принадлежит к жанру «survival-horror», то
этот плагин подходит для написания саундтреков к нему.
В качестве основного формата звука был выбран WAV, так как с
помощью него проще всего экспортировать готовый саундтрек в игру. Данный

108
формат не предполагает сжатия звука, что в положительную сторону влияет
на качество звука.
Дизайн пользовательского интерфейса игры является фактором,
оказывающим влияние на три основных показателя качества программного
продукта: его функциональность, эстетику и производительность.
Функциональность является фактором, на который обращают основное
внимание. Попытка создавать интерфейс так, чтобы пользователи могли
выполнять свои задачи, и им было удобно это делать. Функциональность
важна, но, тем не менее, это не единственный показатель, который должен
учитываться в ходе разработки интерфейса.
Эстетичный внешний вид пользовательского интерфейса и способа его
представления позволяет сформировать у потребителя положительное мнение
о программном продукте.
Эстетические характеристики в видеоиграх играют большую роль, они
позволяют удержать внимание пользователя, разнообразить его игровой
процесс и в целом влияют на общее впечатление от игры и вероятность того,
что игрок порекомендует данный проект другим людям.
Среди параметров, которые можно было бы соотнести с эстетическими
характеристиками, можно выделить:
 степень сочетания цветов;
 степень поддержки одного стиля графического оформления;
 показатель разрешения графических элементов;
 показатель баланса яркости и контрастности изображений.
Производительность, а равно и надежность, также влияют на
перспективу применения игрового продукта. Если он хорошо выглядит, имеет
простое и удобное управление, но при этом страдает производительность, есть
вероятность, что конечный пользователь прекратит прохождение игры и
оставит плохой отзыв. В свою очередь, быстрая и стабильная работа игрового
продукта могут отчасти компенсировать его не самый стильный дизайн или
отсутствие некоторых функций.
109
Для обеспечения успешной работы пользователя от дизайнера
интерфейса требуется соблюдать баланс между вышеперечисленными
факторами на протяжении всего жизненного цикла разработки приложения.
Это достигается последовательной и тщательной проработкой деталей
интерактивного взаимодействия на каждом из этапов разработки
пользовательского интерфейса, включающих:
 проектирование:
 функциональные требования: определение цели разработки и
исходных требований;
 анализ пользователей: определение потребностей пользователей,
разработка сценариев, оценка соответствия сценариев ожиданиям
пользователей;
 концептуальное проектирование: моделирование процесса, для
которого разрабатывается приложение;
 логическое проектирование: определение информационных потоков в
приложении;
 физическое проектирование: выбор платформы, на которой будет
реализован проект и средств разработки.
 реализация:
 прототипирование: разработка бумажных и/или интерактивных
макетов экранных форм.

2.2.4.2 Разработка графического интерфейса

При начале работы с игровым приложением пользователь попадает в


главное меню. Главное меню содержит следующие элементы интерфейса:
 кнопка «Play»;
 кнопка «Option»;
 кнопка «Exit»;

110
 полупрозрачная панель (контейнер) для кнопок;
 фон главного меню.
Рисунок пункта «Главное меню» представлен на рисунке 52.

Рисунок 52 – Пункт «Начало игры»


Раздел «Параметры» позволяет пользователю изменить аудио
настройки. Он содержит следующие элементы:
 фон раздела «Параметры»;
 слайдер «Volume»;
 слайдер «Music»;
 кнопка «Back»;
 полупрозрачная панель (контейнер) для кнопок.
Рисунок пункта «Параметры» представлен на рисунке 53.

111
Рисунок 53 – Пункт «Параметры»
Непосредственно сама локация представляет собой особняк, который
состоит из совокупности спрайтов различных комнат, которые соединены
между собой дверями или же лестницами.
Комнаты в игре делятся на несколько типов, таких как:
 боковые комнаты правой части дома;
 боковые комнаты левой части дома;
 центральные комнаты дома;
 локации вне дома.
Примеры данных локаций представлены на рисунках 54-57
соответственно.

112
Рисунок 54 – Пример боковой комнаты правой части дома

Рисунок 55 – Пример боковой комнаты левой части дома

113
Рисунок 56 – Пример центральной комнаты дома

Рисунок 57 – Пример локации вне дома


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

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

Рисунок 58 – Пример локации

Рисунок 59 – Пример локации


Стоит учитывать тот факт, что из-за случайной генерации комнат и в
целом архитектуры дома, могут быть ситуации, когда на одном уровне будут
присутствовать несколько одинаковых комнат.
На UX/UI интерфейсе представлены следующие элементы:

115
 диалоговая компонента;
 прогресс прохождения данного уровня.
Скриншот интерфейса представлен на рисунке 60.

Рисунок 60 – Скриншот интерфейса

2.2.4.3 Создание анимации

Создание качественной анимации в играх является очень важной


задачей, так как некачественно сделанная анимация будет привлекать к себе
внимание пользователя, мешая ему погружаться в игровой процесс, и в
конечном итоге может привести к недовольству игрока. [14]
Существуют следующие способы анимации персонажей и предметов в
играх:
 спрайтовая анимация;
 скелетная анимация.
Так как первый способ требует серьёзной подготовки и специальных
навыков в области создания художественных изображений, был выбран более
лёгкий и понятный способ скелетной анимации.

116
Суть скелетной анимации заключается в том, что мультипликатор или
моделер создаёт скелет, представляющий собой, как правило, древообразную
структуру костей, в которой каждая последующая кость «привязана» к
предыдущей, то есть повторяет за ней движения и повороты с учётом
иерархии в скелете. Далее каждая вершина модели «привязывается» к какой-
либо кости скелета. Таким образом, при движении отдельной кости двигаются
и все вершины, привязанные к ней. Благодаря этому задача аниматора сильно
упрощается, потому что отпадает необходимость анимировать отдельно
каждую вершину модели, а достаточно лишь задавать положение и поворот
костей скелета.
Также благодаря такому методу сокращается и объём информации,
необходимой для анимирования. Достаточно хранить информацию о
движении костей, а движения вершин высчитываются уже исходя из них.
При создании скелетной анимации следует учитывать несколько
главных требований:
 анимация должна быть плавной, без резких переходов между кадрами;
 при анимации, спрайты, составляющие персонажа не должны разрываться;
 анимация персонажа должна соответствовать его анатомическим
особенностям;
 между двумя кадрами анимации должно быть одинаковое время;
 начальная анимация должна создаваться «на месте», без сдвига кадров;
 каждый кадр анимации должен быть одного размера и разрешения.
Учитывая вышеизложенных требований, была создана анимация для
игрового проекта в программе «DragonBones Pro». Рассмотрим этапы создания
анимации персонажа.
Начальное создание рисунка персонажа и разбиение его на части.
При создании графического изображения персонажа, для дальней его
анимации необходимо разбить каждую часть его тела на отдельные рисунки.
Сделать это можно либо после создания рисунка, либо во время рисования

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

Рисунок 61 – Разбитый на спрайты персонаж


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

118
При правильном построении этой сетки, отдельные спрайты рисунка
можно деформировать в процессе анимации, что делает конечную анимацию
более плавной и реалистичной.
Пример построения сетки искривления представлен на рисунке 62.

Рисунок 62 – Сетка искривления спрайта анимации


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

119
движение ног, привязываются к кости нижней части туловища, таким
образом, точка вращения спрайтов ног будет в пределах области нижней части
туловища.
Вес кости – это процент того, насколько сильно кость влияет на
конкретный спрайт. Благодаря правильному распределению веса костей
конечная анимация получается более плавной.
Пример создания скелета персонажа приведен на рисунке 63.

Рисунок 63 – Спрайты персонажа и кости анимации


Создание анимации персонажа.
После того как были созданы и настроены все кости, начинается этап
создания непосредственно анимации персонажа.

120
Для создания анимации в программе «DragonBones Pro» следует создать
несколько ключевых кадров, их количество зависит от сложности анимации, к
примеру, для того чтобы персонаж поднял руку вверх может понадобиться 2-4
ключевых кадра, а для того чтобы сделать анимацию ходьбы необходимо
сделать 12-16 ключевых кадра. [15]
На ключевом кадре благодаря изменению положения костей задаётся
необходимая поза модели. Пример создания ключевого кадра представлен на
рисунке 64.

Рисунок 64 – Создание ключевого кадра анимации


После создания всех необходимых ключевых кадров просматривается
получившаяся анимация, и вносятся необходимые изменения в определенные
кадры.

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

Рисунок 65 – Ошибка автоматической анимации


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

122
Рисунок 66 – Устранения ошибки автоматической анимации при помощи сетки
искривления
После исправления всех ошибок анимации, её кадры экспортируются в
формате PNG для дальнейшей вставки в игровое приложение с помощью
платформы Unity 3D.

2.2.4.4 Создание саундтреков и звуковых эффектов

Саундтреки (музыкальное сопровождение) в играх жанра «survival-


horror» помогают создать задуманную авторами атмосферу игры. Зачастую
именно благодаря саундтрекам и другим звуковым эффектам, создателям игру
удаётся «напугать» игрока.
Работу со звуком в игре была разделена на два вида:
 создание композиций и эффектов самостоятельно;
 редактирование композиций и эффектов из сторонних источников.

123
Прибегать к самостоятельному написанию музыки приходится из-за
сложности нахождения нужного саундтрека для определенного момента в
игре.
Современные программы для создания электронной музыки
предоставляют широкий спектр опций, которые могут помочь человеку,
незнакомому с музыкальной теорией, написать свой саундтрек. Поэтому было
решено создать несколько композиций самостоятельно. [16]
Редактирование же уже готовых звуковых файлов необходимо по
нескольким причинам:
 необходимость обрезать часть звуковой дорожки;
 необходимость переработать баланс частот в треке;
 необходимость добавить новые звуковые эффекты;
 необходимость добавить новую звуковую линию;
 необходимость изменить параметры саундтрека (скорость, тональность и
так далее).
Всё вышеперечисленное проделывается для создания целостного
конечного звукового оформления.
Стоит отметить характерные черты музыкальных треков в играх
подобного жанра, на основе которых создавались саундтреки для данного
игрового проекта:
 преобладание низких частот;
 периодические резкие частотные переходы;
 отсутствие четко выраженной мелодической линии (эмбиент-эффект);
 более высокий темп музыки, играющей при появлении опасности;
 фоновое звучание композиций.
Для создания и редактирования звукового оформления применялась
программа FL Studio.
Рассмотрим подробнее каждый из этапов создания музыкального
произведения.

124
Выбор основных музыкальных инструментов и написание для них
музыкальной линии.
FL Studio содержит множество встроенных плагинов, которые
имитируют звуки реальных музыкальных инструментов, также имеется
возможность добавлять их из открытых источников. Учитывая специфику
игры, был выбран плагин DarkKZ, который содержит в себе большую
библиотеку звуковых эффектов из различных фильмов ужасов. После выбора
плагина следует создать звуковую дорожку для каждого инструмента при
помощи инструмента piano roll. При этом в программе можно изначально
выставить необходимый темп композиции и её тональность. Как правило, в
саундтреках для подобных игр применяется не более 4-5 звуковых дорожек
Пример написания басовой линии приведен на рисунке 67.

Рисунок 67 – Пример написания басовой линии


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

125
При создании композиции следует учитывать, что все саундтреки в игре
идут друг за другом и поэтому чётко выраженного начала и концовки трека
создавать не стоит.
На временной дорожке можно создать автоматизированные регуляторы
громкости звука для каждой дорожки или для всего трека в целом, а также
производить манипуляции с самими звуковыми дорожками, например,
разрезание одной из них на несколько новых. [17]
Пример создания общей композиции трека на временной дорожке
представлен на рисунке 68.

Рисунок 68 – Пример создания композиции трека.


Сведение трека.
После того как была создана основная композиция трека, следует
отредактировать его, как правило редактирование сводится к нескольким
основным процедурам:
 изменение частотного звучания;
 наложение эффекта компрессии;
 наложение эффекта пространственного звучания (реверберации);
 изменение громкости звуковых дорожек;

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

Рисунок 69 – Пример настройки громкости звуковых дорожек и панорамирования


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

127
Рисунок 70 – Пример балансировки частот
Также следует выделить процесс наложения реверберации, так как
именно этот эффект можно встретить в саундтреках множества игр. Он
добавляет музыке глубины и пространственный эффект, что позволяет создать
необходимую атмосферу, особенно в играх жанра horror.
Реверберация сопровождает любой звук, возникший в естественной
акустической среде. Возникает она при отражении звуковой волны от каких-
либо препятствий и ее возврата в точку прослушивания. Поэтому, в
восприятии акустического звука присутствует его прямой источник и
многочисленные отражения от ближайших поверхностей – преград.
В FL Studio для наложения реверберации можно использовать
встроенный плагин, однако его возможности крайне ограничены, а пресетов
(готовых настроек) практически нет. Поэтому было решено использовать
сторонний плагин Valhalla Vintage Verb.
Стоит отметить, что как правило в композициях данный эффект не
накладывается на басовую линию, однако при создании саундтрека к игре
данное наложение является уместным, так как добавляет нагнетания путём
создания объёмного басового звучания.

128
Пример наложения эффекта реверберации представлен на рисунке 71.

Рисунок 71 – Пример наложения эффекта реверберации


Мастеринг трека.
После редактирования основных звуковых дорожек следует этап
мастеринга, на этом этапе производится изменение характеристик конечного
трека, а также наложение необходимых эффектов.
Выделяют несколько основных этапов мастеринга:
 лимитирование громкости трека
 фильтрация частот трека;
 эквализация трека;
 наложение эффекта компрессии.
Основными из них является эквализация и наложение компрессии.
Эквализация – один из наиболее значимых и ответственных этапов
мастеринга. Данный процесс предполагает обработку фонограммы
эквалайзером и подразумевает коррекцию амплитуды и изменение
соотношения частот.
В процессе мастеринга эквализация применяется очень часто и условно
разделяется на два типа: техническую и художественную. При технической
эквализации главная цель - добиться точного тонального баланса, при

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

Рисунок 72 – Пример эквализации


Компрессия в мастеринге – очень важный этап, который служит для
того, чтобы придать фонограмме плотности и увеличить её воспринимаемую
громкость путём сужения динамического диапазона.
При мастеринге используются как однополосные, так и многополосные
компрессоры, но часто с дополнительными специфическими функциями.
Например, нередко применяются компрессоры с автоматической

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

Рисунок 73 – Пример наложения эффекта компрессии


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

При разработке, для игры был выбран жанр «survival-horror» – жанр


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

131
Хотя геймплей таких игр может включать в себя сражения с какими-
либо противниками, как и в играх других жанров, игрок в «survival-horror» не
ощущает той степени контроля над происходящим, которая типична для
большинства экшн-игр.
Это достигается различными ограничениями – нехваткой боеприпасов,
низким уровнем здоровья протагониста, скоростью передвижения, видимости,
а также различными препятствиями, усложняющими взаимодействие с
игровой механикой.
Зачастую игрок вынужден искать в игре предметы, которые открывают
доступ в новые области игры, решать различные загадки и головоломки.
Дизайн уровней в «survival-horror» зачастую также используется для создания
атмосферы ужаса или ожидания чего-то, пугающего – например, игровой
персонаж может обследовать темные мрачные помещения, напоминающие
лабиринт, и подвергаться неожиданным нападениям врагов. [18]
Выбор такого жанра может показаться несколько противоречивым, если
учитывать главную цель проекта – снятие психофического напряжения,
однако для данного выбора есть обоснование. Дело в том, что хорошо
созданный фильм ужасов или компьютерная игра в жанре horror помогают
человеку отвлечься от собственных проблем и переживаний. Пользователь
переключается с собственных проблем и страхов на вымышленные и таким
образом на какое-то время получает необходимый эффект снятия стресса.
Стоит отдельно отметить, что многие произведения подобного
направления заканчиваются хорошим концом для главного героя, то есть
герой побеждает источник своих страхов и страхов зрителя (или игрока),
таким образом также удаётся получить эффект снятия стресса.
В доказательство того, что в трудные для себя времена многие люди
прибегают к жанру horror для снятия психофического напряжения, можно
привести инфографику популярности различных жанров кинематографа в
США в 20 -21 веках. Из графика видно, что жанр ужасов привлекал к себе
внимание в 30-х и 40-х годах, что соотносится со временами экономического

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

Рисунок 74 – Инфографика популярности жанров кинематографа


Целевой аудиторией игры являются мужчины возрастом от 16 лет. Это
обусловлено тем, что для людей младшего возраста не рекомендуется играть в
игры подобных жанров. Также игра не подойдет очень впечатлительным
людям и людям со слабой психикой. Стоит, прежде всего, понимать, что игры
жанра horror ставят перед собой цель напугать пользователя, именно поэтому
некоторым категориям такие игры могут доставить дискомфорт. [19]

133
Главной концепцией данной игры является поиск ответов на странные
события, которые случаются с главным героем. Сюжет в игре передаётся
посредством:
 монологов главного героя;
 диалога с другими персонажами;
 записок, оставленных в локациях игры;
 заметок в дневнике главного героя.
Из-за ограничений проекта, сюжет в нём передаётся путём текста, а не с
помощью озвучки.
Сюжет в игре линейный и предоставляет пользователю существенного
выбора, также концовка у игры всего одна.
Это связано, прежде всего, с особенностями жанра, главный герой в
подобных играх практически не может влиять на происходящее, ему остаётся
лишь пытаться остаться в живых и разгадать подготовленную для него загадку
какого-либо явления или события. [20]
Также было решено ограничиться лишь хорошей концовкой, так как
плохие варианты концовки могут негативно сказаться на эмоциональном фоне
пользователя и вместо психической разрядки, он может получить от игры ещё
больше стресса.
Игровой процесс представляет собой поиск некоторых объектов в
локации уровня. В начале уровня пользователь может увидеть общую
структуру локации. Пользователю необходимо исследовать все комнаты в
особняке в поисках записок.
Для того, чтобы помешать игроку беспрепятственно ходить по локации
в игру были добавлены монстры, преследующие главного героя, а также
запертые двери, для открытия которых пользователю следует найти
специальный ключ.
Пользователь не может заранее видеть монстров, они могут появится
случайно в каждой из комнат дома. Если монстр заметит главного героя,
игроку следует искать убежище в локации. Убежище представляет собой
134
шкаф, в котором главный герой может на время спрятаться от вражеского
моба. Также от некоторых мобов главный герой может спастись, перемещаясь
между этажами с помощью лестницы.
Стоит отметить, что в игре не предусмотрено оружия, то есть главный
герой никак не может сопротивляться монстрам, единственный шанс
спастись, это спрятаться от них. У героя игры всего одно очко здоровья, это
означает, что если герой не сможет избежать вражеского моба, то он погибнет
и уровень придётся перепроходить заново.
Главной особенностью игры, является случайная генерация положения
комнат на каждом уровне. То есть, если пользователь по тем или иным
причинам будет вынужден переиграть какой-либо уровень, то будет
сгенерирована другая уникальная локация и ему придется заново запоминать
положение комнат и выстраивать свой маршрут.
Данная игровая механика создавалась с целью удержания интереса
пользователя при повторном прохождении уровня.
Сложность игры увеличивается по мере прохождения, сложность уровня
характеризуется несколькими параметрами:
 количество комнат на локации;
 количество врагов на локации;
 количество фрагментов записки, которые необходимо собрать игроку;
 количество закрытых дверей на локации.
Всего в игре десять уровней, которые необходимо пройти игроку, чтобы
получить концовку.
Каждый монстр в игре обладает собственной уникальной механикой
поведения. Пользователю необходимо изучить особенности поведения врагов,
чтобы более эффективно противостоять им. Монстры вводятся в игру
постепенно, к примеру, на первом уровне игрок встретит всего одного
монстра.
Вражеских мобов можно разделить на несколько основных категорий:
 враги, стоячие на месте;
135
 враги, которые могут передвигаться в пределах этажа;
 враги, которые могут перемещаться в пределах всей локации.
Первый тип врагов блокирует главному герою доступ в определенную
комнату. При построении локации учитывается этот момент и в такие
комнаты не добавляются основные интерактивные предметы, однако в случае
обнаружения такого противника, пользователю иногда придется менять свой
маршрут.
Пример врага первого типа представлен на рисунке 75.

Рисунок 75 – Пример врага первого типа


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

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

Рисунок 76 – Пример врага второго типа


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

137
успел дойти до него. Некоторые из врагов данного типа способны проходить
сквозь стены.
Пример врага третьего типа представлен на рисунке 77.

Рисунок 77 – Пример врага третьего типа


При выборе саундтреков, учитывался опыт создания звукового
оформления других разработчиков, из которого можно сделать вывод, что
более пугающей для пользователя является музыка с чётко выраженной
монотонной басовой составляющей.
Графическая составляющая, в том числе и UI интерфейс, также является
важным элементом игры, ведь игрок в первую очередь видит, а потом уже
138
слушает и думает. Для игры был выбран мрачный стиль графического
оформления. Для этого была выбрана преимущественно темно-синяя и темно-
зеленная палитра цветов.
Характерной особенностью игры является низкая яркость изображения в
ней. Пользователь практически не видит ничего кроме небольшого
пространства вокруг игрока.
Учитывая то факт, что по сюжету игры основные действия происходят
во сне главного героя, все анимации персонажей были сделаны медленными,
чтобы передать соответствующую атмосферу.
Сюжет основан на творчестве американского писателя Говарда Филипса
Лавкрафта. Из работ данного автора были взяты некоторые образы и мотивы
повествования, а также общий тон всего произведения.
Такое решение было основано, во-первых, на большой популярности
образов из книг Лавкрафта в массовой культуре, а во-вторых из-за
оригинального стиля повествования и посылов, отличных от классических
произведений в жанре ужасов и мистики.
В центре сюжета лежит история о молодом человеке, который
переезжает в завещанный ему дом, находящийся на окраине глухой деревни.
Герою предстоит столкнуться с различными мистическими явлениями,
которые происходят в старой фамильной усадьбе и в конце помешать планам
главного антагониста игры.
При создании сюжета был создан ряд правил, которых следовало
придерживаться при его написании:
 изложение материала в хронологическом порядке;
 отказ от подробностей;
 привязка текста к изображению;
 логичность повествования.
Основной сюжет в игре передаётся посредством записок, найденных
главным героем, в то время как мысли и переживания героя передаются с
помощью его дневника и монологов.
139
Пример записки в игре представлен на рисунке 78.

Рисунок 78 - Пример записки в игре


На рисунках 79 и 80 кратко представлен сюжет игры в виде схемы.

140
Рисунок 79 – Схематичное представление сюжета игры (часть 1)

141
Рисунок 80 – Схематичное представление сюжета игры (часть 2)

142
2.2.6 Лингвистическое обеспечение

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


выбран C#, современный объектно-ориентированный и типобезопасный язык.
Он относится к семье с C-подобным синтаксисом, из них его синтаксис
наиболее близок к C++ и Java.
Язык имеет статическую типизацию, поддерживает полиморфизм,
перегрузку операторов (в том числе операторов явного и неявного приведения
типа), делегаты, атрибуты, события, свойства, обобщённые типы и методы,
итераторы, анонимные функции с поддержкой замыканий, LINQ и многое
другое. То есть, в общем, говоря, обладает достаточно широким
функционалом для работы.
Данный язык обладает несколькими, важными для проекта, плюсами:
 расширяемость системы (в С# можно спокойно подгружать любые exe,
импортировать классы, объекты из других программ, а также различные
библиотеки);
 кроссплатформенность (mono, концепция NET);
 открытость исходных текстов библиотек, исполняемых программ,
количество литературы и помощь (MSDN);
 защищенность и контроль версий подключаемых алгоритмов (концепция
NET);
 скорость работы (распределение процессов, распределение данных скорость
работы с данными);
 удобство разработки (среда разработки по сравнению с Delphi7);
 поддержка данного языка выбранным движком Unity 3D и возможность
работы с его встроенными библиотеками.
В связи со всеми вышеперечисленными аспектами было решено выбрать
С# в качестве основного языкового средства разработки.

143
2.3 Тестирование продукта

2.3.1 Тест-план

Описание программного продукта:


Игровое приложение в жанре «survival-horror», которое помогало бы
пользователю избавиться от накопленного психофизического напряжения.
Данный продукт написан на языке C# с использованием Unity3D.
Стратегия тестирования:
В данной работе будут проведено тестирование следующих моментов:
производительность, сохранения игрового процесса в экстренных ситуациях, выход
персонажа за текстуру, коллизия, рандомизация комнат и связанных с ними
объектов, алгоритм поведения мобов. Стратегия тестирования представлена в
таблице 3.
Критерии начала:
 готовность тестовой платформы;
 ПК запущен, сбоев в системе его работы нет, перебои в электричестве
отсутствуют;
 законченность разработки требуемого функционала;
 наличие всей готовой документации.
Критерии окончания:
 результаты тестирования удовлетворяют качеству продукта: надежность,
корректность, мобильность;
 выполнены полностью все прописанные тест-кейсы.
Для тестирования программного продукта использовался персональный
компьютер. Его характеристики имеют следующий вид:
 процессор – AMD Ryzen 5 2600;
 материнская плата - Asrock z370 killer sli;
144
 оперативная память - Samsung 8GB x2;
 видеокарта – Nvidia GTX 1660 – 6GB;
 жесткий диск - WD Blue 1TB;
 блок питания Aerocool Vx plus 500w;
 монитор – MSI Оptix g24c;
 клавиатура - Bloody b400.

Таблица 3 – Стратегия тестирования

Функциональное
Объект системы и
Стратегия тестирование
действия
Тесты
Так как основную нагрузку для
игрового процесса представляют
постоянно появляющиеся
Производите ТК1
льность. противники, то стоит проверить, при
каком количестве мобов игра
начинает подтормаживать и «лагать».
Следует провести тест по сохранению
игрового процесса в экстренных
Сохранение
игрового ситуациях выхода из программы,
процесса в таких как зависание, с последующим ТК2
экстренных
ситуациях. «вылетом», принудительное закрытии
игры через диспетчер задач и другие
возможные выходы.

Необходимо проверить игровой


Выход персонажа
процесс на наличие бага «выход ТК3
за текстуры.
персонажа за текстуру»

145
Коллизия. Проверить не проходят ли объекты ТК4
сквозь друг друга (персонаж сквозь
мобов и т.д).

Продолжение таблицы 3

Объект системы и Стратегия Функциональное


действия тестирование

Тесты
Рандомизация
Проверить правильность работы
комнат и
алгоритмов рандомизации (комнат, ТК5
связанных с ними
дверей, лестниц и прочих объектов).
объектов.
Проверить правильность работы
Алгоритм алгоритмов рандомизации (комнат,
ТК6
поведения мобов. дверей, лестниц и других элементов
интерактивного взаимодействия)

2.3.2 Тест-комплекты

Комплект тестов - это коллекция тестовых наборов, сгруппированных


для целей выполнения тестирования. Ниже представлены оформленные в виде
таблиц четыре тестовых-комплекта.

Таблица 4 – Тест-кейс 1

ТС ID/Приоритет TK1 2
Идея: Максимальное количество мобов на уровне не снижает производительность
до критического уровня, при котором происходят «лаги» внутри игры.
Часть выполнения
Процедура Ожидаемый результат
1. Запустить видеоигру; Максимально возможное количество на
2. Замерить показатели уровне не снижает производительность
производительности до добавления и не приводит к появлению «лагов»
мобов;
3. Добавить максимально возможное

146
количество мобов на локацию (20-30);
4. Сравнить показатели
производительности после добавления
мобов, выявить «подтормаживания», если
они имеются.

Таблица 5 – Тест-кейс 2

ТС ID/Приоритет TK2 2
Идея: В экстремальных ситуациях, провоцирующих выход из игры, игровой
процесс пользователя не должен теряться.
Часть выполнения
Процедура Ожидаемый результат
1. Запустить видеоигру в редакторе После вылета игры и повторного её
Unity; запуск, весь игровой процесс будет
2. Начать прохождение; сохранен и не поврежден.
3. Создать условия в редакторе Unity,
при которых видеоигра зависнет и
вылетит;
4. Повторно зайти в игру;
5. Проверить целостность сохранений.

Таблица 6 – Тест-кейс 3

ТС ID/Приоритет TK3 1
Идея: Персонаж не должен выходить за пределы локации.
Часть выполнения
Процедура Ожидаемый результат
1. Запустить видеоигру; Отсутствие багов, связанных с выходом
2. По очереди запускать уровни игры; персонажа за пределы локации и
3. На каждом уровне проверить проваливания в текстуры.
способен ли персонаж выйти за пределы
локации;
4. На каждом уровне пытаться
спровоцировать баг, путем нажатия
нескольких кнопок действия (к примеру,
выстрел и бег вправо одновременно).

Таблица 7 – Тест-кейс 4

ТС ID/Приоритет TK4 1
Идея: Объекты на уровне не проходят сквозь друг друга.

147
Часть выполнения
Процедура Ожидаемый результат
1. Запустить видеоигру в редакторе Персонаж не может пройти сквозь
Unity; мобов. Пули и другие снаряды не
2. Запустить любой уровень; пролетают сквозь мобы. То есть все
3. Добавить на уровень 20-30 мобов; «коллизии» работают корректно.

Продолжение таблицы 7

ТС ID/Приоритет TK4 1
Идея: Объекты на уровне не проходят сквозь друг друга.
Часть выполнения
Процедура Ожидаемый результат
4. Пытаться пройти сквозь мобов Персонаж не может пройти сквозь
(персонаж не должен проходить сквозь мобов. Пули и другие снаряды не
них). пролетают сквозь объекты. То есть все
«коллизии» работают корректно.

Таблица 8 – Тест-кейс 5

Тест-кейс TК5 Приоритет: 2


Идея: Правильности рандомизации объектов на уровне.
Процедура Ожидаемый результат
1. Запустить видеоигру в редакторе Сгенерированный уровень возможно
Unity; пройти, нет багов и непроходимых
2. Запустить любой уровень; препятствий.
3. Проанализировать структуру
уровня;
4. Перезапустить уровень;
5. Вновь проанализировать структуру
уровня.

Таблица 9 – Тест-кейс 6

Тест-кейс TК6 Приоритет: 1


Идея: Соответствие поведения вражеских мобов их алгоритмам
Процедура Ожидаемый результат
1. Запустить видеоигру в редакторе Каждый вид вражеского моба ведет
Unity; себя согласно прописанному для него
2. Запустить любой уровень; алгоритму.
3. Добавить на уровень один из видов
вражеских мобов;
148
4. Протестировать алгоритм его
поведения;
5. Сравнить алгоритм поведения моба;
в игре с написанным заранее алгоритмом
6. Повторять пункты 3-5 для каждого
вида мобов.

2.3.3 Результаты выполнения

Результат выполнения тест-кейса ТК1 соответствует ожидаемому


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

Рисунок 81 – Результат тест-кейса ТК1


Результат выполнения тест-кейса ТК2 соответствует ожидаемому
результату и представлен на рисунке 82.

149
Рисунок 82 – Результат тест-кейса ТК2
Результат выполнения тест-кейса ТК3 соответствует ожидаемому
результату и представлен на рисунке 83.

Рисунок 83 – Результат тест-кейса ТК3


Результат выполнения тест-кейса ТК4 соответствует ожидаемому
результату и представлен на рисунке 84.

150
Рисунок 84 – Результат тест-кейса ТК4
Результат выполнения тест-кейса ТК5 соответствует ожидаемому
результату и представлен на рисунке 85.

Рисунок 85 – Результат тест-кейса ТК5 (белыми линиями указаны возможные


направления движения)
Результат выполнения тест-кейса ТК6 соответствует ожидаемому
результату и представлен на рисунках 86-90.

151
Рисунок 86 – Результат тест-кейса ТК6 (враг «Главный изгой»)

Рисунок 87 – Результат тест-кейса ТК6 (враг «Гуль»)

152
Рисунок 88 – Результат тест-кейса ТК6 (враг «Шоггот»)

ЗАКЛЮЧЕНИЕ

В рамках данной дипломной работы было произведено рассмотрение


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

153
На основе сравнительного анализа было принято решения взять за
прототип «Knock-Knock».
Далее система-прототип была рассмотрена по ее основным видам
обеспечения:
 алгоритмическое обеспечение;
 информационное обеспечение.
Кроме этого дополнительно был рассмотрен следующий материал:
 основные понятия жанра «survival-horror»;
 алгоритмы и методики, применяемые в приложении для достижения
эффекта расслабления.
Для реализации программного обеспечения было сформировано
техническое задание.
В конце отчета было проведено тестирование программного продукта по
выбранным критериям и составлено описание создаваемого приложения по
видам обеспечения:
 в информационном была составлена схема модульной структуры
программы, отражающая потоки информации внутри последней, и модульная
структура искусственного интеллекта;
 в алгоритмическом, по аналогии с предыдущим, приведены блок-схемы
алгоритма программы, алгоритмов ее основных составляющих элементов, а также
алгоритмы и механики искусственного интеллекта;
 в лингвистическом был описан выбранный язык программирования с точки
зрения его достоинств и преимуществ конкретно для движка Unity;
 в техническом – рекомендуемые технические требования к персональному
компьютеру;
 в программном обеспечении были описаны UI/UX интерфейс, анимация и
музыкальное оформление с точки зрения их создания и редактирования;
 наконец в концептуальном описана разработка общей концепции игры, ее
основных механик; в этом же разделе была приведена краткая схема сюжета.

154
БИБЛИОГРАФИЧЕСКИЙ СПИСОК

1. Knock-Knock [Электронный ресурс]. – URL:


https://www.igromania.ru/article/23855/Knock-Knock.html (дата обращения
21.05.2021);
2. Limbo [Электронный ресурс]. – URL:
https://games.mail.ru/pc/articles/review/limbo/ (дата обращения 21.05.2021);
3. Creaks: Обзор [Электронный ресурс]. – URL:
https://stopgame.ru/show/112783/creaks_review (дата обращения 21.05.2021);
4. Little Nightmares — мрачный хоррор в милой обертке. Рецензия
[Электронный ресурс]. – URL: https://3dnews.ru/951110 (дата обращения 21.05.2021);
5. Обзор Darkest Dungeon [Электронный ресурс]. – URL:
https://gamemag.ru/reviews/darkest-dungeon (дата обращения 21.05.2021).
6. Learn Unity3D Programminf with UnityScript /Джанин Сувак. — New-York:
Apress, 2014. — 253с.
7. Unity for Absolute Beginners /Сью Блэкман. — New-York: Apress, 2014г. —
138с.
8. Разработка игр Unity 2018 за 24 часа /Майк Гейг. — Москва: Бомбора, 2021
г. — 258с.
9. Unity в действии. Мультиплатформенная разработка на C# /Хокинг Джозеф.
— Санкт-Петербург: Питер СПб, 2018 г. — 452с.
10. Learning Unity Android Game Development /Томас Финнеган. —
Бирмингем: Packt Publishing, 2015 г. — 351с.
11. Unity и C#. геймдев от идеи до реализации /Бонд Джереми Гибсон. —
Санкт-Петербург: Прогресс книга Питер, 2019 г. — 245с.
12. Learning Unity 2D Game Development by Example /Венита Перейра. —
Ньютон: O'Reilly Media, 2014 г. — 381с.
13. Unity 2D Game Development /Дейв Калабресе. — Бирмингем: PacktPub,
2014 г. — 413с.

155
14. Timing for Animation /Harold Whitaker, John Halas, Tom Sito. — London:
Focal Press, Elsevier, 2009. — 184с.
15. Аниматор. Набор для выживания /Уильямс Ричард. — Москва: Бомбора,
2019. — 392с.
16. Звук на компьютере. Трюки и эффекты /Белунцов Владимир. — Санкт-
Петербург: СПб: Питер, 2009. — 451с.
17. Сочинение и аранжировка музыки на компьютере /Дейв Калабресе. —
Санкт-Петербург: БХВ - Петербург, 2016 г. — 611с.
18. Геймдизайн: Как создать игру, в которую будут играть все /Альпина
Паблишер. — Москва: Шелл Д, 2019 г. — 405с.
19. Проектирование и архитектура игр /Эндрю Роллингз, Дэйв Моррис. —
Москва: Издательский дом «Вильямс», 2005. — 1035с.
20. Unity Game Development Essentials /Will Goldstone. — Москва:
Издательский дом «Книга по Требованию», 2009. — 316с.

156

Вам также может понравиться