walking stickman is now also crawling
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]);
|
||||
|
||||
Reference in New Issue
Block a user