Спочатку створимо блоки. Для цього використовуємо простий куб з різними кольорами (я взяв 4 кольори) і встановимо Скейл кубів в (0.8, 0.8, 0.8).
Потім створимо C # скрипт, назвемо його Match3
Що нам потрібно зробити:
1) Генерація ігрового поля (дошки).
2) Вибір двох блоків.
3) Перевірка поруч вони.
4) Обмін позиціями і даними.
5) Порівняння блоків.
6) Руйнування і Спаун об'єктів.
200? '200px': '' + (this.scrollHeight + 5) + 'px'); ">
// Дошка
public int # 91 ;,] board;
// блоки
public Transform # 91;] block;
void Start (# 41;<
blocks = new int # 91; 10,10];
// генерація дошки
GenBoard (# 41 ;;
>
void GenBoard (# 41;<
// 10x10 = 100blocks
for (int x = 0; x
// Спаун блоків
Transform obj = (Transform # 41; Instantiate (block # 91; randomNumber] .transform, new Vector3 (x, y, 0 # 41 ;, Quaternion.identity # 41; as Transform;
// призначаємо parent
obj.parent = transform;
// призначаємо ім'я
obj.name = "Block # 91; X:" + x + "Y:" + y + "] ID:" + randomNumber;
// встановимо ID на дошці в цій позиції
board # 91; x, y] = randomNumber;
>
>
>
Проходимо по кожному блоку на дошці і отримуємо для нього рандомний номер (це буде колір). Спауном блок.
Не забудьте кожному блоку призначити префаб в масив block.
Тепер створимо новий скрипт. Назвемо його Block. Призначимо цей скрипт кожному новому створеному блоку. Додамо в нього кілька змінних для позиції і ID, вони знадобляться нам надалі.
200? '200px': '' + (this.scrollHeight + 5) + 'px'); ">
// позиції блоку
public int ID;
public int x;
public int y;
private Vector3 myScale;
private float startTime;
public static Transform select;
public static Transform moveTo;
void Start (# 41;<
myScale = transform.localScale;
startTime = Time.time;
>
Тепер потрібно додати цей скрипт до кожного блоку, призначити позицію і ID. В скрипті Match3 в функцію GenBoard додамо
200? '200px': '' + (this.scrollHeight + 5) + 'px'); ">
// Прикріпимо скрипт до кожного блоку
Block b = obj.gameObject.AddComponent
// призначимо змінні
b.x = x;
b.y = y;
b.ID = randomNumber;
Вибір двох блоків.
Для вибору двох блоків, нам потрібна перевірка, натиснув гравець ліву кнопку мишки. Потім потрібно перевірити, над яким саме блоком знаходиться курсор.
В скрипті блоку ми можемо використовувати функцію OnMouseOver, яка викликається коли курсор виявляється над блоком.
Потім, якщо нічого не виділено, і гравець натискає ліву кнопку, виділяємо даний блок. І, якщо даний блок вже виділено - виділяємо його знову.
Для цього нам потрібно визначити дві статичні змінні.
200? '200px': '' + (this.scrollHeight + 5) + 'px'); ">
public static Transform select;
public static Transform moveTo;
void OnMouseExit (# 41;<
// скидаємо Скейл блоку
transform.localScale = myScale;
>
Перевірка поруч чи блоки
Для перевірки, чи знаходяться блоки поруч один з одним, потрібно дізнатися їх позиції.
Використовуємо block.select для доступу до статичної змінної. Ми отримаємо transform виділеного блоку.
В скрипті Match3, в функції Update нам потрібно перевірити, обрані чи два блоки. Якщо це так, потрібно викликати функцію CheckIfNear, яка поверне true або false.
200? '200px': '' + (this.scrollHeight + 5) + 'px'); ">
void Update (# 41;<
if (Block.select Block.moveTo # 41;/два> // Перевірка поруч вони
if (CheckIfNear (# 41; == true # 41;
200? '200px': '' + (this.scrollHeight + 5) + 'px'); ">
bool CheckIfNear (# 41;<
Block sel = Block.select.gameObject.GetComponent
Block mov = Block.moveTo.gameObject.GetComponent
// Перевірка поруч чи
if (sel.x-1 == mov.x sel.y == mov.y # 41;<
// Left
return true;
>
if (sel.x + 1 == mov.x sel.y == mov.y # 41;<
// Right
return true;
>
if (sel.x == mov.x sel.y + 1 == mov.y # 41;<
// Up
return true;
>
if (sel.x == mov.x sel.y-1 == mov.y # 41;<
// Down
return true;
>
Debug.Log ( "What are you trying to select?" # 41 ;;
return false;
>
Обмін даними блоку і зміна позицій
Для цього нам знову знадобиться доступ до Block компоненту виділеного блоку і змінити його змінні.
200? '200px': '' + (this.scrollHeight + 5) + 'px'); ">
void Swap (# 41;<
Block sel = Block.select.gameObject.GetComponent
Block mov = Block.moveTo.gameObject.GetComponent
Vector3 tempPos = sel.transform.position;
int tempX = sel.x;
int tempY = sel.y;
// Обмін позицій
sel.transform.position = mov.transform.position;
mov.transform.position = tempPos;
// Обмін даних
sel.x = mov.x;
sel.y = mov.y;
mov.x = tempX;
mov.y = tempY;
// Зміна ID на дошці
board # 91; sel.x, sel.y] = sel.ID;
board # 91; mov.x, mov.y] = mov.ID;
Перевірка на порівняння полягає в наступному.
Ми знаємо виділений блок. Який, наприклад, чорний. Ми знаємо позицію блоку (маємо доступ до статичної змінної). Але ми не знаємо, так це - чи є 3 таких же блоку поруч з виділеним.
Щоб дізнатися це, ми:
1) Від позиції виділеного блоку підемо вправо.
2) Якщо цей блок того ж кольору, що і виділений, знову підемо вправо і відзначимо що ми знайшли +1 блок.
3) Якщо колір блоку відрізняється від виділено, зупиняємося, вправо більше не йдемо.
Майже те ж саме з іншими напрямками, за виключення того що в цьому випадку ми починаємо перевірку не з позиції виділеного блоку. Відлік ми почнемо з позиції, що стоїть перед виділеним блоком. Ми ж не хочемо перевіряти один і той же блок двічі.
Той же принцип для верхнього і нижнього напрямків.
Після цього потрібно перевірити, вийшов у нас ряд однакових блоків. Якщо countL + countR => 3, блоки зруйнуємо і відзначимо їх як порожні.
200? '200px': '' + (this.scrollHeight + 5) + 'px'); ">
bool CheckMatch (# 41;<
// отримуємо всі доступ до всіх блоків в сцені
Block # 91;] allb = FindObjectsOfType (typeof (Block # 41; # 41; as Block # 91;];
Block sel = Block.select.gameObject.GetComponent
int countU = 0; // лічильник вгору
int countD = 0; // лічильник вниз
int countL = 0; // лічильник вліво
int countR = 0; // лічильник вправо
// Вгору
for (int u = sel.y; u
countU ++;
>
// Перевіряємо, чи є ряд з трьох блоків
if (countL + countR> = 3 || countD + countU> = 3 # 41;<
if (countL + countR> = 3 # 41;<
// руйнуємо і відзначаємо порожні блоки
for (int cl = 0; cl<=countL; cl++)<
foreach (Block b in allb # 41;<
if (b.x == sel.x-cl b.y == sel.y # 41;<
Destroy (b.gameObject # 41 ;;
board # 91; b.x, b.y] = 500; // відзначаємо порожній блок
>
>
>
for (int cr = 0; cr
if (b.x == sel.x + cr b.y == sel.y # 41;<
Destroy (b.gameObject # 41 ;;
board # 91; b.x, b.y] = 500;
>
>
>
>
if (countD + countU> = 3 # 41;<
for (int cd = 0; cd<=countD; cd++)<
foreach (Block blc in allb # 41;<
if (blc.x == sel.x blc.y == sel.y - cd # 41;<
board # 91; blc.x, blc.y] = 500;
Destroy (blc.gameObject # 41 ;;
>
>
>
for (int cu = 0; cu
if (blc.x == sel.x blc.y == sel.y + cu # 41;<
board # 91; blc.x, blc.y] = 500;
Destroy (blc.gameObject # 41 ;;
>
>
>
>
Respawn (# 41 ;;
return true;
Тепер ми можемо створити нові блоки на зазначених позиціях поля. Майже те ж саме ми робили в функції GenBoard
200? '200px': '' + (this.scrollHeight + 5) + 'px'); ">
void Respawn (# 41;<
for (int x = 0; x
int randomNumber = Random.Range (0, blocks.Length # 41 ;; // ID
Transform obj = (Transform # 41; Instantiate (blocks # 91; randomNumber] .transform, new Vector3 (x, y, 0 # 41 ;, Quaternion.identity # 41 ;;
obj.parent = transform;
Block b = obj.gameObject.AddComponent
// призначимо змінні
b.ID = randomNumber;
b.x = x;
b.y = y;
// призначимо ID на дошці нове значення
board # 91; x, y] = randomNumber;
>
>
>
>
І, вже в функції Update
200? '200px': '' + (this.scrollHeight + 5) + 'px'); ">
void Update (# 41;<
if (Block.select Block.moveTo # 41;/If 2 blocks are selected, what we need more?
// Check if they are near
if (CheckIfNear (# 41; == true # 41;<
// Near
Swap (# 41 ;; // Swap their position and data
// Check for match3
if (CheckMatch (# 41; == true # 41;<
// There is match
Block.select = null;
Block.moveTo = null;
>
else<
// There is no match, return them in their default position
Swap (# 41 ;;
Block.select = null;
Block.moveTo = null;
>
>
else<
// Not near
Block.select = null;
Block.moveTo = null;
// We can again select new blocks
>
>
>