From b47455c5d2745fdd5b04ba0d1c37358650ca0906 Mon Sep 17 00:00:00 2001 From: enne2 Date: Mon, 22 Jun 2026 19:50:44 +0200 Subject: [PATCH] Fix enemy rendering screen offset and implement pixel-perfect sprite collision --- engine.c | 24 ++++++++++++++++-------- test_movement.py | 4 ++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/engine.c b/engine.c index c2a9b99..1186b80 100644 --- a/engine.c +++ b/engine.c @@ -8,7 +8,7 @@ #include "tiles.h" #include "player.h" -#define MAP_SIZE 15 +#define MAP_SIZE 7 uint8_t maze[MAP_SIZE][MAP_SIZE]; static uint8_t map_buffer[32 * 32]; @@ -386,7 +386,7 @@ void engine_update(uint8_t keys, uint8_t prev_keys) { } } - // Render enemy sprite relative to the scroll viewport + // Render enemy sprite relative to the scroll viewport with centering offset int16_t enemy_px, enemy_py; if (enemy_is_moving) { enemy_px = enemy_start_px + (((enemy_target_px - enemy_start_px) * (int16_t)enemy_move_progress) >> 4); @@ -396,8 +396,9 @@ void engine_update(uint8_t keys, uint8_t prev_keys) { enemy_py = (enemy_lx + enemy_ly) * 8 + 16; } - int16_t enemy_screen_x = enemy_px - scroll_x; - int16_t enemy_screen_y = enemy_py - scroll_y; + // Add player centering offset (+24, +16) to align with player sprite at (88, 88) + int16_t enemy_screen_x = enemy_px - scroll_x + 24; + int16_t enemy_screen_y = enemy_py - scroll_y + 16; // Determine player-enemy distance for visibility masking int8_t edx = (int8_t)player_lx - (int8_t)enemy_lx; @@ -413,10 +414,17 @@ void engine_update(uint8_t keys, uint8_t prev_keys) { move_metasprite(enemy_metasprite, 0, 4, 0, 0); // Hide offscreen } - // Collision detection / Game Over conditions - if ((player_lx == enemy_lx && player_ly == enemy_ly) || - (is_moving && enemy_is_moving && target_lx == enemy_target_lx && target_ly == enemy_target_ly) || - (is_moving && enemy_is_moving && target_lx == enemy_start_lx && target_ly == enemy_start_ly && start_lx == enemy_target_lx && start_ly == enemy_target_ly)) { + // Get current interpolated player coordinates + int16_t p_px = is_moving ? (start_px + (((target_px - start_px) * (int16_t)move_progress) >> 4)) : ((player_lx - player_ly) * 16 + 96); + int16_t p_py = is_moving ? (start_py + (((target_py - start_py) * (int16_t)move_progress) >> 4)) : ((player_lx + player_ly) * 8 + 16); + + // Collision detection: check actual pixel distance (sprites overlap) + int16_t dx_collision = p_px - enemy_px; + int16_t dy_collision = p_py - enemy_py; + if (dx_collision < 0) dx_collision = -dx_collision; + if (dy_collision < 0) dy_collision = -dy_collision; + + if (dx_collision < 12 && dy_collision < 6) { game_over = 1; BGP_REG = 0xFF; // Screen all black return; diff --git a/test_movement.py b/test_movement.py index ae271a9..b172b94 100644 --- a/test_movement.py +++ b/test_movement.py @@ -28,8 +28,8 @@ def main(): ly = pyboy.memory[player_ly_addr] print(f"Initial player coordinates in RAM: lx={lx}, ly={ly}") - # Read maze array from RAM (15x15 starting at maze_addr) - map_size = 15 + # Read maze array from RAM (7x7 starting at maze_addr) + map_size = 7 maze = [] for y in range(map_size): row = []