Эксперимент 52. Игровое поле

Создадим игру «Сокобан». Sokoban — логическая игра-головоломка, в которой игрок передвигает ящики по лабиринту, показанному в виде плана, с целью поставить все ящики на заданные конечные позиции. Только один ящик может быть передвинут за раз, причём герой игры — «кладовщик» — может только толкать ящики, но не тянуть их.

Отображать игру будем на TFT дисплее, управлять кладовщиком будем с помощью кнопок. Игровое поле разобьем на клетки 16 на 16 пикселей. Разрешение дисплея 128 на 160 пикселей. Получается 8 на 10 клеток. Отображать графику будем с помощью спрайтов — маленьких картинок. Мы уже подготовили набор спрайтов, в который входят картинка для стены, ящика, цели и кладовщика. Их нужно загрузить во внутреннюю память микроконтроллера.

Начнем с построения игрового поля — лабиринта. Нужно описать в каких клетках есть стена, а в каких нет. Проще всего это сделать с помощью двумерного массива. Число 1 будет обозначать наличие стены, а 0 — ее отсутствие.

Схема эксперимента

Рисунок 1. Монтажная схема эксперимента для дисплея с 8 выводами

Рисунок 2. Монтажная схема эксперимента для дисплея с 11 выводами

Программный код эксперимента

Exp52.ino
  1. #include <SPI.h>
  2. #include <Adafruit_ST7735.h>
  3. #include "LittleFS_ImageReader.h"
  4.  
  5. #define PIN_CS 2
  6. #define PIN_DC 4
  7. #define PIN_RST 5
  8.  
  9. Adafruit_ST7735 tft = Adafruit_ST7735(PIN_CS, PIN_DC, PIN_RST);
  10. LittleFS_ImageReader reader;
  11.  
  12. bool Map[10][8] = {
  13. {1,1,0,1,1,1,0,1},
  14. {0,1,1,1,1,1,1,0},
  15. {1,1,0,0,0,1,1,1},
  16. {0,1,0,1,0,1,0,1},
  17. {0,1,0,0,0,1,0,1},
  18. {1,1,1,1,0,0,0,1},
  19. {1,0,0,0,0,0,0,1},
  20. {1,0,0,0,1,0,0,1},
  21. {1,0,0,0,1,1,1,1},
  22. {1,1,1,1,1,0,0,0}
  23. };
  24.  
  25. void setup() {
  26. os_update_cpu_frequency(160);
  27. LittleFS.begin();
  28. tft.initR(INITR_BLACKTAB);
  29. tft.setRotation(2);
  30. tft.fillScreen(ST77XX_BLACK);
  31.  
  32. for (int y = 0; y < 10; y++) {
  33. for (int x = 0; x < 10; x++) {
  34. if (Map[y][x]) reader.drawBMP("/brick.bmp", tft, x * 16, y * 16);
  35. }
  36. }
  37. }
  38.  
  39. void loop() {
  40. }

Мы объявили двумерный массив Map с описанием игровой карты. И в цикле перебираем все ее элементы. Те элементы, где присутствует 1 мы рисуем изображение стены (картинка brick.bmp).