Критерии
|
Unity
|
Unreal engine
|
Construct 2
|
Стоимость
|
Personal-Бесплатно Pro-75$ в месяц
|
Бесплатно 5% с дохода продукта
|
Free edition - бесплатно Personal License
- 8400р. Buisness License- 27500р.
|
Маркет
|
+
|
+
|
-
|
Язык прогр.
|
С#/JS(Mod)
|
C++/ BluePrint
|
WYSIWYG
<https://ru.wikipedia.org/wiki/WYSIWYG>-редактор
|
Код
|
Закрытый
|
Открытый
|
Закрытый
|
Уд. и скорость разр. под мобильные платформы
|
4/5
|
2/5
|
5/5
|
Третьим претендентом является движок Unity. Движок так же является бесплатным, но со своими
особенностями. Код у движка закрытый и сценарные языки C# и JavaScript. Но для мобильных разработок движок является самым оптимальным решением
из-за удобства и скорости разработки. На нем и остановился выбор.
В качестве сценарного языка был сделан выбор в пользу С#, так как проект
изначально планировалось реализовывать на этом языке.
2. Проектирование
.1 Проектирование образа и функционала игрового персонажа
.1.1 Образ персонажа
Согласно требованиям, к приложению нужно продумать образ персонажа.
Для этого рисуется набросок самого персонажа. Но перед этим требуется
знать, что именно персонаж будет делать, как двигаться и множество других
мелочей, чтобы подчеркнуть его индивидуальность. Наш персонаж должен бежать в
одном направлении и прыгать. Отталкиваясь от этого можно нарисовать образ и
продумать дальнейшую его анимацию. На рисунке показан образ созданного
персонажа игры.
Рисунок 2.1. Образ персонажа
После как мы нарисовали образ следует подумать над анимацией, так как
персонаж на экране должен двигаться. Для этого существуют спрайты.
Спрайты- это графические объекты. Под спрайтами подразумеваются рисунки,
которые выводятся на экран с помощью аппаратного ускорения. В до начала 1990х
годов понятие спрайт распространялось на всех двумерных персонажах, а после
развития мультимедиа и повышения глубины цвета вышло программное обеспечение,
которое ввело общий API для двухмерной
и трехмерной графики. То есть сейчас двухмерные изображения выводятся, как и
трехмерные.
В проекте будут реализованы спрайты типа Billboard (постоянно повернуты к камере), так
как игра будет в 2D.
Было принято решение для анимации персонажа сделать 9 спрайтов.
Чтобы анимация была более плавная эти спрайты будут меняться за маленький
промежуток времени и каждый в своей последовательности как показано на рисунке
2.2
Рисунок 2.2. Спрайты персонажа
Анимация персонажа готова, но нужно произвести провальную настройку
анимации в движке при реализации продукта.
2.1.2 Функции персонажа
Персонаж обладает рядом функций, которые должны быть в дальнейшем
реализованы:
) Бег
Персонаж должен бежать в одном направлении. Будет реализован счетчик,
который накапливает очки при забеге.
) Прыжок
При нажатии на сенсорную область персонаж должен прыгать, чтобы
преодолевать препятствия
) Взаимодействие с объектами.
В игре будут существовать различные объекты, с которыми персонаж должен
будет взаимодействовать.
а) Взаимодействие с платформами. Персонаж не должен проходить сквозь эти
объекты. Он должен только соприкасаться. Персонаж и платформы имеют коллизию.
б) Взаимодействие с монетками. Персонаж должен соприкасаться с этими
объектами, прибавление к счету монеток и их исчезновение на экране.
в) Взаимодействие с объектом Death. Если персонаж упадет за платформу, то он соприкасается с объектом
Death. Объект расположен вне зоны видимости экрана. После этого должно выйти
меню перезапуска уровня.
2.2 Разработка интерфейса игры
Так как реализация продукта на мобильные устройства, то следует
представить мобильное устройство и нарисовать эскиз будущего интерфейса.
Игра будет состоять из трех сцен (меню, городок, игровой уровень). Для
каждой сцены нужно нарисовать собственный эскиз, после которых можно будет
нарисовать сцены и обозначить свой функционал. Следует помнить при реализации
что характеристики экранов устройств разные и это нужно учесть при реализации,
чтобы интерфейс продукта подгонялся под размеры экрана.
2.2.1 Меню
Меню - это первая сцена, которую должен видеть перед собой пользователь.
На рисунке 2.3 показана схема меню.
В нем должно быть реализовано
) переход на сцену городка
) выход из игры.
Рисунок 2.3. Схема меню
2.2.2 Городок
Сцена с городка одна из перспективных сцен. Схема городка показана на
рисунке 2.4.
В ней должны быть реализовано
)возврат в меню
)переход на игровую сцену.
Так же чтобы пользователю было интересно пользоваться продуктом нужно ему
дать возможность отслеживать свой прогресс. Для этого следует реализовать счет
монеток, которые он соберет во время игры.
В будущем в этой сцене следует так же реализовать Здание с выпадающим
меню для прокачки персонажа.
Рисунок 2.4. Схема города
2.2.3 Игровая сцена
Самая важная сцена в игре - игровая, где пользователь играет за
персонажа, который преодолевает препятствия и собирает монетки. Схема игровой
сцены показана на рисунке 2.5.
В этой сцене должно быть реализовано
) Возврат в город
) Взаимодействие пользователя с персонажем
) Взаимодействие персонажа с платформами.
) Взаимодействие с монетками
) Отрисовка объектов на экране
) генерация объектов за пределами видимости экрана
) При взаимодействии персонажа с монеткой добавлять к счету +1
) Во время игры должны накапливаться очки забега
) Взаимодействие персонажа с объектом Death для выхода меню перезапуска уровня
) Меню перезапуска уровня
Рисунок 2.5. Схема игровой сцены
После того как были разработаны схемы можно приступать к графической
части, чтобы подготовить текстуры к реализации.
Для начала рисуем тайлы (небольшие изображения, которые являются
фрагментами большого изображения) для платформ. Платформы будут разного
размера, и чтобы не обрисовывать платформы постоянно используются тайлы. В
нашем проекте тайлы- это 4 изображения, из которых можно получить целую
платформу, по которой персонаж будет передвигаться. Тайлы, которые будут
задействованы в проекте показаны на рисунке 2.6
Рисунок 2.6. Тайлы платформ
У игры должен быть задний фон(background) согласно заявленной стилистике. В проекте background выглядит как на рисунке 2.7. Он
должен соответствовать предпочтениям пользователя. Background- один из ключевых элементов игры,
так как он дает представление о мире игры.
Рисунок 2.7. Background проекта
Так же нужно изображение монетки, как показан на рисунке 2.8. Текстура монетки
будет накладываться на объекты, с которыми персонаж должен взаимодействовать.
Рисунок 2.8. Текстура монетки
Так как персонаж уже нарисован можно создать первичную визуальную
картинку интерфейса и игривого процесса, которые показаны на рисунках 2.9 и
2.10
Рисунок 2.9. Первичная визуальная картинка интерфейса городка
Рисунок 2.9. Первичная визуальная картинка интерфейса игровой сцены
2.3 Разработка алгоритмов
.3.1 Разработка генерации платформ
Платформы должны генерироваться разной длинны. У каждой платформы имеется
коллизия, чтобы персонаж мог по ним передвигаться. Генерироваться платформы
должны из списка готовых объектов, чтобы не загружать оперативную память.
Использовать порождающий шаблон проектирования object pool. Когда платформа становится не нужна, она
возвращается в пул. Блок-схема показана на рисунке 2.11
Рисунок 2.11. Блок-схема алгоритма генерации платформ
2.3.2 Разработка управления персонажем
Персонаж будет двигаться в одном направлении. При нажатии на экран должна
пройти проверка на положение персонажа. Если персонаж касается платформы, то он
может прыгать. В обратном случае он продолжает движение. Это все сопровождается
анимацией персонажа. На рисунке 2.12 изображена блок-схема управления
персонажем.
Рисунок 2.11. Блок-схема алгоритма управления персонажем
3. Реализация
.1 Развитие приложения в соответствии с методологией гибкой
разработки Scrum
Для разработки игры было принято решение использовать методологию Scrum. Scrum прост в изучении. Он рассчитан на небольшую команду,
которая способна выполнять большой круг задач. В основном эту методологию
используют маленькие компании и небольшие команды, так как она избавляет от
необходимости обучения и найма специализированного персонала руководителей. Эта
методология больше других подходит для проекта, так как была необходимость
отслеживать работу над проектом, и реализация проходила только одним человеком.
Любой программный продукт начинается с идеи. Представителя идеи, в
методологии Scrum называют Product Owner (PO) или
Владельцем продукта. В нашем случае владельцем продукта является одно лицо. Product
Owner- тот, кто видит цель продукта, кто способен сформулировать и начать
процесс движения к ее достижению. Нужно четко представлять, что хочу получить в
итоге. Для этого стоит сформировать список пожеланий для достижения цели. Этот
список называется Product Backlog Items (PBI). Его следует постоянно
модифицировать в зависимости от ситуации на рынке или пожелания Product
Owner'a.Backlog Items:
1. Жанр Runner.
2. Игра в 2D.
3. Стиль игры Western.
4. Городок, в котором игрок способен улучшать персонажа.
. Внутри игровые транзакции.
Строго стоит понимать, что хочешь в итоге получить. Это игра жанра Runner в стиле дикого запада. Так же он
хотел, чтобы игра отличалась от других в этом жанре. Поэтому одной из
особенностей игры является городок, в котором игрок смог бы улучшать своего
персонажа.
Сейчас на рынке мобильных игр ежедневно появляются все больше игр. Его
постоянно нужно отслеживать, так как игра - это продукт, который должен
заинтересовать пользователя своей уникальностью. Этот рынок довольно капризен
по отношению к продуктам, которые не смогли зацепить аудиторию. А для
разработчика игр популярность и качество его продукта очень важна.
Следующий критерий, без которого не обойтись, это команда. По Scrum
считается, что эффективная разработка достигается, если команда будет принимать
собственные решения каким образом она будет двигаться к цели. Поэтому основное
требование к команде - самоорганизация и самоуправление. Это требование следует
обозначить, чтобы проект был успешен. Из-за этого требования в команде
существует роль ScrumMaster’a. Он должен соблюдать правела которые обозначены в
методологии.
После того, как владелец продукта сформулирует цель, нужно ее достичь. Но
достижение цели - далеко не простая задача. Поэтому и формируются жёстко
фиксированные во времени итерации - спринты. Легче разрабатывать ПО короткими
забегами. После завершения спринта производится оценка полученного и
корректировка движения. Владелец продукта всегда в курсе того, как поняли его
идеи. Если идеи поняты не совсем верно, то корректировку можно организовать на
следующем спринте. Владелец продукта должен быть спокоен, так как это
сказывается на работе команды. Команда должна осознавать, что они делают то,
что нужно.
У спринтов существует список задач. Спринт должен осуществляться в срок,
в который команда должна успеть сделать поставленные задачи и не забыть, что
они делали. Оптимальная продолжительность спринта - 2 недели.
Всегда первый день спринта уходит на планирование задач, которые
формируются по приоритетам. Каждая задача не должна занимать слишком много
времени на реализацию. Лучше большую задачу поделить на более мелкие. В таблице
3.1 представлено содержание спринтов, которые были выполнены в процессе
разработки игрового приложения.
Таблица 3.1. Спринты проекта
№ спринта
|
Содержание
|
1
|
1. область сцены бега 2. движение персонажа 3. объекты, по
которым персонаж передвигается 4. Объекты которые персонаж может собирать
(монеты) 5. генерация объектов на расстоянии и уничтожение их.
|
2
|
1.Смерть персонажа и перезапуск уровня 2. Очки 3. область
сцены город. Создание зданий и взаимодействие пользователя с ними. 4.
переключение между городом и сценой бега
|
3
|
1. главное меню 2. Текстуры персонажа 3. Текстуры меню
|
4
|
1. Текстуры меню 2. текстуры сцены бега 3. текстуры города
4. музыка для сцен и меню
|
5
|
1. тестирование 2. исправление ошибок 3. техническая
документация. 4. Публикация в Google play
|
Чтобы оценить время на задачу, нужно понимать, что член команды - это
живой человек. Следовательно, лучше спросить его, за какой срок он сможет
выполнить поставленную перед ним задачу. Этот срок можно смело умножать на два
и еще немного прибавить, тогда будет получен реальный срок выполнения задачи.
Членам команды нужно всегда помнить о самоорганизации и ScrumMaster.
Главная цель спринта - добиться, чтобы тесты, которые предъявляются
требованиям, выполнялись к окончанию спринта. Для сплоченного движения команды
к цели в Scrum рекомендуется делать ежедневные митинги. На митинге каждый член
команды, делает отчет что он уже сделал и что будет делать сегодня.
Митинг - это довольно мощная практика, поскольку на нём происходит
координация команды. Каждый способен подстроиться под другого. Scrum Muster должен обеспечить организацию митинга. Это один из
важнейших процессов в ходе разработки.
В конце спринта команда сдает его владельцу продукта и всем, кто в этом
заинтересован. Каждый отчитывается по выполненным и невыполненным задачам.
Главное - не переносить срок сдачи спринта, так как это вредит ходу разработки
в целом. По своему опыту могу сказать, что может привести к провалу спринта,
следовательно, к сдвигу сроков сдачи проекта.
Опыт использования методологии Scrum для разработки мобильного игрового приложения показал, что это хороший
способ достижения командой требуемого результата. Некоторые правила в
дальнейшем можно будет ослабить или упразднить за ненадобностью, так как
команда будет работать на одной волне.
3.2 Настройка функционала рабочей области
приложение алгоритм платформа
Настройка функционала происходит с помощью инструментов движка Unity. Инструменты упрощают работу с
объектами и их функциями. В проекте необходимо организовать работу объектов и
скриптов для получения ожидаемых результатов.
Согласно схеме сцены меню, нужно реализовать стартовое меню, которое
видит пользователь после запуска игры.
Так как шрифт, задний фон и звуковые эффекты готовы, то можно настроить
меню. Выглядеть эта сцена должна как показано на рисунке 3.1.
Рисунок 3.1 Сцена меню
При создании сцены создается объект Main Camera, который не изменяем.
Для того, чтобы игра поддерживала разные форматы экранов создаётся объект
Canvas, к которому будут привязаны элементы
управления. Для корректной работы элементов управления к объекту прикрепляется
скрипт Menu.cs, который указан в приложении 1.
Canvas
настраивается, как показано на рисунке 3.2.
Рисунок 3.2. Настройка Canvas
Для каждой кнопки, которая привязана к объекту нужно определить событие
при нажатии и шрифт текста как показано на рисунке. Событием для выхода из игры
будет выбор значения Menu.QuitGame, а, чтобы перейти на другую игровую
сцену нужно выбрать Menu.PlayGame, как показано на рисунке 3.3
Рисунок 3.3. Настройка перехода между сценами
Задний фон и звуковые эффекты добавляются непосредственно на рабочую
область сцены.
3.2.2 Настройка игровой сцены
Согласно схеме игровой сцены, нужно распределить объекты. Объект Сanvas следует расположить как в сцене
меню.
Объект сцены - Camera.
К ней привязаны большинство объектов, так как это зона видимости пользователя.
Пользователь должен наблюдать объекты, которые показаны на схеме игровой сцены.
Так же к данному объекту привязаны объекты вне зоны видимости пользователя,
которые служат для генерации объектов и взаимодействия с персонажем.
Для камеры реализуется скрипт, который указан в приложении, с помощью
которого камера двигается.
Для данного объекта заданы параметры, которые показаны на рисунке 3.4.
Рисунок 3.4. Настройка объекта Camera
3.2.3 Настройка персонажа
Объект Player, который привязан к объекту Camera имеет параметры, которые показаны на
рисунке 3.5.
Рисунок 3.5. Настройка объекта Player
Для реализации управления и взаимодействия персонажа с объектами
используются скрипты PlayerController и GameManager, которые указаны в приложении 1.
Чтобы настроить анимацию персонажа используется инструмент Animator, который встроен в движок. Данный
инструмент показан на рисунке 3.6
Рисунок 3.6. Инструмент Animator
Для каждой анимации задается свой параметр. В данном случае параметры
Player_Jump и Player_run
Перед реализацией продукта были нарисованы спрайты персонажа. С помощью
инструмента Animator, каждый спрайт задействован как
показано на рисунке 3.7
Рисунок 3.7. Анимация персонажа с помощью Animator
3.2.4 Настройка генерации объектов
Для генерации объектов реализуются объекты для платформ и монет, которые
располагаем на рабочей области сцены: PlatformGenerator, ObjectPool, CoinGenerator в которых реализованы скрипты,
выполняющие свой функционал. Прикреплять скрипты стоит как показано на
рисунках. 3.8-3.11.
Рисунок 3.8. Объект CoinGenerator
К ObjectPooler и ObjectPooler (1) прикрепляются созданные
платформы из нарисованных ранее тайлов. В игре реализованы платформы размером
12х1 и 7х1
Рисунок 3.9. Объект ObjectPooler
Рисунок 3.10. Объект ObjectPooler (1)
С помощью скрипта Platform Generator задается
дистанция генерации платформ и дистанция генерации монет.
Рисунок 3.11. Объект PlatformGenerator
3.2.5 Меню перезапуска уровня
Если персонаж не преодолевает препятствие, то должно выпадать меню
перезапуска уровня. Для этого создается объект DethMenu, который показан на рисунке 3.12 к
которому прикреплен скрипт Dethmenu и кнопки с действиями. Так же присутствует свое изображение, которое
показано на рисунке 3.13.
Рисунок 3.12. Объект DethMenu
Рисунок 3.13. Меню перезапуска уровня
3.2.6 Настройка сцены городка
Сцену городка настраиваем по аналогии со сценой главного меню.
Согласно схеме сцены городка, нужно реализовать кнопки переходов на
другие сцены. Так как шрифт, задний фон и звуковые эффекты готовы, то можно
настроить внешний вид сцены.
Задний фон и звуковые эффекты добавляются непосредственно на рабочую
область сцены.
Выглядеть эта сцена должна как показано на рисунке 3.14
Рисунок 3.14. Сцена городка
Событием для возврата на сцену меню будет Menu.BackGame. Чтобы перейти на другую игровую сцену нужно выбрать Menu.PlayGame.
Объект таверна - это кнопка, которая вызывает выпадающее меню на сцене,
где можно прокачивать персонажа за накопленные монетки, но это будет реализовано
в будущем. В нынешнем проекте реализация не предусмотрена. Так же на сцене
должен быть показан счет монет, который был накоплен на игровой сцене. Для
этого создан текстовой объект с помощью которого выводится информация.
3.3 Реализация скриптов на языке C#
Так как был сделан выбор в пользу языка С#, скрипты будут реализованы на
этом языке. В таблице 3.2 приведены переменные и их назначение скрипта GameManager.
Таблица 3.2. Переменные и их назначение скрипта GameManager
Название переменной
|
Тип переменной
|
Назначение
|
platformGenerator
|
Transform
|
Информация о платформах
|
platformStartPoint
|
Vector3
|
Стартовая позиция платформы
|
score
|
int
|
Информация о накопленных очках
|
ScoreText
|
Text
|
Вывод информации о накопленных очках
|
Timer
|
timer
|
Время
|
thePlayer
|
PlayerController
|
Ссылка на объект PlayerController
|
playerStartPoint
|
Vector3
|
Стартовая позиция персонажа
|
CoinText
|
Text
|
Вывод информации о монетках
|
Coins
|
float
|
Информация о монетках
|
platformList
|
PlatformDestruction[]
|
Список платформ
|
theDethScreen
|
Dethmenu
|
Ссылка на объект DethMenu
|
Функции:
А) Void Start. Загрузка данных монеток, присвоение
позиции платформы, присвоение позиции игрока
Б) Void Update. Прибавление очков к счётчику и вывод на экран.
Сохранение монеток и их загрузка.
В) Void Reset. Перезапуск уровня
Каждый из скриптов указан в приложении 1.
4. Тестирование
.1 Методика тестирования
Тестирование-состоит из нескольких этапов. В случае с данным проектом
методика тестирования включает в себя:
4.1.1 Модульное тестирование
Начальный этап тестирования. Данный вид тестирования подразумевает под
собой проверку отдельных модулей (скриптов). После модульного тестирования
можно утверждать, что каждый модуль работает правильно.
4.1.2 Функциональное тестирование
Используется для проверки работоспособности всего приложения. В нём
тестируются отдельные функции всего приложения, при этом неважно, какие модули
их реализуют.
4.1.3 Тестирование инсталляции
Крайне важная часть тестирования ПО. Инсталляция является первым шагом
пользовательского взаимодействия с приложением. Тестирование в проекте
направлено на успешную установку на мобильное устройство пользователя.
4.2 Результаты тестирования
.2.1 Результаты модульного тестирования
Каждый модуль (скрипт) тестировался отдельно. Работоспособность модулей
корректна.
4.2.2 Результаты функционального тестирования
Каждая функция тестировалась согласно функциональным требованиям
приложения. Тестирование каждой сцены проводится отдельно, так как они
независимы друг от друга. Функциональное тестирование приведено в таблице 4.1
Таблица 4.1. Функциональное тестирование
Функция
|
Результат
|
Бег
|
При дв. персонаж двигается в одном нап. с одной скоростью.
|
Прыжок
|
При касании на экран, персонаж прыгает, с условием, если он
находится на платформе.
|
Взаимодействие с платформой
|
Персонаж и платформа имеют коллизию, в связи с этим они не
проходят через друг друга.
|
Взаимодействие с монеткой
|
Персонаж подбирает монетку и прибавляет к счету +1
|
Взаимод. с объектом Death
|
Если персонаж касается объекта, то выпадает меню перезапуска
уровня.
|
Переход на сцену городка
|
Конопка возврата в город выполняет свою функцию
|
Выход из игры
|
Кнопка выхода из игры выполняет свою функцию
|
Возврат в меню в городке
|
Кнопка возврата в меню выполняет свою функцию
|
Переход на игровую сцену
|
Кнопка перехода на игровую сцену выполняет свою функцию
|
Генерация объектов
|
Объекты ген. на прот. всего сеанса игры на рабочей области
|
Уничтожение объектов
|
Объекты уничтожаются за пределами видимости пользователя,
как предусматривалось изначально
|
4.2.3 Результаты тестирования инсталляции
Тестирование было проведено на нескольких мобильных устройствах, которые
имеют соответствующие технические характеристики:
1) Lenovo A6010
2) Sumsung Galaxy S6
3) Fly iq4417
4) Samsung galaxy s4
На каждом из устройств приложение работало корректно, установка и
удаление не вызвала проблем.
Заключение
В процессе работы над ВКР проведена аналитика целевой аудитории, для
которой будет данное приложение интересно. В связи с этим сформированы
требования к приложению. Проведен анализ аналогичных приложений, существующих
на рынке. Для проекта подобран игровой движок, с помощью которого был
реализован продукт. Спроектированы и реализованы функции, которые были заявлены
в задании выпускной квалификационной работы.
Для разработки приложения была применена методология гибкой разработки Scrum, с помощью которой работа над
приложением была систематизирована и окончена в срок. Было проведено успешное
тестирование игрового приложения. Игра будет опубликована в Google Play для получения обратной связи от пользователей и
дальнейшего развития проекта.
Список литературы
приложение алгоритм платформа
1. Scrum
[Электронный ресурс]: Википедия / Scrum - Режим доступа: https://ru.wikipedia.org/wiki/Scrum
2. А.Пушкарев / Гибкая методология разработки Scrum
[Электронный ресурс]: Мегамозг/ А.Пушкарев - Режим доступа:
http://megamozg.ru/post/5340
3. Справка по
Unity [Электронный ресурс]: Руководство по
Unity/Cправка по Uniy -
Режим доступа: http://unity.ogf.su/Documentation/Manual/
. Борис
Романчевский/Для кого эта игрушка и как определить целевую аудиторию
[Электронный ресурс]: Разработка/ Борис Романчевский - Режим доступа:https://habrahabr.ru/post/253895/
. Руководство
Unity[Электронный ресурс]: Unity-Руководство / Руководство по Unity- Режим доступа: http://docs.unity3d.com/ru/current/Manual/
Приложение
Скрипты проекта
) CameraController.cs
using UnityEngine; using System.Collections;class
CameraController : MonoBehaviour { public PlayerController thePlayer;
private Vector3 lastPlayerPosition;
private float distanceToMove;Start () { thePlayer =
FindObjectOfType<PlayerController> ();lastPlayerPosition =
thePlayer.transform.position;
}
void Update () {
distanceToMove = thePlayer.transform.position.x -
lastPlayerPosition.x;
transform.position = new Vector3(transform.position.x +
distanceToMove, transform.position.y,transform.position.z); lastPlayerPosition
= thePlayer.transform.position;
}
}
2) PlayerController.cs
using UnityEngine; using System.Collections;
public class PlayerController : MonoBehaviour { public int
kill; public float moveSpeed;
public float jumpForce; private Rigidbody2D myRigidbody;
public bool grounded;LayerMask whatIsGround; private Collider2D
myCollider;Animator myAnimator;
public GameManager theGameManager;
void Start () { myRigidbody = GetComponent<Rigidbody2D>
(); myCollider = GetComponent<Collider2D> ();
myAnimator = GetComponent<Animator> ();
} void Update () { grounded = Physics2D.IsTouchingLayers
(myCollider, whatIsGround);
myRigidbody.velocity = new Vector2 (moveSpeed,
myRigidbody.velocity.y);
if (Input.GetKeyDown(KeyCode.Space) ||
Input.GetMouseButtonDown(0)) { if(grounded)
{ myRigidbody.velocity = new
Vector2(myRigidbody.velocity.x,jumpForce);
}
} myAnimator.SetFloat ("Speed", myRigidbody.velocity.x);
myAnimator.SetBool ("Grounded", grounded);
} void OnTriggerEnter2D (Collider2D other) { if
(other.gameObject.tag.Equals("killbox")) {
theGameManager.RestartGame();
} if (other.gameObject.tag.Equals ("coin")) {
theGameManager.Coins+=1; theGameManager.CoinText.text="Coin:
"+theGameManager.Coins;
}
}
}
3) CoinGenerator.cs
using UnityEngine; using System.Collections; public class
CoinGenerator :{ public ObjectPooler coinPool; public float
distanceBetveenCoins; public void SpawnCoins (Vector3 startPosttion) {
GameObject coin1 = coinPool.GetPooledObject ();
coin1.transform.position = startPosttion; coin1.SetActive
(true);
GameObject coin2 = coinPool.GetPooledObject ();
coin2.transform.position = new Vector3(startPosttion.x -
distanceBetveenCoins, startPosttion.y, startPosttion.z); coin2.SetActive
(true);
GameObject coin3 = coinPool.GetPooledObject ();
coin3.transform.position = new Vector3(startPosttion.x +
distanceBetveenCoins, startPosttion.y, startPosttion.z);
coin3.SetActive (true); } }
) Coinmanager.csUnityEngine;
using System.Collections;
public class CoinGenerator : MonoBehaviour { public
ObjectPooler coinPool;
public float distanceBetveenCoins;
public void SpawnCoins (Vector3 startPosttion)
{ GameObject coin1 = coinPool.GetPooledObject ();
coin1.transform.position = startPosttion;
coin1.SetActive (true); coin2 = coinPool.GetPooledObject ();
.transform.position = new Vector3(startPosttion.x - distanceBetveenCoins,
startPosttion.y, startPosttion.z);
coin2.SetActive (true);
GameObject coin3 = coinPool.GetPooledObject ();
coin3.transform.position = new Vector3(startPosttion.x +
distanceBetveenCoins, startPosttion.y, startPosttion.z);.SetActive (true);
}
}
) Dethmenu.cs
using UnityEngine;
using System.Collections;
public class Dethmenu : MonoBehaviour { public string
mainMenulevel;
public void RestartGame() { Application.LoadLevel
("Run");
} public void QuitToMain() { Application.LoadLevel
(mainMenulevel);
} }
) GameManager.csUnityEngine; using System.Collections;
using UnityEngine.UI;class GameManager : MonoBehaviour { public Transform
platformGenerator;
private Vector3 platformStartPoint; private int score;
public Text ScoreText; public timer Timer;
public PlayerController thePlayer;
private Vector3 playerStartPoint;
public Text CoinText;
public float Coins;
private PlatformDestruction[] platformList; public Dethmenu
theDethScreen;
void Start () { Coins=PlayerPrefs.GetFloat
("coin");
platformStartPoint = platformGenerator.position;
playerStartPoint = thePlayer.transform.position;
} void Update () { if (Timer.timer1 > 0.3) { score += 1;
ScoreText.text =""+ "Score: " + score;
Timer.timer1 = 0; } PlayerPrefs.SetFloat ("coin", Coins);
Coins=PlayerPrefs.GetFloat ("coin");
} public void RestartGame() { thePlayer.gameObject.SetActive
(false);
theDethScreen.gameObject.SetActive (true);
} public void Reset() { theDethScreen.gameObject.SetActive
(false);
platformList = FindObjectsOfType<PlatformDestruction>
(); for (int i = 0;
i < platformList.Length; i++) { platformList
[i].gameObject.SetActive (false);
} thePlayer.transform.position = playerStartPoint;
platformGenerator.position = playerStartPoint;
thePlayer.gameObject.SetActive (true);
} }
) GameManagerCity.csUnityEngine;System.Collections;UnityEngine.UI;
public class GameManagerCity : MonoBehaviour { public Text
GoldText;
public float Gold;
void Start () { Gold = PlayerPrefs.GetFloat
("coin");
}Update () { PlayerPrefs.SetFloat ("coin", Gold);
GoldText.text = "Gold: " + Gold;
}
}
) Menu.csUnityEngine;System.Collections;
public class Menu : MonoBehaviour { public string playGame;
public string backGame;
public void PlayGame()
{ Application.LoadLevel (playGame);
} public void BackGame()
{ Application.LoadLevel (backGame);
} public void QuitGame() { Application.Quit ();
}
}
9) ObjectPooler.cs
using UnityEngine;
using System.Collections; using System.Collections.Generic;
public class ObjectPooler : MonoBehaviour { public GameObject
pooledObject;
public int pooledAmount;
List<GameObject> pooledObjects;
void Start () { pooledObjects = new List<GameObject>();
for (int i = 0; i < pooledAmount;++) { GameObject obj =
(GameObject)Instantiate(pooledObject);
obj.SetActive (false);
pooledObjects.Add (obj);
}
}
public GameObject GetPooledObject() { for (int i = 0; i <
pooledObjects.Count; i++) { if (!pooledObjects[i].activeInHierarchy) { return
pooledObjects[i];
}
} obj = (GameObject)Instantiate(pooledObject);
.SetActive (false);
pooledObjects.Add (obj); return obj;
}
}
10) PauseMenu.cs
using UnityEngine;
using System.Collections;
public class PauseMenu : MonoBehaviour { public string
mainMenulevel;
public GameObject pauseMenu;
public void PauseGame()
{ Time.timeScale = 0f; pauseMenu.SetActive(true);
} public void ResumeGame() { Time.timeScale = 1f;
pauseMenu.SetActive(false);
} public void RestartGame() { Time.timeScale = 1f;
pauseMenu.SetActive(false);
Application.LoadLevel ("Run");
} public void QuitToMain() { Time.timeScale = 1f;
Application.LoadLevel (mainMenulevel);
}
}
) PlatformDestruction.csUnityEngine;
using System.Collections;class PlatformDestruction :
MonoBehaviour { public GameObject platformDestructionPoint;
void Start () { platformDestructionPoint = GameObject.Find
("PlatformDestructionPoint");
} void Update () { if (transform.position.x <
platformDestructionPoint.transform.position.x) { gameObject.SetActive(false);
} } }
) PlatformGenerator.csUnityEngine; using
System.Collections; public class PlatformGenerator : MonoBehaviour { public
GameObject thePlatform;
public Transform generationPoint;
public float distannceBetween;
private float platformWidth;
public float distanceBetweenMin;
public float distanceBetweenMax;
private int platformSelector;
private float[] platformWidths;
public ObjectPooler[] theObjectPools;
public CoinGenerator theCoinGenerator;
public float RandomCoinThreshold;
void Start () { platformWidths = new
float[theObjectPools.Length];
for (int i = 0; i < theObjectPools.Length;
i++) { platformWidths[i] =
theObjectPools[i].pooledObject.GetComponent<BoxCollider2D> ().size.x;
}
theCoinGenerator = FindObjectOfType<CoinGenerator> ();
}
void Update () {
if (transform.position.x < generationPoint.position.x) {=
Random.Range (distanceBetweenMin, distanceBetweenMax); platformSelector =
Random.Range(0, theObjectPools.Length);
transform.position = new Vector3(transform.position.x +
(platformWidths[platformSelector]/2) + distannceBetween, transform.position.y,
transform.position.z);newPlatform =
theObjectPools[platformSelector].GetPooledObject();
newPlatform.transform.position = transform.position;
newPlatform.transform.rotation = transform.rotation;
newPlatform.SetActive (true);(Random.Range (0f, 100F) <
RandomCoinThreshold) {
theCoinGenerator.SpawnCoins (new Vector3
(transform.position.x, transform.position.y + 1f, transform.position.z));
}
transform.position = new Vector3(transform.position.x +
(platformWidths[platformSelector]/2), transform.position.y, transform.position.z);
}
}
}
) timer.csUnityEngine;System.Collections;class timer :
MonoBehaviour {
public float timer1;
void Update () {
if (timer1 >= 0)
{ timer1 += Time.deltaTime;
}
if (timer1 > 2)
{
timer1 = 0;
}
}
}