so://phie

freezo

A retro platform game
git clone git://soophie.de/freezo

fix: Fixed wall entity target detection bug


commit: c828b946ebb446d3a90149f694b10163d247f68f
parent: a5d21e2269385d64870f1cc35c3458ce5c257ad0
author: Sophie <info@soophie.de>
time: 2024-12-17 14:01

diff --git a/include/entity.h b/include/entity.h

index 41a34bb..0ff5b97 100644

--- a/include/entity.h

+++ b/include/entity.h

1@@ -31,3 +31,5 @@ void entity_update(entity_t *entity, game_t *game);

2 void entity_draw(entity_t *entity, game_t *game);

3 void entity_detach(entity_t *entity);

4 void entity_free(entity_t *entity);

5+

6+rect_t entity_get_rect(entity_t *entity);

7

8

diff --git a/src/entity.c b/src/entity.c

index 5c7c32f..8d6d434 100644

--- a/src/entity.c

+++ b/src/entity.c

1@@ -4,6 +4,7 @@

2 #include "../include/enemy.h"

3 #include "../include/gate.h"

4 #include "../include/door.h"

5+#include "../include/const.h"

6

7 entity_t *entity_create(entity_e type) {

8 entity_t *entity = malloc(sizeof(entity_t));

9@@ -79,3 +80,22 @@ void entity_detach(entity_t *entity) {

10 void entity_free(entity_t *entity) {

11 free(entity);

12 }

13+

14+rect_t entity_get_rect(entity_t *entity) {

15+ rect_t rect;

16+ switch (entity->type) {

17+ case ENTITY_ENEMY:

18+ rect = rect_from_pos(entity->enemy->pos, ENEMY_WIDTH, ENEMY_HEIGHT);

19+ break;

20+ case ENTITY_GATE:

21+ rect = rect_from_pos((pos_t) { entity->gate->pos.x, entity->gate->pos.y - TILE_HEIGHT }, ENEMY_WIDTH, ENEMY_HEIGHT);

22+ break;

23+ case ENTITY_DOOR:

24+ rect = rect_from_pos((pos_t) { entity->door->pos.x, entity->door->pos.y - TILE_HEIGHT }, ENEMY_WIDTH, ENEMY_HEIGHT);

25+ break;

26+ case ENTITY_BOSS:

27+ rect = rect_from_pos((pos_t) { entity->boss->pos.x, entity->boss->pos.y - TILE_HEIGHT }, 2 * ENEMY_WIDTH, ENEMY_HEIGHT);

28+ break;

29+ }

30+ return rect;

31+}

32

33

diff --git a/src/player.c b/src/player.c

index d24d4f3..224571e 100644

--- a/src/player.c

+++ b/src/player.c

1@@ -252,21 +252,7 @@ void player_update(player_t *player, game_t *game) {

2 if (!entity->is_bad) {

3 continue;

4 }

5- rect_t entity_rect;

6- switch (entity->type) {

7- case ENTITY_ENEMY:

8- entity_rect = rect_from_pos(entity->enemy->pos, ENEMY_WIDTH, ENEMY_HEIGHT);

9- break;

10- case ENTITY_GATE:

11- entity_rect = rect_from_pos((pos_t) { entity->gate->pos.x, entity->gate->pos.y - TILE_HEIGHT }, ENEMY_WIDTH, ENEMY_HEIGHT);

12- break;

13- case ENTITY_DOOR:

14- entity_rect = rect_from_pos((pos_t) { entity->gate->pos.x, entity->gate->pos.y - TILE_HEIGHT }, ENEMY_WIDTH, ENEMY_HEIGHT);

15- break;

16- case ENTITY_BOSS:

17- entity_rect = rect_from_pos((pos_t) { entity->gate->pos.x, entity->gate->pos.y - TILE_HEIGHT }, 2 * ENEMY_WIDTH, ENEMY_HEIGHT);

18- break;

19- }

20+ rect_t entity_rect = entity_get_rect(entity);

21 if (rect_collide(shooting_rect, entity_rect)) {

22 float entity_x = entity_rect.x + entity_rect.width / 2.0;

23 float entity_distance = fabs(entity_x - (player->dir > 0 ? player->pos.x + PLAYER_WIDTH : player->pos.x));

24@@ -300,11 +286,23 @@ void player_update(player_t *player, game_t *game) {

25 if (rect_collide(shooting_rect, tile_rect)) {

26 if (player->dir > 0) {

27 player->shooting_distance = tile->pos.x - (player->pos.x + PLAYER_WIDTH);

28- player->target_entity = NULL;

29+ // clear target if it stands behind a wall

30+ if (player->target_entity != NULL) {

31+ rect_t rect = entity_get_rect(player->target_entity);

32+ if (rect.x > tile->pos.x) {

33+ player->target_entity = NULL;

34+ }

35+ }

36 }

37 else {

38 player->shooting_distance = player->pos.x - (tile->pos.x + TILE_WIDTH);

39- player->target_entity = NULL;

40+ // clear target if it stands behind a wall

41+ if (player->target_entity != NULL) {

42+ rect_t rect = entity_get_rect(player->target_entity);

43+ if (rect.x + rect.width < tile->pos.x + TILE_WIDTH) {

44+ player->target_entity = NULL;

45+ }

46+ }

47 }

48 }

49 }

50

51