Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Unity_в_действии_Джозеф_Хокинг_Рус.pdf
Скачиваний:
82
Добавлен:
21.06.2022
Размер:
26.33 Mб
Скачать

5.3. Отображение различных карт      127

float posY = -(offsetY * j) + startPos.y;

card.transform.position = new Vector3(posX, posY, startPos.z); ¬ В двухмерной

графике нам нужно только смещение по осям X и Y; значение Z не меняется.

}

}

}

}

Хотя этот сценарий намного длиннее предыдущих, объяснять тут особо нечего, потому что большинство дополнений представляют собой обычные объявления переменных и математические вычисления. Самым странным фрагментом кода является, вероятно, выражение, начинающее условную инструкцию if (i == 0 && j == 0). Это выражение заставляет либо выбрать исходный объект-карту для первой ячейки нашей сетки, либо клонировать этот объект для остальных ячеек. Так как исходная карта в сцене уже есть, ее копирование на каждом шаге цикла приведет к появлению слишком большого количества карт. Карты раскладываются путем смещения в соответствии с количеством итераций цикла.

СОВЕТ  Двухмерные объекты, как и трехмерные, можно двигать в различные места экрана, меняя значение transform.position, причем это значение может все время увеличиваться внутри метода Update(). Но как вы видели в процессе перемещения объекта-игрока, прямое редактирование параметра transform.position не позволяет добавить механизм распознавания столкновений. Аналогично, для перемещения двухмерных объектов с распознаванием столкновений нужно добавить к объекту компоненты группы Physics2D и редактировать, например, параметр rigidbody2D.velocity.

Запустите код, и в сцене появится сетка из восьми карт, показанная на рис. 5.9. Теперь нам осталось только разбить карты на пары.

Рис. 5.9. Сетка из восьми карты, которые открываются щелчком мыши

5.3.4. Тасуем карты

Пока наши карты представляют собой не зависящие друг от друга объекты, но мы определим массив из их идентификаторов (чисел от 0 до 3, сопоставленных каждой

128      Глава 5. Игра Memory на основе новой 2D-функциональности

паре карт) и затем перемешаем элементы этого массива. Именно он послужит нам основой при выкладке карт. Код представлен в следующем листинге.

Листинг 5.7. Раскладка карт из перемешанного списка

...

void Start() { ¬ Большая часть листинга — это контекст, показывающий, куда вставлять дополнения.

Vector3 startPos = originalCard.transform.position;

int[] numbers = {0, 0, 1, 1, 2, 2, 3, 3}; ¬

Объявляем целочисленный массив с парами идентификато-

 

 

 

 

ров для всех четырех спрайтов с изображениями карт.

numbers = ShuffleArray(numbers); ¬ Вызов функции, перемешивающей элементы массива.

for (int i =

0; i

< gridCols; i++) {

 

for (int j

=

0;

j < gridRows; j++) {

 

MemoryCard

card;

 

if (i ==

0

&&

j == 0) {

 

card =

originalCard;

 

}else {

card = Instantiate(originalCard) as MemoryCard;

}

int index = j * gridCols + i;

int id = numbers[index]; ¬ Получаем идентификаторы из перемешанного списка, а не из случайных чисел. card.SetCard(id, images[id]);

float posX = (offsetX * i) + startPos.x; float posY = -(offsetY * j) + startPos.y;

card.transform.position = new Vector3(posX, posY, startPos.z);

}

}

}

private int[] ShuffleArray(int[] numbers) { ¬ Реализация алгоритма тасования Кнута. int[] newArray = numbers.Clone() as int[];

for (int i = 0; i < newArray.Length; i++ ) { int tmp = newArray[i];

int r = Random.Range(i, newArray.Length); newArray[i] = newArray[r];

newArray[r] = tmp;

}

return newArray;

}

...

Теперь после щелчка на кнопке Play сетка будет заполнена картами из перемешанного набора, в котором присутствует ровно по две карты каждого вида. Массив карт пропущен через алгоритм тасования Кнута (еще его называют алгоритмом Фишера— Йетса), который предлагает простой, но эффективный способ перемешать элементы массива. Он в цикле просматривает элементы массива и меняет местами каждый элемент с другим элементом, выбранным случайным образом.

Можно щелчками мыши открыть все карты, но в игре Memory карты должны открываться парами, поэтому нам нужен дополнительный код.