Создаем игру XO на Unity3d
В данной статье я выложу код видео уроков и картинки для проекта.
Вдруг кто захочет повторить мой путь )
Пустое поле | Крестик | Нолик |
1) (Unity3D) Описание создания интерфейса игры ХО часть 1
2) (Unity3D) Описание создания интерфейса игры ХО часть 2
3) (Unity3D) Описание создания интерфейса игры ХО часть 3
4) (Unity3d) Реализуем проект на Unity 3D
Код скрипта MainGame.cs
MainGame
using UnityEngine; using System.Collections; public class MainGame : MonoBehaviour { int WhoWin = 0; //кем будем играть public int Player = 0, //игрок Comp = 0; //компьютер //может ли ходить игрок public bool CanStep = true; //поле выбора кнопок нарисовано bool DrawSelect = true; //картинка из которой будет строиться блок public GameObject Img; //массив игровых элементов GameObject[] SelectPlayer; //режим игры public int GameMode = 0; void MainMenu() { //получаем размеры экрана int H = Screen.height / 3, //высота экрана W = Screen.width / 2; //ширина экрана //размер кнопок и надписей по ширине int Width_BL = 100, Height_BL = 40; //расчитываем центр для надписей и кнопок //из центра окна вычитаем пол кнопки W = (W - Width_BL / 2); Rect Location = new Rect( W, //задаем позицию по Х H, //задаем позицию по Y Width_BL, //задаем размер по X Height_BL //задаем размер по Y ); GUI.Label( Location, //опеделеяем размеры и расположение надписи "Меню игры" //опеределяем название надписи ); //смещаем вниз на 10 и высоту надписи H += (Height_BL + 10); //так как кнопка шире на 15 точек поэтому вычьтем //эту разницу из точки где должно быть начало кнопки W -= 15; Location = new Rect( W, //задаем позицию по Х H, //задаем позицию по Y Width_BL, //задаем размер по X Height_BL //задаем размер по Y ); if ( GUI.Button( Location, //опеделеяем размеры и расположение кнопки "Старт игры" //опеределяем название надписи кнопки ) ) GameMode = 1; //смещаем вниз на 10 и высоту надписи H += (Height_BL + 10); Location = new Rect( W, //задаем позицию по Х H, //задаем позицию по Y Width_BL, //задаем размер по X Height_BL //задаем размер по Y ); //создаем кнопку if (GUI.Button( Location, //опеделеяем размеры и расположение кнопки "Выход" //опеределяем название надписи кнопки )) Application.Quit(); } //функция отображения 2 картинок отображающих Х и О void DrawSelectStep() { //2 игровых блока Х и О SelectPlayer = new GameObject[2]; //определяем позицию где будет создан блок Vector3 BlockLocation = new Vector3(-3, 0, 0); //создаем блок крестика SelectPlayer[0] = (GameObject)Instantiate(Img, BlockLocation, Quaternion.identity); //получаем у блока компонент наш скрипт ImgChange Imgchanes = SelectPlayer[0].GetComponent<ImgChange>(); //задаем крестик Imgchanes.Status = 1; //определяем позицию где будет создан блок BlockLocation = new Vector3(3, 0, 0); //создаем блок крестика SelectPlayer[1] = (GameObject)Instantiate(Img, BlockLocation, Quaternion.identity); //получаем у блока компонент наш скрипт Imgchanes = SelectPlayer[1].GetComponent<ImgChange>(); //задаем крестик Imgchanes.Status = 2; DrawSelect = false; } //удаление игровых обьктов с поля void DestroyGameObgect() { //выставляем флаг рисования в правду DrawSelect = true; //если есть что удалять то удаляем if(SelectPlayer!=null) //перебираем массив созданных блоков foreach (GameObject ForDel in SelectPlayer) { //уничтожаем обьекты Destroy(ForDel); } } //функция отображения поля для игры void DrawPoleGame() { //определяем позицию где будет создан блок Vector3 BlockLocation = new Vector3(-3, 0, 0); //обьявялем поле из 9 элементов SelectPlayer = new GameObject[9]; //номер создаваемого блока int Index = 0; //начальные координаты для блоков float X = -3, Y = 3; //цикл для пререхода по оси Y for (int I2 = 0; I2 < 3; I2++) { //цикл для перехода по оси Х for (int I = 0; I < 3; I++) { //определяем позицию где будет создан блок BlockLocation = new Vector3(X, Y, 0); //создаем игровой блок SelectPlayer[Index] = (GameObject)Instantiate(Img, BlockLocation, Quaternion.identity); //расчитываем следующюю координату по Х X += 2.8f; //расчитываем следующий номер блока Index++; } //расчитываем следующюю координату по Х X = -3; //расчитываем следующюю координату по Y Y -= 3; } DrawSelect = false; } //описываем внешний вид void OnGUI() { //режим игры Стартовое меню if ( GameMode==0 ) MainMenu(); if (GameMode == 1) { if (DrawSelect) DrawSelectStep(); if (Player != 0) //если выбор сделан значит двигаемся дальше { //уничтожаем игрвой обьект DestroyGameObgect(); //меняем режим игры на следующий GameMode++; } } //режим игры if (GameMode == 2) { //рисуем поле игрока if (DrawSelect) DrawPoleGame(); //ход ПК if (CanStep == false) { //пробуем сделать ход int Index = Random.Range(0, 9); //получаем компоненте ImgChange ImgChange statusPoly = SelectPlayer[Index].GetComponent<ImgChange>(); if (statusPoly.Status == 0) { //записываем ход statusPoly.Status = Comp; //разрешаем ходить игроку CanStep = true; } } if (BeginsPaly()) GameMode = 3; if (TestWin(Player)) { WhoWin = Player; GameMode = 3; } if (TestWin(Comp)) { WhoWin = Comp; GameMode = 3; } } //окно с результатом игры if (GameMode == 3) { if (SelectPlayer!=null) DestroyGameObgect(); string Finish = "Ничья"; if (WhoWin != 0) { if (WhoWin == Player) Finish = "Вы выиграли"; if (WhoWin == Comp) Finish = "Вы проиграли"; } //получаем размеры экрана int H = Screen.height / 3, //высота экрана W = Screen.width / 2; //ширина экрана //размер кнопок и надписей по ширине int Width_BL = 200, Height_BL = 140; //расчитываем центр для надписей и кнопок //из центра окна вычитаем пол кнопки W = (W - Width_BL / 2); Rect Location = new Rect( W, //задаем позицию по Х H, //задаем позицию по Y Width_BL, //задаем размер по X Height_BL //задаем размер по Y ); GUI.Label( Location, //опеделеяем размеры и расположение надписи Finish //опеределяем название надписи ); //смещаем вниз на 10 и высоту надписи H += (Height_BL + 10); //так как кнопка шире на 15 точек поэтому вычьтем //эту разницу из точки где должно быть начало кнопки W -= 15; Location = new Rect( W, //задаем позицию по Х H, //задаем позицию по Y Width_BL, //задаем размер по X Height_BL //задаем размер по Y ); if ( GUI.Button( Location, //опеделеяем размеры и расположение кнопки "Вернуться в меню" //опеределяем название надписи кнопки ) ) { //загружаем игру заново Application.LoadLevel("xo"); } } } bool BeginsPaly() { //перебираем каждый блок foreach (GameObject block in SelectPlayer) { ImgChange status = block.GetComponent<ImgChange>(); if (status.Status == 0) return false; } return true; } //функция проверки на победу передаем значение кого будем проверять bool TestWin(int WHO) { //список вариантов выигрышных комбинаций int[,] WinVariant = { { //1 вариант 1,1,1, //Х Х Х 0,0,0, //_ _ _ 0,0,0 //_ _ _ }, { //2 вариант 0,0,0, //_ _ _ 1,1,1, //Х Х Х 0,0,0 //_ _ _ }, { //3 вариант 0,0,0, //_ _ _ 0,0,0, //_ _ _ 1,1,1 //Х Х Х }, { //4 вариант 1,0,0, //Х _ _ 1,0,0, //Х _ _ 1,0,0 //Х _ _ }, { //5 вариант 0,1,0, //_ Х _ 0,1,0, //_ Х _ 0,1,0 //_ Х _ }, { //6 вариант 0,0,1, //_ _ Х 0,0,1, //_ _ Х 0,0,1 //_ _ Х }, { //7 вариант 1,0,0, //Х _ _ 0,1,0, //_ Х _ 0,0,1 //_ _ Х }, { //8 вариант 0,0,1, //_ _ Х 0,1,0, //_ Х _ 1,0,0 //Х _ _ } }; //получаем поле int[] TestMap = new int[9]; if (SelectPlayer != null) { //просчитываем поле for (int I = 0; I < 9; I++) { ImgChange status = SelectPlayer[I].GetComponent<ImgChange>(); if (status.Status == WHO) TestMap[I] = 1; } } //выбираем вариант для сравнения for (int Variant_Index = 0; Variant_Index < WinVariant.GetLength(0); Variant_Index++) { //счетчик для подсчета соотвествий int WinState = 0; for (int TestIndex = 0; TestIndex < TestMap.Length; TestIndex++) { //если параметр равен 1 то проверяем его иначе 0 тоже = 0 if (WinVariant[Variant_Index, TestIndex] == 1) { //если в параметр в варианте выигрыша совпал с вариантом на карте считаем это в параметре WinState if (TestMap[TestIndex] == 1) WinState++; } } //если найдены 3 совпадения значит это и есть выигрышная комбинация if (WinState == 3) return true; } return false; } // Use this for initialization void Start () { } // Update is called once per frame void Update () { } }
Код скрипта ImgChange.cs
Код скрипта ImgChange
using UnityEngine; using System.Collections; public class ImgChange : MonoBehaviour { //статус ячейки public int Status = 0; //3 картинки (пусто крест и ноль) public Sprite[] Imgs = new Sprite[3]; //смена статуса ячейки void ChangeImg() { //получаем компонент игрового поля картинку //если поле пусто то меняем значение иначе оставляем как есть SpriteRenderer MyImage = this.GetComponent("SpriteRenderer") as SpriteRenderer; //в зависимости от статуса меняем изображение switch (Status) { case 0: MyImage.sprite = Imgs[0]; break; //пустое поле case 1: MyImage.sprite = Imgs[1]; break; // крестик case 2: MyImage.sprite = Imgs[2]; break; // нолик } } //обработка нажатия мыши на поле void OnMouseDown() { //находим камеру GameObject A = GameObject.FindGameObjectWithTag("Player"); //получаем ссылку на наш скрипт MainGame P = A.GetComponent<MainGame>(); switch (P.GameMode) { case 1: //задаем игроку ту картинку которую он бырал P.Player = Status; //если наша картинка равна 1 значит компьютеру нужно задать 2 а нам 1 if (Status == 1) P.Comp = 2; //O if (Status == 2) P.Comp = 1; //X break; case 2: //если можно сделать ход if(P.CanStep) //и данный блок свободен if (Status == 0) { //запсиываем в него ход Status = P.Player; //передаем ход ПК P.CanStep = false; } break; } } // Use this for initialization void Start () { } // Update is called once per frame void Update () { ChangeImg(); } }