Skip to content

Commit

Permalink
lib: add canvas to menu, use canvas
Browse files Browse the repository at this point in the history
demo: finish letris
  • Loading branch information
and3rson committed Feb 8, 2024
1 parent 0fa611a commit db08171
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 35 deletions.
59 changes: 42 additions & 17 deletions firmware-demo/src/demo_letris.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@

const bool shapesData[7][4][4] = {
{{0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}}, // I
{{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, // O
{{0, 1, 1, 0}, {1, 1, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, // S
{{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, // Z
{{1, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, // T
{{1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, // L
{{1, 1, 1, 0}, {1, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, // J
{{0, 0, 0, 0}, {0, 1, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}}, // O
{{0, 0, 0, 0}, {0, 1, 1, 0}, {1, 1, 0, 0}, {0, 0, 0, 0}}, // S
{{0, 0, 0, 0}, {1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}}, // Z
{{0, 0, 0, 0}, {1, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}, // T
{{0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 1, 0}}, // L
{{0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}, {0, 1, 1, 0}}, // J
};

const uint16_t colors[7] = {
Expand Down Expand Up @@ -52,12 +52,14 @@ class Shape {
y = 0;
}

void draw() {
void draw(bool drawEmptyBlocks = false) {
for (int yy = 0; yy < 4; yy++) {
for (int xx = 0; xx < 4; xx++) {
if (this->shapeData[yy][xx]) {
canvas->fillRect(X_OFFSET + (this->x + xx) * BLOCK_SIZE, (this->y + yy) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, color);
canvas->fillRect(X_OFFSET + (this->x + xx) * BLOCK_SIZE + 2, (this->y + yy) * BLOCK_SIZE + 2, BLOCK_SIZE - 4, BLOCK_SIZE - 4, lilka::display.color565(0, 0, 0));
} else if (drawEmptyBlocks) {
canvas->fillRect(X_OFFSET + (this->x + xx) * BLOCK_SIZE, (this->y + yy) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, lilka::display.color565(0, 0, 0));
}
}
}
Expand Down Expand Up @@ -105,6 +107,27 @@ class Field {
}
}
}
// Перевіряємо, чи є рядки, які можна видалити
for (int y = 0; y < FIELD_ROWS; y++) {
bool full = true;
for (int x = 0; x < FIELD_COLS; x++) {
if (!this->blocks[y][x]) {
full = false;
break;
}
}
if (full) {
// Видаляємо рядок
for (int yy = y; yy > 0; yy--) {
for (int xx = 0; xx < FIELD_COLS; xx++) {
this->blocks[yy][xx] = this->blocks[yy - 1][xx];
}
}
for (int xx = 0; xx < FIELD_COLS; xx++) {
this->blocks[0][xx] = 0;
}
}
}
}
bool willCollide(Shape *shape, int dx, int dy) {
// Повертає true, якщо фігура зіткнеться з іншими блоками, якщо зміститься на (dx, dy)
Expand Down Expand Up @@ -133,15 +156,20 @@ void demo_letris() {
Field field(&canvas);
Shape shape(&canvas);
Shape nextShape(&canvas);
nextShape.reset();

// Вітання
while (!lilka::controller.getState().start.justPressed) {
float time = millis() / 1000.0;
canvas.fillScreen(canvas.color565(0, 0, 0));
for (uint16_t y = 0; y < 64; y++) {
int16_t xShift = sin(time * 5 + y / 4.0) * 8;
for (uint16_t x = 0; x < 128; x++) {
canvas.drawPixel(x + xShift, y, letris_splash[y * LILKA_DISPLAY_WIDTH + x]);
float yShifts[letris_splash_width];
for (uint16_t x = 0; x < letris_splash_width; x++) {
yShifts[x] = cos(time + ((float)x) / 32.0) * 8;
}
for (uint16_t y = 0; y < letris_splash_height; y++) {
int16_t xShift = sin(time * 4 + y / 8.0) * 4;
for (uint16_t x = 0; x < letris_splash_width; x++) {
canvas.drawPixel(x + xShift, LILKA_DISPLAY_HEIGHT / 2 - letris_splash_height / 2 + y + yShifts[x], letris_splash[y * letris_splash_width + x]);
}
}
lilka::display.renderCanvas(canvas);
Expand All @@ -166,7 +194,7 @@ void demo_letris() {
bool fastDrop = false;
while (1) {
// Починаємо рух фігури
int nextMove = millis() + (fastDrop ? 50 : 500);
int nextMove = millis() + (fastDrop ? 25 : 500);

// Затримуємо рух фігури, поки не наступив час для наступного кроку
while (millis() < nextMove) {
Expand All @@ -179,7 +207,7 @@ void demo_letris() {
} else if (state.down.justPressed) { // TODO: Change to right
// Користувач натиснув вправо
dx = 1;
} else if (state.start.justPressed) { // TODO: Change to down
} else if (state.start.justPressed && !fastDrop) { // TODO: Change to down
// Користувач натиснув вниз
fastDrop = true;
nextMove = 0;
Expand All @@ -194,7 +222,7 @@ void demo_letris() {
// Малюємо поле та фігуру
field.draw();
shape.draw();
nextShape.draw();
nextShape.draw(true);
// Відображаємо зміни на екрані
lilka::display.renderCanvas(canvas);
}
Expand All @@ -214,7 +242,4 @@ void demo_letris() {

// Гра закінчилася. Виводимо повідомлення на екран
lilka::ui_alert("Game over", "Гру завершено!\nТи намагався. :)");
while (!lilka::controller.getState().start.justPressed) {
delay(10);
}
}
2 changes: 1 addition & 1 deletion firmware-demo/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void demos_menu() {
};

String demos[] = {
"Лінії", "Шайба", "М'ячик", "Епілепсія", "Тетріс", "<< Назад",
"Лінії", "Шайба", "М'ячик", "Епілепсія", "Летріс", "<< Назад",
};
int count = sizeof(demos) / sizeof(demos[0]);
int cursor;
Expand Down
5 changes: 4 additions & 1 deletion lib/lilka/src/lilka/display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ void Display::renderCanvas(Canvas &canvas) {
draw16bitRGBBitmap(0, 0, canvas.getFramebuffer(), LILKA_DISPLAY_WIDTH, LILKA_DISPLAY_HEIGHT);
}

Canvas::Canvas() : Arduino_Canvas(LILKA_DISPLAY_WIDTH, LILKA_DISPLAY_HEIGHT, NULL) {}
Canvas::Canvas() : Arduino_Canvas(LILKA_DISPLAY_WIDTH, LILKA_DISPLAY_HEIGHT, NULL) {
setFont(u8g2_font_10x20_t_cyrillic);
setUTF8Print(true);
}

Display display;

Expand Down
38 changes: 22 additions & 16 deletions lib/lilka/src/lilka/ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,34 @@
namespace lilka {

int ui_menu(String title, String menu[], int menu_size, int cursor, const menu_icon_t *icons[]) {
display.fillScreen(display.color565(0, 0, 0));
Canvas canvas;
canvas.begin();
canvas.fillScreen(canvas.color565(0, 0, 0));
canvas.fillTriangle(0, 0, 64, 0, 0, 32, canvas.color565(0, 0, 255));
canvas.fillTriangle(LILKA_DISPLAY_WIDTH, LILKA_DISPLAY_HEIGHT, LILKA_DISPLAY_WIDTH - 64, LILKA_DISPLAY_HEIGHT, LILKA_DISPLAY_WIDTH, LILKA_DISPLAY_HEIGHT - 32, canvas.color565(255, 255, 0));
controller.resetState();
while (1) {
display.setCursor(32, 48);
display.setTextColor(display.color565(255, 255, 255));
display.setFont(u8g2_font_6x13_t_cyrillic);
display.setTextSize(2);
display.println(title);
display.println();
display.setTextSize(1);
display.setFont(u8g2_font_10x20_t_cyrillic);
canvas.setCursor(32, 48);
canvas.setTextColor(canvas.color565(255, 255, 255));
canvas.setFont(u8g2_font_6x13_t_cyrillic);
canvas.setTextSize(2);
canvas.println(title);
canvas.println();
canvas.setTextSize(1);
canvas.setFont(u8g2_font_10x20_t_cyrillic);

for (int i = 0; i < menu_size; i++) {
display.fillRect(0, 96 + i * 24 - 20, LILKA_DISPLAY_WIDTH, 24, i == cursor ? display.color565(255, 0, 0) : display.color565(0, 0, 0));
canvas.fillRect(0, 96 + i * 24 - 20, LILKA_DISPLAY_WIDTH, 24, i == cursor ? canvas.color565(255, 64, 0) : canvas.color565(0, 0, 0));
canvas.setTextBound(0, 96 + i * 24 - 20, LILKA_DISPLAY_WIDTH, 24);
if (icons != NULL && icons[i] != NULL) {
display.draw16bitRGBBitmap(0, 96 + i * 24 - 20, *icons[i], 24, 24);
canvas.draw16bitRGBBitmap(0, 96 + i * 24 - 20, const_cast<uint16_t *>(*icons[i]), 24, 24);
}
display.setCursor(32, 96 + i * 24);
display.setTextColor(display.color565(255, 255, 255));
canvas.setCursor(32, 96 + i * 24);
canvas.setTextColor(canvas.color565(255, 255, 255));
// gfx->print(i == cursor ? "> " : " ");
display.println(menu[i]);
canvas.println(menu[i]);
}
display.renderCanvas(canvas);

State state = controller.getState();

Expand Down Expand Up @@ -67,14 +73,14 @@ void ui_alert(String title, String message) {

controller.resetState();

display.fillRect(left, top, width, mid - top, display.color565(32, 96, 96));
display.fillRect(left, top, width, mid - top, display.color565(32, 32, 128));
display.setFont(u8g2_font_6x13_t_cyrillic);
display.setTextSize(2);
display.setTextBound(left + xMargin, top, width - xMargin * 2, mid - top);
display.setCursor(left + xMargin, top + 13 * 2);
display.println(title);

display.fillRect(left, mid, width, bottom - mid, display.color565(32, 32, 32));
display.fillRect(left, mid, width, bottom - mid, display.color565(32, 96, 96));
display.setFont(u8g2_font_10x20_t_cyrillic);
display.setTextSize(1);
display.setTextBound(left + xMargin, top, width - xMargin * 2, bottom - mid);
Expand Down

0 comments on commit db08171

Please sign in to comment.