В предыдущей части я закодировал каждую фигуру Тетриса в 16-битное число и поместил все фигуры-числа в массив.
Когда фигура будет падать внутри "стакана", или когда игрок будет её двигать и поворачивать, мне надо будет решать вопрос: может ли фигура передвинуться из своего текущего положения в новое положение? Она не может переместиться или повернуться, если в её новом положении какая-то из клеток "стакана" окажется уже занята.
Если бы "стакан" был матрицей 12*21 и фигура была матрицей 4*4, то мне пришлось бы осуществлять такие проверки:
Я бы по очереди брал каждый элемент фигуры, и если там находится кубик (1), я бы выяснял, где относительно начала стакана находится этот элемент (падающая фигура имеет позицию внутри стакана, а кубик имеет позицию внутри фигуры). Получив позицию кубика фигуры, я бы посмотрел, что находится в стакане в этой позиции. Если там тоже находится кубик (1), то фигура там поставлена быть не может. Значит, надо будет решать, что с ней делать дальше.
В моём случае вся матрица фигуры упакована в одно число, но это не помешает мне добывать из неё элементы. Матрица "стакана" также упакована построчно, одно число – одна строка (используется 12 бит из 16-ти). Фигуру я тоже могу развернуть в 4 строки (это не тип "строка", это горизонтальный ряд матрицы):
Чтобы перемещать фигуру влево и вправо, я могу использовать битовые сдвиги внутри строки:
Стало быть, если есть строки стакана и строки фигуры, я могу просто наложить эти строки друг на друга как двоичные числа и сразу узнать, не пересекаются ли они. Не надо будет проверять каждый кубик фигуры по отдельности. Так как фигура состоит из 4-х строк, то нужно осуществить только 4 проверки путем побитного "И" с содержимым "стакана".
Пока что я написал функцию, которая распаковывает фигуру из 16-битного числа, возвращая массив из 4-х чисел – строк фигуры.
И также я написал функцию, которая рисует фигуру на экране, чтобы убедиться в том, что все фигуры были заданы правильно и нет никаких проблем с отображением.
Попутно я выяснил, что в предыдущей части неправильно закодировал одну фигуру, так что исправил эту ошибку. Я получил такой результат и вижу, что всё в порядке:
Я пока ничего не оптимизировал. Нужно получить рабочий код, и тогда станет понятнее, как подходить к его оптимизации. Текущий код можно посмотреть и проверить живьем по ссылке.
В следующей части я сделаю движение и повороты фигуры с помощью клавиш и проверки в стакане.