Этот урок возник в связи с тем, что мы делали обзор на другие источники и выяснили, что большинство из них напрямую завязаны на Unity. Мы же хотели бы сделать универсальное и максимально понятное, модульное решение, котороe не зависело от движка и могло быть использовано в любом языке программирования будь то Java, С++
Download completed: https://www.dropbox.com/s/5i0fr7kst2j2hut/Tetris.unitypackage?dl=0
Необходимые знания: двумерные массивы, циклы, создание объектов из кода в Unity
Начнем.
Download starter: https://www.dropbox.com/s/drt5wsmlk6yncwj/TetrisStarter.unitypackage?dl=0
1. Создадим скрипт Tetris и повесим его на Main Camera.
2. Игровое поле зададим 2мерным массивом размером 16x8. Все действия будут происходить именно в массиве, а мы лишь будем визуализировать результат средствами Unity. Необходимо инициализировать его заполнив конкретными значениями, для того, чтобы было проще тестировать наш алгоритм.
3. Объявим двумерный массив из int'ов как глобальную переменную.
public class Tetris : Monobehaviour{
int[,] pole = new int[,]{
{0,0,0,0,0,0,0,0},
{0,0,0,1,1,1,0,0},
{0,0,0,0,1,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,2,0},
{0,0,0,0,0,0,2,0},
{2,0,0,0,0,0,2,2},
{2,2,2,2,2,2,2,2},
{2,0,0,0,0,0,2,2},
{2,0,0,0,0,2,2,2},
{2,0,0,0,2,2,2,2},
{2,2,2,2,2,2,2,2},
{2,2,2,2,2,2,2,2},
};
void Start(){
}
void Update(){
}
}
Это не размер оригинального поля, но вполне достаточно, чтобы тестировать основные моменты. В таком массиве
0 - пустое место,
1 - фигура, которая падает,
2 - блоки, которые уже упали.
4. Следующим шагом будет визуализация нашего массива. Для этого понадобится картинка блока тетриса размером 100x100 пикселей, чтобы в мире размер одного блока составлял 1x1 метр и нам не нужно было масштабировать наши блоки.
5. Из этого sprite создадим prefab. Можно пометить его static для частичной оптимизации.
6. В нашем тетрисе получим к нему доступ объявив публичную переменную
public GameObject pfbBlock;
7. Идея визуализации такова: мы изначально создадим все поле из квадратов, а потом будем включать и выключать их в зависимости от содержимого массива pole.
8. Нам очевидно потребуется получать доступ к этим блока и где-то их хранить. Будем их хранить в двумерном массиве из GameObject
GameObject[,] allBlocks;
9. Создадим ф-ю Fill, котороя и создаст все игровые блоки и поместит их в двумерный массив allBlocks.
10. Внутри Fill
allBlocks = new GameObject[16,8];
for( int y=0;y<16;y++){
for( int x=0;x<8;x++){
allBlocks[y,x] = GameObject.Instanciate( blockPfb ); //создаем и помещаем кубик в массив
allBlocks[y,x].transform.position = new Vector3( x, 15 - y, 0 ); //мы специально отнимаем от 15 y иначе наше поле нарисуется отраженным сверху вниз, потому что координаты в массиве идут вниз и вправо, а в Unity вверх и вправо.
}
}
11. Вызовем ф-ю Fill, после инициализации нашего поля.
Если мы сейчас запустим игру все поле должно быть в квадратах. Настройте камеру так, чтобы вы видели все игровое поле.
12. Создадим ф-ю Draw без параметров ничего не возвращающую
13. Вызываем ф-ю Draw в Update;
14. Внутри Draw будем анилизировать наш массив pole и в зависимости от того какое в нем число включать или выключать нужный кубик на экране. Для того чтобы пройтить по двумерному массиву нам понадобится for внутри for сначала по строкам, потом по x.
for (int y = 0; y < 16; y++) {
for (int x = 0; x < 8; x++) {
if ( pole[y,x] > 0 ){
blocks[y,x].SetActive( true );
}
else{
blocks[y,x].SetActive( false );
}
}
}
15. После запуска игры вы должны увидеть ваше игровое поле на экране.
Следующая часть
Download completed: https://www.dropbox.com/s/5i0fr7kst2j2hut/Tetris.unitypackage?dl=0
Необходимые знания: двумерные массивы, циклы, создание объектов из кода в Unity
Начнем.
Download starter: https://www.dropbox.com/s/drt5wsmlk6yncwj/TetrisStarter.unitypackage?dl=0
1. Создадим скрипт Tetris и повесим его на Main Camera.
2. Игровое поле зададим 2мерным массивом размером 16x8. Все действия будут происходить именно в массиве, а мы лишь будем визуализировать результат средствами Unity. Необходимо инициализировать его заполнив конкретными значениями, для того, чтобы было проще тестировать наш алгоритм.
3. Объявим двумерный массив из int'ов как глобальную переменную.
public class Tetris : Monobehaviour{
int[,] pole = new int[,]{
{0,0,0,0,0,0,0,0},
{0,0,0,1,1,1,0,0},
{0,0,0,0,1,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,2,0},
{0,0,0,0,0,0,2,0},
{2,0,0,0,0,0,2,2},
{2,2,2,2,2,2,2,2},
{2,0,0,0,0,0,2,2},
{2,0,0,0,0,2,2,2},
{2,0,0,0,2,2,2,2},
{2,2,2,2,2,2,2,2},
{2,2,2,2,2,2,2,2},
};
void Start(){
}
void Update(){
}
}
Это не размер оригинального поля, но вполне достаточно, чтобы тестировать основные моменты. В таком массиве
0 - пустое место,
1 - фигура, которая падает,
2 - блоки, которые уже упали.
4. Следующим шагом будет визуализация нашего массива. Для этого понадобится картинка блока тетриса размером 100x100 пикселей, чтобы в мире размер одного блока составлял 1x1 метр и нам не нужно было масштабировать наши блоки.
5. Из этого sprite создадим prefab. Можно пометить его static для частичной оптимизации.
6. В нашем тетрисе получим к нему доступ объявив публичную переменную
public GameObject pfbBlock;
7. Идея визуализации такова: мы изначально создадим все поле из квадратов, а потом будем включать и выключать их в зависимости от содержимого массива pole.
8. Нам очевидно потребуется получать доступ к этим блока и где-то их хранить. Будем их хранить в двумерном массиве из GameObject
GameObject[,] allBlocks;
9. Создадим ф-ю Fill, котороя и создаст все игровые блоки и поместит их в двумерный массив allBlocks.
10. Внутри Fill
allBlocks = new GameObject[16,8];
for( int y=0;y<16;y++){
for( int x=0;x<8;x++){
allBlocks[y,x] = GameObject.Instanciate( blockPfb ); //создаем и помещаем кубик в массив
allBlocks[y,x].transform.position = new Vector3( x, 15 - y, 0 ); //мы специально отнимаем от 15 y иначе наше поле нарисуется отраженным сверху вниз, потому что координаты в массиве идут вниз и вправо, а в Unity вверх и вправо.
}
}
11. Вызовем ф-ю Fill, после инициализации нашего поля.
Если мы сейчас запустим игру все поле должно быть в квадратах. Настройте камеру так, чтобы вы видели все игровое поле.
12. Создадим ф-ю Draw без параметров ничего не возвращающую
13. Вызываем ф-ю Draw в Update;
14. Внутри Draw будем анилизировать наш массив pole и в зависимости от того какое в нем число включать или выключать нужный кубик на экране. Для того чтобы пройтить по двумерному массиву нам понадобится for внутри for сначала по строкам, потом по x.
for (int y = 0; y < 16; y++) {
for (int x = 0; x < 8; x++) {
if ( pole[y,x] > 0 ){
blocks[y,x].SetActive( true );
}
else{
blocks[y,x].SetActive( false );
}
}
}
15. После запуска игры вы должны увидеть ваше игровое поле на экране.
Почему ты объявил массив allBlocks ,а в Fill меняешь blocks
ОтветитьУдалить