Создаем игру 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();
}
}