crawl was redesigned to crwal1 and crawl2

This commit is contained in:
Filipriec
2025-11-16 22:40:09 +01:00
parent cf07c9c47a
commit 42ad5ee7a2
7 changed files with 75 additions and 36 deletions

View File

@@ -1,8 +1,8 @@
// src/assets/character_crawl_frames.h
#pragma once
// Crawl frame 1
static const char *CRAWL_FRAME_1[] = {
// Crawl1 frame 1
static const char *CRAWL1_FRAME_1[] = {
"........",
"........",
"...y4@W.",
@@ -11,8 +11,8 @@ static const char *CRAWL_FRAME_1[] = {
".aa@s@.."
};
// Crawl frame 2
static const char *CRAWL_FRAME_2[] = {
// Crawl2 frame 1
static const char *CRAWL2_FRAME_1[] = {
"........",
"........",
"........",
@@ -21,18 +21,22 @@ static const char *CRAWL_FRAME_2[] = {
".a@@PR@L"
};
enum class CrawlFrame {
enum class CrawlType {
Crawl1 = 0,
Crawl2,
COUNT
};
static const char **CHARACTER_CRAWL_FRAMES[] = {
CRAWL_FRAME_1,
CRAWL_FRAME_2
static const char **CHARACTER_CRAWL1_FRAMES[] = {
CRAWL1_FRAME_1,
};
static const char **CHARACTER_CRAWL2_FRAMES[] = {
CRAWL2_FRAME_1,
};
static const int CHARACTER_CRAWL_FRAME_COUNT = sizeof(CHARACTER_CRAWL_FRAMES) / sizeof(CHARACTER_CRAWL_FRAMES[0]);
static const int CHARACTER_CRAWL1_FRAME_COUNT = sizeof(CHARACTER_CRAWL1_FRAMES) / sizeof(CHARACTER_CRAWL1_FRAMES[0]);
static const int CHARACTER_CRAWL2_FRAME_COUNT = sizeof(CHARACTER_CRAWL2_FRAMES) / sizeof(CHARACTER_CRAWL2_FRAMES[0]);
// Height (rows per crawl frame)
static const int CHARACTER_CRAWL_FRAME_HEIGHT = sizeof(CRAWL_FRAME_1) / sizeof(CRAWL_FRAME_1[0]);
static const int CHARACTER_CRAWL1_FRAME_HEIGHT = sizeof(CRAWL1_FRAME_1) / sizeof(CRAWL1_FRAME_1[0]);
static const int CHARACTER_CRAWL2_FRAME_HEIGHT = sizeof(CRAWL2_FRAME_1) / sizeof(CRAWL2_FRAME_1[0]);

View File

@@ -8,6 +8,7 @@
#include <cmath>
namespace {
// Vygenerovane AI, proste to nahodne vymiena obrazky - assests
// Frame selector with two regimes:
// 1) Normal (speed <= 6): pingpong with holds at both ends
// 2) Highspeed (speed >= 7): 0, random(1..last-1), last, random(1..last-1)...
@@ -92,22 +93,26 @@ static inline int compute_frame_index(int frame_count,
void WalkingState::update() {
// stop crawling after duration
if (current_state == PlayerState::Crawl &&
if ((current_state == PlayerState::Crawl1 ||
current_state == PlayerState::Crawl2) &&
state_timer.elapsed_time() >= CRAWL_DURATION) {
current_state = PlayerState::Walk;
state_timer.stop();
}
}
void WalkingState::start_crawl() {
current_state = PlayerState::Crawl;
void WalkingState::start_crawl(PlayerState crawl_type) {
if (crawl_type != PlayerState::Crawl1 && crawl_type != PlayerState::Crawl2)
return;
current_state = crawl_type;
state_timer.reset();
state_timer.start();
}
void WalkingState::set_state(PlayerState s) {
if (current_state != s) {
walk_index = run_index = crawl_index = 0;
walk_index = run_index = crawl1_index = crawl2_index = 0;
phase = 0.0f;
}
current_state = s;
@@ -127,18 +132,19 @@ void WalkingState::set_motion_state_for_speed(int player_speed, int ground_speed
void WalkingState::toggle_walk_frame(float player_speed, int tick_counter) {
switch (current_state) {
case PlayerState::Run:
run_index =
compute_frame_index(CHARACTER_RUN_FRAME_COUNT, player_speed, tick_counter);
run_index = compute_frame_index(CHARACTER_RUN_FRAME_COUNT, player_speed, tick_counter);
break;
case PlayerState::Walk:
walk_index =
compute_frame_index(CHARACTER_WALK_FRAME_COUNT, player_speed, tick_counter);
walk_index = compute_frame_index(CHARACTER_WALK_FRAME_COUNT, player_speed, tick_counter);
break;
case PlayerState::Crawl:
crawl_index =
compute_frame_index(CHARACTER_CRAWL_FRAME_COUNT, player_speed, tick_counter);
case PlayerState::Crawl1:
crawl1_index = compute_frame_index(CHARACTER_CRAWL1_FRAME_COUNT, player_speed, tick_counter);
break;
case PlayerState::Crawl2:
crawl2_index = compute_frame_index(CHARACTER_CRAWL2_FRAME_COUNT, player_speed, tick_counter);
break;
}
}
@@ -154,9 +160,13 @@ FrameSelection WalkingState::get_frame_selection() const {
f.movement = MovementType::Run;
f.frame_index = run_index;
break;
case PlayerState::Crawl:
f.movement = MovementType::Crawl;
f.frame_index = crawl_index;
case PlayerState::Crawl1:
f.movement = MovementType::Crawl1;
f.frame_index = crawl1_index;
break;
case PlayerState::Crawl2:
f.movement = MovementType::Crawl2;
f.frame_index = crawl2_index;
break;
default:
f.movement = MovementType::Walk;

View File

@@ -5,7 +5,7 @@
constexpr auto CRAWL_DURATION = 300ms;
enum class PlayerState { Walk, Run, Crawl };
enum class PlayerState { Walk, Run, Crawl1, Crawl2 };
struct FrameSelection {
MovementType movement;
@@ -18,12 +18,13 @@ private:
Timer state_timer;
int walk_index = 0; // cycles 06
int run_index = 0; // cycles 06
int crawl_index = 0; // cycles 01
int crawl1_index = 0; // cycles 01
int crawl2_index = 0; // cycles 01
float phase = 0.0f;
public:
void update();
void start_crawl();
void start_crawl(PlayerState crawl_type);
void set_motion_state_for_speed(int player_speed, int ground_speed);
void toggle_walk_frame(float player_speed, int tick_counter);

View File

@@ -54,8 +54,20 @@ void render_loop(int speed) {
}
if (uart_event == UartEvent::Triggered) {
// start crawl frame for x time
player_state.start_crawl();
const char* msg = uart.get_message();
PlayerState current = player_state.get_state();
if (msg && strstr(msg, "crawl2")) {
// enter Crawl2 only if currently crawling in crawl1
if (current == PlayerState::Crawl1)
player_state.start_crawl(PlayerState::Crawl2);
}
else if (msg && strstr(msg, "crawl")) {
// trigger normal crawl from walk/run
if (current == PlayerState::Walk || current == PlayerState::Run)
player_state.start_crawl(PlayerState::Crawl1);
}
need_redraw = true;
}

View File

@@ -27,12 +27,20 @@ void draw_character(int x, int y, MovementType movement, int frame_index) {
character_height = CHARACTER_RUN_FRAME_HEIGHT;
break;
case MovementType::Crawl:
total_frames = CHARACTER_CRAWL_FRAME_COUNT;
case MovementType::Crawl1:
total_frames = CHARACTER_CRAWL1_FRAME_COUNT;
if (frame_index < 0 || frame_index >= total_frames)
frame_index = 0;
character = CHARACTER_CRAWL_FRAMES[frame_index];
character_height = CHARACTER_CRAWL_FRAME_HEIGHT;
character = CHARACTER_CRAWL1_FRAMES[frame_index];
character_height = CHARACTER_CRAWL1_FRAME_HEIGHT;
break;
case MovementType::Crawl2:
total_frames = CHARACTER_CRAWL2_FRAME_COUNT;
if (frame_index < 0 || frame_index >= total_frames)
frame_index = 0;
character = CHARACTER_CRAWL2_FRAMES[frame_index];
character_height = CHARACTER_CRAWL2_FRAME_HEIGHT;
break;
}

View File

@@ -4,7 +4,8 @@
enum class MovementType {
Walk,
Run,
Crawl
Crawl1,
Crawl2
};
// Draw the player object starting at given (x, y)

View File

@@ -18,8 +18,11 @@ CharacterPosition get_aligned_frame_position(CharacterPosition base,
case MovementType::Run:
character_height = CHARACTER_RUN_FRAME_HEIGHT;
break;
case MovementType::Crawl:
character_height = CHARACTER_CRAWL_FRAME_HEIGHT;
case MovementType::Crawl1:
character_height = CHARACTER_CRAWL1_FRAME_HEIGHT;
break;
case MovementType::Crawl2:
character_height = CHARACTER_CRAWL2_FRAME_HEIGHT;
break;
}