КУРСОВАЯ РАБОТА
РУКОВОДИТЕЛЬ:
КУЗНЕЦОВА В.Э.
ДАТА ЗАЩИТЫ:
______________________
ОЦЕНКА: _____________
ПОДПИСЬ___________
ТУЙМАЗЫ 2021
Содержание
Введение..................................................................................................................3
Глава 1. Теоретическая часть.............................................................................5
1.1. Движок Unreal Engine...................................................................................5
1.2. История развития игры...............................................................................10
1.3. Исследование понятия и классификация компьютерных игр................14
Глава 2. Практическая часть............................................................................30
2.1. Алгоритм реализации проекта...................................................................30
2.2. Функционал проекта...................................................................................33
2.3. Разработка компьютерной игры «Ферма»................................................36
Заключение...........................................................................................................40
Список источников и литературы...................................................................42
Приложение..........................................................................................................44
2
Введение
3
возможность взаимодействия со светом двухмерных объектов, идентичную
взаимодействию трехмерных в 3D пространстве
На Unity написаны тысячи игр, приложений, визуализации
математических моделей, которые охватывают множество платформ и
жанров. При этом Unity используется как крупными разработчиками, так и
независимыми студиями.
Целью данной курсовой работы является изучение и реализация в
программном продукте компьютерной игры «2048». Данная работа состоит
из двух разделов, заключения и приложения. Первый раздел - теоретический
и содержит общие сведения. Второй - это практическая часть. Здесь
описывается метод, разобранный на конкретных примерах. В заключении
представлен вывод о проделанной работе.
Задачи:
1. Изучить игровой движок Project Anarchy и расписать изученную
информацию.
2. Изучить информацию о Unity.
3. Разработать игру на игровом движке Unity.
4
Глава 1. Теоретическая часть
1.1. Движок Project Anarchy
11
так как она не задачка, не долг, не закон. По приказу играться нельзя, лишь
добровольно.
А что игра даёт детям? Перерыв в повседневности, с её утилитаризмом,
с её монотонностью, с её твердой детерминацией вида жизни. Игра это
неординарность. Выход в другое состояние души. Подчиняясь только
правилам игры, человек свободен от всяческих сословных, меркантильных и
иных условностей. Игра снимает то твердое напряжение, в котором
пребывает ребенок в собственной настоящей жизни, и заменяет его
добровольной и удовлетворённой мобилизацией духовных и физических сил.
Порядок: система правил в игре абсолютна и несомненна. Нереально
нарушать правила и быть в игре. Это качество порядок, совсем ценно сейчас
в нашем нестабильном, беспорядочном мире. Создает гармонию.
Сформировывает рвение к совершенству. Игра имеет тенденцию становиться
прелестной. Хотя в игре существует элемент неопределенности,
противоречия в игре стремятся к разрешению. Увлеченность: в игре нет
частичной выгоды. Она интенсивно вовлекает всего человека, активизирует
его способности. Возможность сделать и сплотить коллектив.
Привлекательность игры столь велика и игровой контакт людей друг с
другом столь полон и глубок, что игровые содружества обнаруживают
способность сохраняться и после окончания игры, вне её рамок. Элемент
неопределенности, который возбуждает, активизирует разум, настраивает на
поиск хороших решений. Понятие о чести. Она противоборствует корыстным
и узкогрупповым интересам. Для нее не значительно, кто конкретно победит,
но принципиально, чтоб победа была одержана по всем правилам, и чтоб в
борьбе были проявлены с наибольшей полнотой мужество, разум, честность
и благородство. Игра дает понятие о самоограничении и самопожертвовании
в пользу коллектива, поскольку лишь "сыгранный" коллектив добьется
совершенства в игре. Компенсацию, нейтрализацию недостатков реальности.
Противопоставляет твердому миру действительности иллюзорный
гармоничный мир - антипод. Игра дает романтизм. Физическое улучшение,
12
поскольку в активных собственных формах она предполагает обучение и
применение в деле игрового фехтования, умения ориентироваться и
двигаться по пересеченной местности, причем в доспехах и с игровым
орудием. Возможность проявить либо совершенствовать свои творческие
навыки в разработке нужной игровой атрибутики. Это орудие, доспехи,
одежда, разные амулеты, идолы и прочее. Развитие воображения, поскольку
оно нужно для сотворения новейших миров, легенд, ситуаций, правил игры.
Стойкий энтузиазм к хорошей литературе, поскольку ролевая игра создается
способом литературного моделирования. Чтоб сделать свой мир необходимо
прочесть предварительно о остальных. Возможность развить свой разум,
поскольку нужно выстроить интригу и воплотить её. Развитие остроумия,
поскольку процесс и пространство игры непременно предполагают
возникновение комичных ситуаций, хохм и анекдотов. Развитие
психологической пластичности. Игра далеко не одно лишь состязание, но и
театральное искусство, способность вживаться в образ и довести его до
конца. Удовлетворенность общения с единомышленниками. Умение
ориентироваться в настоящих жизненных ситуациях, проигрывая их не один
раз и как бы понарошку в собственном вымышленном мире. Дает
психологическую устойчивость. Снимает уровень тревожности, который так
высок сейчас у родителей и передается детям. Производит активное
отношение к жизни и целеустремленность в выполнении поставленной цели.
Воспитательное значение игры во многом зависит от
профессионального мастерства педагога, от знания им психологии дитя,
учета его возрастных и личных особенностей, от правильного методического
управления взаимоотношениями детей, от четкой организации и проведения
всевозможных игр.
Игровое творчество проявляется и в поисках средств, для изображения
загаданного. Дети реализуют свой план с помощью речи, жестов, мимики,
употребляя различные предметы, сооружения, постройки.
13
Игровое творчество развивается под влиянием воспитания и обучения,
уровень его зависит от обретенных знаний и привитых умений, от
сформированных интересов дитя. Не считая того, в игре с особой силой
появляются личные особенности детей, также влияющие на развитие
творческого плана.
Через игру равномерно готовится сознание дитя к грядущим
изменениям условий жизни, отношений со сверстниками и со взрослыми,
формируются свойства личности, нужные школьнику. В игре формируются
такие свойства, как самостоятельность, инициативность, организованность,
развиваются творческие способности, умение работать коллективно.
Игровым приемом при обучении иностранным языкам пользовались
издавна. Известные педагоги эпохи Возрождения (Рабле, Эразм
Роттердамский) уделяли большое внимание играм на занятиях иностранным
языком. Игры широко использовались при обучении в домашних условиях.
На возможность использования игр при обучении иностранным языкам
обратил внимание еще величайший педагог прошлого Я.А. Каменский, а в
дальнейшем Н.К. Крупская писала: "Чрезвычайно важны и полезны игры на
иностранном языке. Они помогают естественному изучению языка".
Рис. 2 3D Shooter
2) Arcade (аркада) (рис. 3)
Игры, в которых игроку приходится действовать быстро, полагаясь в
первую очередь на свои рефлексы и реакцию. Аркады характеризуются
развитой системой бонусов: начисление очков, постепенно открываемые
элементы игры и т.д. Термин «аркада» по отношению к компьютерным играм
возник во времена игровых автоматов, которые устанавливались в торговых
галереях (arcades). Игры на них были простыми в освоении (чтобы привлечь
побольше играющих). В последствии эти игры перекочевали в игровые
приставки и до сих являются основным жанром на них.
15
Рис. 3 Arcade
3) Arcade Racing (Аркадные гонки)(рис. 4)
Аркадные гонки характеризуются легким, отдаленным от реальности
управлением.
Примеры: серия Trackmania, Go for ride
16
4) Classic Arcade (Классические аркады) (рис. 5)
Суть классических аркад объяснить довольно сложно. Обычно главной
целью является прохождение уровня за максимально короткий промежуток
времени или сбор всех бонусов на уровне. Сюда же можно отнести
разнообразные арканоиды и пинболлы.
Примеры: Pacman, Digger, Battle City
17
Рис. 6 Fighting
6) Platformer (Платформеры) (рис.7)
Понятие платформеров пришло с игровых приставок. Именно там этот
жанр наиболее популярен. Основной задачей игрока является преодоление
препятствий (ям, шипов, врагов и т.д.) с помощью прыжков. Зачастую
приходится прыгать по абстрактно расставленным в воздухе "палочкам" (т.н.
платформам), отсюда и пошло название жанра.
Примеры: Mario, Aladdin
Рис. 7 Platformer
18
7) Scrollers (Скроллеры) (рис. 8)
В скроллерах экран непрерывно движется в одну из сторон, а игроку
предлагается уничтожать появляющихся врагов и собирать появляющиеся
бонусы. По направлению движения различают вертикальные и
горизонтальные скроллеры. Жанр был очень популярен в середине 90-х
годов, сейчас скроллеры практически не выпускаются.
Примеры: Jets'n'Guns, AirStrike, DemonStar, KaiJin
Рис. 8 Scrollers
8) Virtual Shooting (Виртуальный тир) (рис. 9)
Впервые зародился на игровых автоматах, впоследствии перешел на
многие игровые платформы, включая PC. Игровой процесс представляет
собой отстрел неожиданно появляющихся врагов, но в отличии от экшенов
мы не можем управлять движением игрока или камерой, всю игру мы как
едем по "рельсам". В связи с этим иногда делают видеотиры, т.е. всю игру
снимают на видеокамеру, в определенных местах подставляя разные
варианты видеоотрывков.
Примеры: Mad Dog McGee, серия House of the Dead
19
Рис. 9 Scrollers
9) Simulation (симуляторы) (рис. 10)
Игра-симуляция. При помощи компьютера, как можно более полно,
имитируется управление каким-либо сложным технической системы
(например: боевым истребителем, автомобилем и т.д.).
Примеры: серия Need for Speed, Descent III, Aviator
Рис. 10 Simulation
20
10) Экономические симуляции (рис. 11)
В экономических симуляциях представлены различные экономические
процессы и взаимодействия различных величин.
Примеры: Sims, Civilization
21
Рис. 12 Strategy
12) Sport (спортивные) (рис. 13)
Как и следует из названия - имитация какой-либо спортивной игры,
например футбола.
Примеры: FIFA, NBA, Tennis
Рис. 13 Sport
22
13) Adventure (приключения), или Quest (рис. 14)
Игра-повествование, в которой управляемый игроком герой
продвигается по сюжету и взаимодействует с игровым миром посредством
применения предметов, общения с другими персонажами и решения
логических задач.
Примеры: Space Quest; Myst, Мор. Утопия
Рис. 14 Adventure
14) Role-Playing Games (RPG) (ролевые игры) (рис. 15)
Правильное название этого жанра Computer RPG (CRPG), так как эти
игры являются адаптированными для компьютера традиционными ролевыми
играми.
23
Рис. 15 Role-Playing Games
15) Puzzle (головоломки, логические) (рис. 16)
В некомпьютерной головоломке роль арбитра, следящего за
соблюдением правил, играет или сам игрок (пасьянс), или некоторое
механическое устройство (кубик Рубика). С появлением компьютеров
возможности головоломок расширились, так как написать компьютерную
программу проще, чем сконструировать механическое устройство.
Головоломки, как правило, не требуют реакции от игрока (однако многие
ведут счёт времени, потраченного на решение).
Примеры: Сапёр (Minesweeper); Sokoban.
24
Рис. 16 Puzzle
16) Traditional (традиционные) и board (настольные) (рис. 17)
Компьютерная реализация настольных игр, например шахмат.
Примеры: CGoban
Рис. 17 Вoard
17) Текстовые (рис. 18)
Новое веяние в игровой культуре. Чаще всего, жанр являет собой
текстовый квест, количество участников в котором не ограничено. Иногда
такая игра может длиться годами.
Классификация игр по количеству игроков.
25
Рис. 18 Текстовые
18) Одиночные (single player) (рис. 19)
Рассчитаны на игру в одиночку, против компьютера.
Рис. 19 Одиночные
Рис. 20 Многопользовательские
20) Многопользовательские на одном компьютере (hot seat и splitscreen)
(рис. 21)
На современных персональных компьютерах бывают редко, однако
часто встречаются на старых ПК и приставках. Hot seat - игра по очереди на
одном компьютере. В режиме splitscreen экран делится на две части, каждый
из игроков играет на своей части.
27
Рис. 21 Многопользовательские на одном компьютере
21) Многопользовательские через электронную почту (PBEM) (рис. 22)
В основном встречается в пошаговых стратегиях. Результаты хода
записываются в специальный файл и отсылаются другому игроку через
электронную почту.
28
22) Массовые (MMO, Massively Multiplayer Onine) (рис. 23)
Массовые игры по Интернету. Наиболее часто встречающиеся жанры -
настольные и ролевые игры (т.н. MMORPG, или Massively Multiplayer Online
RPG). Среди них различают также браузерные игры (игры, не требующие
установки какого-либо клиента), а также текстовые онлайновые игры - жанр
MUD.
Рис. 23 Массовые
29
Глава 2. Практическая часть
2.1. Игровой движок Unity
32
2.2. Функционал проекта
35
2.3. Разработка компьютерной игры «2048»
Для удобной навигации в папке Assets нужно создать такие папки как:
Scripts, Prefabs, Spawners. Далее в папке Prefabs создадим наши плитки с
цифрами (рис. 25). Даем им имена.
36
Рис. 25 Игровые плитки
Кликаем левой кнопкой мыши на плитку. Справа появится инспектор,
где мы можем поменять позицию, повернуть его, уменьшить или увеличить в
размерах.
Сами по себе плитки двигаться не будут. Для этого им нужно
прописать скрипт, который при нажатии определенной кнопки будет
двигаться в ту или иную сторону. Нажимаем на кнопку Add Component и в
поиске пишем название скрипта с заглавной буквы. Кликаем по кнопке New
Script и нажимаем Create and Add (рис. 26).
37
Рис. 27 Скрипт движения
При запуске игры нас встречает игровое поле. В правом верхнем углу
наши очки, после каждого соединения плиток с одинаковыми цифрами очки
суммируются (рис. 28).
38
Чем дольше вы играете, тем больше очков вы набираете. После
проигрыша появятся окошко с предложением переиграть (рис. 29).
39
Заключение
41
Список источников и литературы
43
Приложение
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
Loaded,
44
WaitingForInput,
CheckingMatches,
GameOver
#region monodevelop
void Awake() {
state = State.Loaded;
void Update() {
if (state == State.GameOver) {
gameOverPanel.SetActive(true);
state = State.WaitingForInput;
GenerateRandomTile();
GenerateRandomTile();
#if UNITY_STANDALONE
if (Input.GetButtonDown("Left")) {
if (MoveTilesLeft()) {
state = State.CheckingMatches;
} else if (Input.GetButtonDown("Right")) {
if (MoveTilesRight()) {
state = State.CheckingMatches;
} else if (Input.GetButtonDown("Up")) {
if (MoveTilesUp()) {
state = State.CheckingMatches;
} else if (Input.GetButtonDown("Down")) {
45
if (MoveTilesDown()) {
state = State.CheckingMatches;
} else if (Input.GetButtonDown("Reset")) {
Reset();
} else if (Input.GetButtonDown("Quit")) {
Application.Quit();
#endif
touchStartPosition = Input.GetTouch(0).position;
if(Input.GetTouch(0).phase == TouchPhase.Ended) {
return;
swipeDelta.Normalize();
if(MoveTilesUp()) {
state = State.CheckingMatches;
if(MoveTilesDown()) {
state = State.CheckingMatches;
if(MoveTilesRight()) {
state = State.CheckingMatches;
46
} else if(swipeDelta.x < 0.0f && swipeDelta.y > -0.5f &&
swipeDelta.y < 0.5f) {
if(MoveTilesLeft()) {
state = State.CheckingMatches;
#endif
GenerateRandomTile();
if (CheckForMovesLeft()) {
ReadyTilesForUpgrading();
state = State.WaitingForInput;
} else {
state = State.GameOver;
#endregion
#endregion
47
return true;
return true;
return true;
return false;
int value;
// find out if we are generating a tile with the lowest or highest value
value = highestNewTileValue;
} else {
value = lowestNewTileValue;
while (!found) {
if (GetObjectAtGridPosition(x, y) == noTile) {
found = true;
GameObject obj;
if (value == lowestNewTileValue) {
obj = SimplePool.Spawn(tilePrefabs[0],
worldPosition, transform.rotation);
} else {
obj = SimplePool.Spawn(tilePrefabs[1],
worldPosition, transform.rotation);
tiles.Add(obj);
TileAnimationHandler tileAnimManager =
obj.GetComponent<TileAnimationHandler>();
tileAnimManager.AnimateEntry();
x++;
if (x >= cols) {
y++;
x = 0;
if (y >= rows) {
y = 0;
49
private GameObject GetObjectAtGridPosition(int x, int y) {
return hit.collider.gameObject;
} else {
return noTile;
if (obj == noTile) {
continue;
raycastOrigin.y -= halfTileWidth;
if (hit.collider != null) {
if (hitObject != obj) {
if (hitObject.tag == "Tile") {
if (CanUpgrade(thisTile, thatTile)) {
hasMoved = true;
} else {
if (!Mathf.Approximately(obj.transform.position.y, newPosition.y)) {
obj.transform.position = newPosition;
hasMoved = true;
if (!Mathf.Approximately(obj.transform.position.y, newPosition.y)) {
obj.transform.position = newPosition;
hasMoved = true;
return hasMoved;
if (obj == noTile) {
continue;
raycastOrigin.x -= halfTileWidth;
51
RaycastHit2D hit = Physics2D.Raycast(raycastOrigin, -Vector2.right,
Mathf.Infinity);
if (hit.collider != null) {
if (hitObject != obj) {
if (hitObject.tag == "Tile") {
if (CanUpgrade(thisTile, thatTile)) {
hasMoved = true;
} else {
newPosition.x += spaceBetweenTiles;
if (!Mathf.Approximately(obj.transform.position.x, newPosition.x)) {
obj.transform.position = newPosition;
hasMoved = true;
if (!Mathf.Approximately(obj.transform.position.x, newPosition.x)) {
obj.transform.position = newPosition;
hasMoved = true;
return hasMoved;
52
private bool MoveTilesRight() {
if (obj == noTile) {
continue;
raycastOrigin.x += halfTileWidth;
if (hit.collider != null) {
if (hitObject != obj) {
if (hitObject.tag == "Tile") {
if (CanUpgrade(thisTile, thatTile)) {
hasMoved = true;
} else {
newPosition.x -= spaceBetweenTiles;
if (!Mathf.Approximately(obj.transform.position.x, newPosition.x)) {
obj.transform.position = newPosition;
hasMoved = true;
if (!Mathf.Approximately(obj.transform.position.x, newPosition.x)) {
53
obj.transform.position = newPosition;
hasMoved = true;
return hasMoved;
if (obj == noTile) {
continue;
raycastOrigin.y += halfTileWidth;
if (hit.collider != null) {
if (hitObject != obj) {
if (hitObject.tag == "Tile") {
if (CanUpgrade(thisTile, thatTile)) {
hasMoved = true;
54
} else {
newPosition.y -= spaceBetweenTiles;
if (!Mathf.Approximately(obj.transform.position.y, newPosition.y)) {
obj.transform.position = newPosition;
hasMoved = true;
if (!Mathf.Approximately(obj.transform.position.y, newPosition.y)) {
obj.transform.position = newPosition;
hasMoved = true;
return hasMoved;
tile.upgradedThisTurn = false;
55
public void Reset() {
gameOverPanel.SetActive(false);
SimplePool.Despawn(tile);
tiles.Clear();
points = 0;
scoreText.text = "0";
state = State.Loaded;
tiles.Remove(toDestroy);
tiles.Remove(toUpgrade);
SimplePool.Despawn(toDestroy);
SimplePool.Despawn(toUpgrade);
tiles.Add(newTile);
tile.upgradedThisTurn = true;
points += upgradeTile.value * 2;
scoreText.text = points.ToString();
tileAnim.AnimateUpgrade();
}
56
#endregion
using UnityEngine;
using System.Collections.Generic;
/// <summary>
/// Класс Pool представляет пул для конкретного сборного модуля.
/// </summary>
class Pool {
// Мы добавляем идентификатор к имени всего, что мы создаем.
// Это чисто косметическое средство.
int nextId =1;
// Constructor
public Pool(GameObject prefab, int initialQty) {
this.prefab = prefab;
57
// Захватите последний объект в неактивном массиве
obj = inactive.Pop();
if(obj == null) {
// Неактивный объект, который мы ожидали найти,
больше не существует.
// Наиболее вероятными причинами являются:
// - Кто-то вызывает Destroy() на нашем объекте
// - Смена сцены (которая уничтожит все наши объекты).
// ПРИМЕЧАНИЕ: Это можно было бы предотвратить с помощью
DontDestroyOnLoad
// -если ты действительно этого не хочешь.
// Не беспокойтесь-мы просто попробуем следующий в нашей
последовательности.
obj.transform.position = pos;
obj.transform.rotation = rot;
obj.SetActive(true);
return obj;
/// <summary>
/// Добавлено к недавно созданным объектам, чтобы мы могли связать их обратно
/// к правильному пулу на despawn.
/// </summary>
class PoolMember : MonoBehaviour {
public Pool myPool;
}
/// <summary>
/// Init our dictionary.
/// </summary>
static void Init (GameObject prefab=null, int qty = DEFAULT_POOL_SIZE) {
if(pools == null) {
pools = new Dictionary<GameObject, Pool>();
58
}
if(prefab!=null && pools.ContainsKey(prefab) == false) {
pools[prefab] = new Pool(prefab, qty);
}
}
/// <summary>
/// Если вы хотите предварительно загрузить несколько копий объекта в начале
/// сцены, вы можете использовать это. Действительно не нужен, если только вы
не
/// собирается перейти от нулевых экземпляров к 10+ очень быстро.
/// Технически можно было бы оптимизировать больше, но на практике
// Последовательность / Spawn/Despawn будет чертовски быстрой, и
/// это позволит избежать дублирования кода.
/// </summary>
static public void Preload(GameObject prefab, int qty = 1) {
Init(prefab, qty);
/// <summary>
/// Создает копию указанного префаба (при необходимости создает экземпляр).
/// ПРИМЕЧАНИЕ: Помните, что Awake() или Start() будут запускаться только в
самом первом случае.
/// spawn и что переменные-члены не будут сброшены. OnEnable будет работать
/// /// после нереста-но помните, что переключение Активно будет также
/// вызовите эту функцию.
/// </summary>
static public GameObject Spawn(GameObject prefab, Vector3 pos, Quaternion rot)
{
Init(prefab);
/// <summary>
/// Отбросьте указанный gameobject обратно в свой пул.
/// </summary>
static public void Despawn(GameObject obj) {
PoolMember pm = obj.GetComponent<PoolMember>();
if(pm == null) {
Debug.Log ("Object '"+obj.name+"' wasn't spawned from a pool.
Destroying it instead.");
GameObject.Destroy(obj);
}
else {
pm.myPool.Despawn(obj);
}
}
59
}
using UnityEngine;
using System.Collections;
}
using UnityEngine;
using System.Collections;
}
using UnityEngine;
using System.Collections;
60
yield return null;
}
void Start() {
_transform = transform;
growVector = new Vector3(growSize, growSize, 0f);
}
}
61