===== Эксперимент 52. Игровое поле ===== Создадим игру "Сокобан". Sokoban — логическая игра-головоломка, в которой игрок передвигает ящики по лабиринту, показанному в виде плана, с целью поставить все ящики на заданные конечные позиции. Только один ящик может быть передвинут за раз, причём герой игры — «кладовщик» — может только толкать ящики, но не тянуть их. [[https://ru.wikipedia.org/wiki/Sokoban|Подробнее об игре Sokoban]] Отображать игру будем на TFT дисплее, управлять кладовщиком будем с помощью кнопок. Игровое поле разобьем на клетки 16 на 16 пикселей. Разрешение дисплея 128 на 160 пикселей. Получается 8 на 10 клеток. Отображать графику будем с помощью //спрайтов// — маленьких картинок. Мы уже подготовили набор спрайтов, в который входят картинка для стены, ящика, цели и кладовщика. Их нужно загрузить во внутреннюю память микроконтроллера. {{ :products:esp-iot:sokoban_sprites.zip |}} Начнем с построения игрового поля — лабиринта. Нужно описать в каких клетках есть стена, а в каких нет. Проще всего это сделать с помощью двумерного массива. Число 1 будет обозначать наличие стены, а 0 — ее отсутствие. ==== Схема эксперимента ==== {{ :products:esp-iot:exp25_mont.png?direct&600 |}} //Рисунок 1. Монтажная схема эксперимента для дисплея с 8 выводами// {{ :products:esp-iot:exp25_mont_11pin.png?direct&600 |}} //Рисунок 2. Монтажная схема эксперимента для дисплея с 11 выводами// ==== Программный код эксперимента ==== #include #include #include "LittleFS_ImageReader.h" #define PIN_CS 2 #define PIN_DC 4 #define PIN_RST 5 Adafruit_ST7735 tft = Adafruit_ST7735(PIN_CS, PIN_DC, PIN_RST); LittleFS_ImageReader reader; bool Map[10][8] = { {1,1,0,1,1,1,0,1}, {0,1,1,1,1,1,1,0}, {1,1,0,0,0,1,1,1}, {0,1,0,1,0,1,0,1}, {0,1,0,0,0,1,0,1}, {1,1,1,1,0,0,0,1}, {1,0,0,0,0,0,0,1}, {1,0,0,0,1,0,0,1}, {1,0,0,0,1,1,1,1}, {1,1,1,1,1,0,0,0} }; void setup() { os_update_cpu_frequency(160); LittleFS.begin(); tft.initR(INITR_BLACKTAB); tft.setRotation(2); tft.fillScreen(ST77XX_BLACK); for (int y = 0; y < 10; y++) { for (int x = 0; x < 10; x++) { if (Map[y][x]) reader.drawBMP("/brick.bmp", tft, x * 16, y * 16); } } } void loop() { } Мы объявили двумерный массив ''Map'' с описанием игровой карты. И в цикле перебираем все ее элементы. Те элементы, где присутствует 1 мы рисуем изображение стены (картинка brick.bmp).