Эта тема уже несколько раз затрагивалась на форуме, и где-то даже был работающий пример. Однако вновь и вновь актуальность проявляется, но при этом пример становится найти всё труднее и труднее. Поэтому я решил создать эту тему, в которой разъясняется принцип работы и присутствует пример.
Итак, задача: например, есть курсор, которым мы рисуем блоки с рельсами и внешний вид этих блоков должен автоматически менять вид в зависимости от блоков, стоящих по соседству. Например, если мы нарисовали горизонтальную линию из блоков, а после вертикальную, то в вертикальной линии рельсы идти вертикально, в горизонтальной - горизонтально, а в месте пересечения будет крестовина.
Алгоритм весьма прост и для вычисления номера кадра спрайта использует всего 4 двоичных операции.
Итак, чтобы рассчитать номер кадра, мы проверяем блоки вокруг и устанавливаем в переменной соответствующие биты, если какой-либо блок присутствует.
В моём примере за каждый блок вокруг отвечает один бит в переменной env:
слева - бит 0
справа - бит 1
сверху - бит 2
снизу - бит 3
в итоге у нас получается 16 всевозможных вариантов:
нвпл (низ, верх, право, лево)
0 0000 нет блоков округ
1 0001 блок слева
2 0010 блок справа
3 0011 блок слева и блок справа
4 0100 блок сверху и так далее
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
Тут четырьмя цифрами указано двоичное значение, а слева - соответствующее ему десятичное. Оно же и является номером нужного кадра. Секрет в том, что спрайты стоят именно в таком порядке, поэтому нам не нужно ничего дополнительно высчитывать.
Итак, сначала заносим в переменную ноль (сбрасываем все биты). Дальше проверили, есть ли блок слева. Если да, то устанавливаем бит 0. Следующий - справа. Если есть, то устанавливаем бит 1. И так далее. В итоге получили номер кадра.
После этого нужно также не забыть изменить внешний вид прилегающих блоков.
Собственно, пример...
Использую там два варианта спрайта: один - railway, то есть некое условное подобие железной дороги, второй - block, служащий в качестве блоков земли, из которых мы строим остров. Переключение клавишами 1 и 2.
Извиняюсь за "художество". У меня не было цели делать более реалистичные рисунки (рельсы со шпалами, берег реки и т.п.), поэтому всё нарисовано довольно условно.
upd: ссылка на вариант с анализом 8 окружающих блоков (то есть используется 8 бит).