QUOTE: Be the change, make a difference.

fix: Fixed wall entity target detection bug - freezo - A retro platform game

freezo

A retro platform game
git clone git@soophie.de:/srv/git/freezo
log | files | refs | readme

commit c828b946ebb446d3a90149f694b10163d247f68f
parent a5d21e2269385d64870f1cc35c3458ce5c257ad0
Author: Sophie <info@soophie.de>
Date:   Tue, 17 Dec 2024 14:01:48 +0100

fix: Fixed wall entity target detection bug

Diffstat:
Minclude/entity.h | 2++
Msrc/entity.c | 20++++++++++++++++++++
Msrc/player.c | 32+++++++++++++++-----------------
3 files changed, 37 insertions(+), 17 deletions(-)

diff --git a/include/entity.h b/include/entity.h @@ -31,3 +31,5 @@ void entity_update(entity_t *entity, game_t *game); void entity_draw(entity_t *entity, game_t *game); void entity_detach(entity_t *entity); void entity_free(entity_t *entity); + +rect_t entity_get_rect(entity_t *entity); diff --git a/src/entity.c b/src/entity.c @@ -4,6 +4,7 @@ #include "../include/enemy.h" #include "../include/gate.h" #include "../include/door.h" +#include "../include/const.h" entity_t *entity_create(entity_e type) { entity_t *entity = malloc(sizeof(entity_t)); @@ -79,3 +80,22 @@ void entity_detach(entity_t *entity) { void entity_free(entity_t *entity) { free(entity); } + +rect_t entity_get_rect(entity_t *entity) { + rect_t rect; + switch (entity->type) { + case ENTITY_ENEMY: + rect = rect_from_pos(entity->enemy->pos, ENEMY_WIDTH, ENEMY_HEIGHT); + break; + case ENTITY_GATE: + rect = rect_from_pos((pos_t) { entity->gate->pos.x, entity->gate->pos.y - TILE_HEIGHT }, ENEMY_WIDTH, ENEMY_HEIGHT); + break; + case ENTITY_DOOR: + rect = rect_from_pos((pos_t) { entity->door->pos.x, entity->door->pos.y - TILE_HEIGHT }, ENEMY_WIDTH, ENEMY_HEIGHT); + break; + case ENTITY_BOSS: + rect = rect_from_pos((pos_t) { entity->boss->pos.x, entity->boss->pos.y - TILE_HEIGHT }, 2 * ENEMY_WIDTH, ENEMY_HEIGHT); + break; + } + return rect; +} diff --git a/src/player.c b/src/player.c @@ -252,21 +252,7 @@ void player_update(player_t *player, game_t *game) { if (!entity->is_bad) { continue; } - rect_t entity_rect; - switch (entity->type) { - case ENTITY_ENEMY: - entity_rect = rect_from_pos(entity->enemy->pos, ENEMY_WIDTH, ENEMY_HEIGHT); - break; - case ENTITY_GATE: - entity_rect = rect_from_pos((pos_t) { entity->gate->pos.x, entity->gate->pos.y - TILE_HEIGHT }, ENEMY_WIDTH, ENEMY_HEIGHT); - break; - case ENTITY_DOOR: - entity_rect = rect_from_pos((pos_t) { entity->gate->pos.x, entity->gate->pos.y - TILE_HEIGHT }, ENEMY_WIDTH, ENEMY_HEIGHT); - break; - case ENTITY_BOSS: - entity_rect = rect_from_pos((pos_t) { entity->gate->pos.x, entity->gate->pos.y - TILE_HEIGHT }, 2 * ENEMY_WIDTH, ENEMY_HEIGHT); - break; - } + rect_t entity_rect = entity_get_rect(entity); if (rect_collide(shooting_rect, entity_rect)) { float entity_x = entity_rect.x + entity_rect.width / 2.0; float entity_distance = fabs(entity_x - (player->dir > 0 ? player->pos.x + PLAYER_WIDTH : player->pos.x)); @@ -300,11 +286,23 @@ void player_update(player_t *player, game_t *game) { if (rect_collide(shooting_rect, tile_rect)) { if (player->dir > 0) { player->shooting_distance = tile->pos.x - (player->pos.x + PLAYER_WIDTH); - player->target_entity = NULL; + // clear target if it stands behind a wall + if (player->target_entity != NULL) { + rect_t rect = entity_get_rect(player->target_entity); + if (rect.x > tile->pos.x) { + player->target_entity = NULL; + } + } } else { player->shooting_distance = player->pos.x - (tile->pos.x + TILE_WIDTH); - player->target_entity = NULL; + // clear target if it stands behind a wall + if (player->target_entity != NULL) { + rect_t rect = entity_get_rect(player->target_entity); + if (rect.x + rect.width < tile->pos.x + TILE_WIDTH) { + player->target_entity = NULL; + } + } } } }