Пишем сапёр на Unity. Настройка
16К открытий17К показов
Логические игры часто включают в себя клеточные поля, при этом клетки имеют определенные свойства и модели поведения. В этой серии уроков мы покажем вам, как создать простую версию классической игры Сапёр. Прилагаем список статей:
- Пишем сапёр на Unity. Настройка.
- Пишем Сапёр на Unity. Взаимодействие.
- Пишем Сапёр на Unity. Обработка конца игры.
В первой части серии мы будем строить само игровое поле, сделав которое вы сможете написать свою игру, использующую клеточное поле. В качестве игрового движка будем использовать Unity, который можно скачать по этой ссылке. Вы должны иметь хоть какое-то представление о нем, но если вы новичок, то прочитайте нашу серию уроков по созданию арканоида в четырех частях:
- Настройка проекта.
- Механика мяча и платформы.
- Поведение блоков, префабы и дизайн уровней.
- Добавление звуков и новых уровней.
Правила игры
Цель игры — найти все мины и не взорваться. Мины спрятаны в клетках, а сами поля бывают разных размеров от 9×9 (легкий уровень) до 16×30 (сложный уровень). Впрочем, никто не запрещает использовать любой понравившийся размер поля.
При нажатии на клетку вы «раскрываете» её. Если там мина — вы проиграли. Если же мины есть в рядом стоящих клетках, то на месте клетки, на которую вы нажали, появляется число, означающее количество мин вокруг нее. А если вокруг безопасно, то все близлежащие «безопасные» клетки раскроются.
Если вы уверены, что в какой-то клетке находится мина, смело жмите на нее правой кнопкой — клетка отметится флажком и вы не сможете «раскрыть» клетку, пока не снимите флажок. Это делается для того, чтобы вы случайно не открыли клетку, в которой точно находится мина.
После того, как все клетки с минами будут отмечены, вы выигрываете. Попробуйте поиграть в это демонстрационное приложение — именно такую игру в результате мы и должны получить.
Базовая клетка
Создайте новый проект Unity, добавьте на сцену кубик (Cube) и назовите его Tile. Перетащите его в папку с проектом для того, чтобы превратить его в префаб. Кубик пока ничего не умеет, но мы воспользуемся им, чтобы построить игровое поле, а затем добавим ему новых возможностей.
Генератор клеток
Создайте новый пустой объект и назовите его Grid. Так же как и кубик, сделайте его префабом (перетащив в папку с проектом). Этот объект — наш будущий генератор клеток, который и будет создавать игровое поле.
Создайте новый сценарий (в качестве языка программирования будем на этот раз использовать JavaScript) и также назовите его Grid. Прикрепите его к нашему генератору и пропишите в скрипте:
Сохраните скрипт и перетащите наш кубик Tile в поле Tile Prefab компонента Script объекта Grid. У вас должно получится вот так:
Названия переменных говорящие: numberOfTiles позволяет задать количество клеток на игровом поле, а distanceBetweenTiles задает расстояние между клетками.
В настоящий момент генератор клеток ничего не делает. Давайте добавим несколько строчек кода в метод CreateTiles:
Если вы нажмете на кнопку Play, то увидите нечто подобное:
Функция CreateTiles создает копии префаба кубика (столько раз, сколько мы задали) и помещает их в линию, где расстояние между кубиками равно distanceBetweenTiles. Попробуйте подобрать оптимальное расстояние, чтобы будущее поле выглядело красиво.
Но для Сапёра нам нужно поле в виде сетки, а не линии. Чтобы достичь этого, добавьте в сценарий объекта Grid новую переменную, которая будет отвечать за количество кубиков в строке:
public var tilesPerRow: int = 4;
И перепишем метод CreateTiles:
Запустив игру, вы увидите такую картину:
Вы наверняка поняли, что значение numberOfTiles должно делиться на tilesPerRow нацело, иначе полученное поле будет неправильным и некрасивым. Но наша реализация игры будет правильно работать и в случае неправильного поля.
Добавление мин
Теперь, когда мы создали основу, давайте поработаем с минами. Создайте новый сценарий, назовите его Tile и прикрепите его к префабу Tile. Добавьте строчку с объявлением переменной:
public var isMined: boolean = false;
Этот параметр нам и скажет, есть ли в клетке мина. Далее нам нужно позволить генератору создавать новый объект, который мы только что создали. Для этого измените тип переменной tilePrefab с GameObject на Tile в скрипте объекта Grid:
public var tilePrefab: Tile;
А теперь добавим новые переменные:
И не забудем про инициализацию:
И немного изменим команду Instantiate:
А в конце сценария выполним метод AssignMines. Вот так будет выглядеть измененный метод CreateTiles:
Метод AssignMines случайным образом задаст некоторым клеткам мины:
Как работает функция AssignMines? Дело в том, что все созданные клетки в методе CreateTiles помещаются в массив tilesAll. И уже в методе AssignMines они копируются в массив tilesUnmined. Далее случайным образом отбирается numberOfMines плиток. Параметр isMined отобранных плиток устанавливается в true, а они сами удаляются из массива tilesUnmined и помещаются в tilesMined.
На данный момент обычные клетки никак не отличаются от тех, которые с минами. Этот момент мы обязательно исправим, но вы уже сейчас можете проверить демо-игру, в которой можете по-своему настроить поле и количество мин (красные кубики).
Дизайн плиток
Сейчас наши клетки выглядят как кубики (по сути это и есть кубики). Давайте изменим их внешний вид.
В исходных файлах вы найдете 3D модель puzzleObjects.fbx. Скопируйте файл в папку с проектом для дальнейшего использования (убедитесь в том, что он импортируется с размером, установленным в 1):
Перейдите в настройки префаба Tile и поменяйте значение поля Mesh Filter на tileImproved.
И здесь же сбросьте значения компонента Box Collider, нажав на него правой кнопкой мыши и выбрав Reset.
И наконец, присвойте объекту новый материал, чтобы он не имел стандартный белый цвет.
Обратите внимание, мы поменяли параметры префаба лишь раз, но изменениям будут подвергнуты все созданные из него объекты. В этом и есть преимущество этих объектов.
Добавление чисел
Для того, чтобы показывать количество мин вокруг открывшейся клетки, воспользуемся 3D текстом. Создайте, выбрав GameObject -> Create Other -> 3D Text, и добавьте его к объекту Tile. Вот, как это должно выглядеть:
Поверните текст так, чтобы он лежал на клетке, установите значение текста в 0, а его размер измените так, чтобы он не выглядел размытым.
Теперь мы должны получить доступ к тексту из кода. Добавьте следующую строчку в скрипт объекта Tile:
public var displayText: TextMesh;
Перетащите объект текста в новое поле компонента Script объекта Tile:
Вывод
И на этом наша статья подходит к концу. Мы создали функциональную основу для игры в жанре головоломок. Эта основа может быть использована вами не только для Сапёра.
В следующей части этой серии мы добавим больше возможностей клеткам и доведем игру до ума. Оставайтесь с нами!
Перевод статьи «Build a Grid-Based Puzzle Game Like Minesweeper in Unity: Setup»
16К открытий17К показов