walking stickman is now also crawling

This commit is contained in:
Priec
2025-11-14 14:12:40 +01:00
parent 13f01d13f8
commit b147d92423
22 changed files with 135 additions and 25 deletions

View File

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

@@ -0,0 +1,7 @@
.....a@$..
.....7PF..
..yaM@@__y
..@.y@FFF~
..._$M@_..
yaa@~.`@y.
........@r

View File

@@ -0,0 +1,7 @@
.g@$
.7PF
y@$.
0@F.
4@$.
y$@.
u@..

View File

@@ -0,0 +1,9 @@
......_g@$w..
......4@@@F..
.....yyyy`...
...g@~@@@y_ys
..4F..@@FTF~.
.....g@@g,...
..._a@^.4@_..
4R@F~....7@y.
..........~@.

View File

@@ -0,0 +1,4 @@
.._$@.
.$By`.
4@$@@a
aa@W@.

View File

@@ -0,0 +1,3 @@
a@@Bw_,
7@@Db@$
4@@PF#@

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -0,0 +1,4 @@
chafa --symbols ascii-block -c none --fill none --invert --size=13x20 predloha_run_a.jpg > out.txt
a = 78x111
b = 34x111

View File

@@ -4,6 +4,7 @@
#include "background.h"
#include "mbed.h"
#include "player.h"
#include "player_mask.h"
#include <cstring>
extern BufferedSerial serial_port;
@@ -17,19 +18,24 @@ static bool message_active = false;
void draw_mask(const char *unused_filename, int shift, const char *text);
static bool read_uart() {
// Returns:
// 0 = no change - walk1
// 1 = normal redraw - walk2
// 2 = button triggered - crawl1
static int read_uart() {
bool changed = false;
bool triggered = false;
// cita spravu z uartu
if (serial_port.readable()) {
memset(rx_buffer, 0, sizeof(rx_buffer));
ssize_t num = serial_port.read(rx_buffer, sizeof(rx_buffer) - 1);
if (num > 0) {
// toogle ledky
led = !led;
led = !led; // toogle ledky
strncpy(message, rx_buffer, sizeof(message) - 1);
message_active = true;
changed = true;
triggered = true;
}
}
@@ -49,11 +55,15 @@ static bool read_uart() {
changed = true;
}
return changed;
if (triggered)
return 2; // LED toggled press
if (changed)
return 1;
return 0;
}
static bool update_animation(Timer &anim_timer, int &shift, int speed) {
if (anim_timer.elapsed_time() >= 200ms) {
if (anim_timer.elapsed_time() >= 170ms) {
// speed determines scroll steps per tick
shift += speed;
anim_timer.reset();
@@ -75,17 +85,28 @@ void render_loop(int speed) {
while (true) {
need_redraw = false;
if (read_uart()) {
need_redraw = true;
}
int uart_state = read_uart(); // returns 0/1/2
if (uart_state == 1)
need_redraw = true;
bool triggered = (uart_state == 2);
if (update_animation(anim_timer, shift, speed))
need_redraw = true;
if (need_redraw) {
draw_mask(bg_file, shift, message_active ? message : nullptr);
draw_player(18, 16);
ThisThread::sleep_for(50ms);
if (need_redraw || triggered) {
draw_mask(bg_file, shift, message_active ? message : nullptr);
static int frame = 0;
if (triggered) {
// Display triggered frame once
draw_player(18, 13, 2);
} else {
draw_player(18, 13, frame);
frame = (frame + 1) % 2; // alternate between frame 0 and 1
}
ThisThread::sleep_for(50ms);
}
ThisThread::sleep_for(25ms);

View File

@@ -4,16 +4,32 @@
#include "player_mask.h"
#include <cstdio>
void draw_player(int view_width, int view_height) {
const int sprite_height = PLAYER_MASK_LINES;
const int sprite_width = 3; // all rows are same width (3 chars)
void draw_player(int view_width, int view_height, int frame_index) {
if (frame_index < 0 || frame_index >= PLAYER_FRAME_COUNT)
frame_index = 0; // fallback
const char **sprite = PLAYER_FRAMES[frame_index];
int sprite_height = 0;
if (frame_index == 0)
sprite_height = PLAYER_MASK_LINES_FRAME_1;
else if (frame_index == 1)
sprite_height = PLAYER_MASK_LINES_FRAME_2;
else
sprite_height = PLAYER_MASK_LINES_FRAME_3;
// Width from first line
int sprite_width = 0;
if (sprite_height > 0) {
const char *first_line = sprite[0];
while (first_line[sprite_width] != '\0')
sprite_width++;
}
int center_x = view_width / 2 - sprite_width / 2;
int center_y = view_height / 2 - sprite_height / 2;
for (int i = 0; i < sprite_height; i++) {
printf("\033[%d;%dH%s", center_y + i + 1, center_x + 1, PLAYER_MASK[i]);
printf("\033[%d;%dH%s", center_y + i + 1, center_x + 1, sprite[i]);
}
fflush(stdout);
}

View File

@@ -2,4 +2,4 @@
#pragma once
// Draw the player object centered over the background
void draw_player(int view_width, int view_height);
void draw_player(int view_width, int view_height, int frame_index);

View File

@@ -1,12 +1,50 @@
// src/render/player_mask.h
#pragma once
// Simple 3x3 player sprite for overlay drawing
static const char *PLAYER_MASK[] = {
" @ ",
"/|\\",
"/ \\"
// Player frame 1
static const char *PLAYER_MASK_FRAME_1[] = {
".....a@$..",
".....7PF..",
"..yaM@@__y",
"..@.y@FFF~",
"..._$M@_..",
"yaa@~.`@y.",
"........@r"
};
static const int PLAYER_MASK_LINES =
sizeof(PLAYER_MASK) / sizeof(PLAYER_MASK[0]);
// Player frame 2
static const char *PLAYER_MASK_FRAME_2[] = {
".g@$",
".7PF",
"y@$.",
"0@F.",
"4@$.",
"y$@.",
"u@.."
};
// Player frame 3 (triggered)
static const char *PLAYER_MASK_FRAME_3[] = {
".._$@.",
".$By`.",
"4@$@@a",
"aa@W@."
};
// Combine frames for easy access
static const char **PLAYER_FRAMES[] = {
PLAYER_MASK_FRAME_1, // 0
PLAYER_MASK_FRAME_2, // 1
PLAYER_MASK_FRAME_3 // 2 (triggered)
};
static const int PLAYER_FRAME_COUNT = sizeof(PLAYER_FRAMES) / sizeof(PLAYER_FRAMES[0]);
// Line counts per frame
static const int PLAYER_MASK_LINES_FRAME_1 =
sizeof(PLAYER_MASK_FRAME_1) / sizeof(PLAYER_MASK_FRAME_1[0]);
static const int PLAYER_MASK_LINES_FRAME_2 =
sizeof(PLAYER_MASK_FRAME_2) / sizeof(PLAYER_MASK_FRAME_2[0]);
static const int PLAYER_MASK_LINES_FRAME_3 =
sizeof(PLAYER_MASK_FRAME_3) / sizeof(PLAYER_MASK_FRAME_3[0]);