From 909e0760c51f5fb30e5f1b23dc112238577f585b Mon Sep 17 00:00:00 2001 From: mibi88 <76903855+mibi88@users.noreply.github.com> Date: Sun, 9 Jul 2023 13:22:20 +0200 Subject: [PATCH 1/3] Collisions are not sticky anymore and the player can't go trough the blocks but he is shaking when you collide with a wall and is not stopped by the borders of the map. --- src/player.c | 30 +++++++++++++++++++++--------- src/player.h | 14 +++++++++++--- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/player.c b/src/player.c index 6d0627d..fcaba7b 100644 --- a/src/player.c +++ b/src/player.c @@ -44,11 +44,15 @@ void player_move(Map *map_level, Player *player, Direction direction) { const char dx = one_px_mov[direction*2]*SPEED; const char dy = one_px_mov[direction*2+1]*SPEED; /* If the player will collide with a hard tile. */ - if(player_collision(map_level, player, direction)){ - /* I fix his position so he won't be partially in the tile. */ - player_fix_position(player, 1, 1); + if(player_collision(map_level, player, direction, P_CENTER)){ + player_fix_position(player, dx, dy); }else{ /* If he won't collide I just move him normally */ + if(player_collision(map_level, player, direction, P_RIGHTDOWN) || + player_collision(map_level, player, direction, P_LEFTUP)){ + /* I fix his position so he won't be partially in the tile. */ + player_fix_position(player, dx==0, dy==0); + } player->x += dx; player->y += dy; } @@ -58,19 +62,27 @@ void player_action(Player *player) { /**/ } -bool player_collision(Map *map_level, Player *player, Direction direction) { +bool player_collision(Map *map_level, Player *player, Direction direction, + Checkpos nomov_axis_check) { /* What's the tile the player is going to. */ short int i; /* Where is the tile where he will go to from his position. */ - const char dx = one_px_mov[direction*2]; - const char dy = one_px_mov[direction*2+1]; + char dx = one_px_mov[direction*2]; + char dy = one_px_mov[direction*2+1]; + if(!dx){ + dx += nomov_axis_check; + dx = dx*(P_WIDTH/2+(nomov_axis_check == P_CENTER)); + }else if(!dy){ + dy += nomov_axis_check; + dy = dy*(P_HEIGHT/2+(nomov_axis_check == P_CENTER)); + } /* The tile he will go to. */ - int player_tile_x = player->x/T_WIDTH; - int player_tile_y = player->y/T_HEIGHT; + int player_tile_x = (player->x+dx)/T_WIDTH; + int player_tile_y = (player->y+dy)/T_HEIGHT; for(i=0;inblayers;i++){ /* if he's on a hard tile */ if(is_in((short int*)hard_tiles, HARD_TILES_AMOUNT, - get_tile(map_level, player_tile_x+dx, player_tile_y+dy, i))){ + get_tile(map_level, player_tile_x, player_tile_y, i))){ return true; /* He will collide with it. */ } } diff --git a/src/player.h b/src/player.h index e4771a2..51cc4c0 100644 --- a/src/player.h +++ b/src/player.h @@ -14,9 +14,15 @@ typedef enum { D_RIGHT } Direction; +typedef enum { + P_LEFTUP = -1, + P_CENTER = 0, + P_RIGHTDOWN = 1 +} Checkpos; + /* Struct that define player parameters */ typedef struct { - unsigned short int x, y; /* The position of the player */ + int x, y; /* The position of the player */ unsigned char px, py; /* The position of the player on screen */ unsigned short int life; /* How many lives the player still has between 0 * and 100. */ @@ -32,8 +38,10 @@ void player_move(Map *map_level, Player *player, Direction direction); /* (Mibi88) TODO: Describe this function please, I've no idea what she's for! */ void player_action(Player *player); -/* Check if the player is in collision with the map or a NPC. */ -bool player_collision(Map *map_level, Player *player, Direction direction); +/* Check if the player is in collision with the map or a NPC. Checkpos is used + * to check the axis where the player is not moving. */ +bool player_collision(Map *map_level, Player *player, Direction direction, + Checkpos nomov_axis_check); /* Fix the position of the player so that he's not a bit inside of a hard block * after a collision. */ From 6afde39af89417294df6215158b786f0d6fb3a6b Mon Sep 17 00:00:00 2001 From: mibi88 <76903855+mibi88@users.noreply.github.com> Date: Sun, 9 Jul 2023 13:37:49 +0200 Subject: [PATCH 2/3] \o/ The collisions are working PERFECTLY now except on the borders of the map! \o/ --- src/player.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/player.c b/src/player.c index fcaba7b..bc2efcc 100644 --- a/src/player.c +++ b/src/player.c @@ -45,14 +45,19 @@ void player_move(Map *map_level, Player *player, Direction direction) { const char dy = one_px_mov[direction*2+1]*SPEED; /* If the player will collide with a hard tile. */ if(player_collision(map_level, player, direction, P_CENTER)){ + /* If the will collide with the center of the player. */ player_fix_position(player, dx, dy); }else{ - /* If he won't collide I just move him normally */ if(player_collision(map_level, player, direction, P_RIGHTDOWN) || player_collision(map_level, player, direction, P_LEFTUP)){ + /* If the will collide with the edges of the player. */ /* I fix his position so he won't be partially in the tile. */ + /* I invert dx and dy to fix the axis where he is not moving on. */ + /* Do not replace dx==0 with !dx or dy==0 with !dy, it won't work! + */ player_fix_position(player, dx==0, dy==0); } + /* If he won't collide with the center, so I just move him normally */ player->x += dx; player->y += dy; } @@ -71,11 +76,11 @@ bool player_collision(Map *map_level, Player *player, Direction direction, char dy = one_px_mov[direction*2+1]; if(!dx){ dx += nomov_axis_check; - dx = dx*(P_WIDTH/2+(nomov_axis_check == P_CENTER)); }else if(!dy){ dy += nomov_axis_check; - dy = dy*(P_HEIGHT/2+(nomov_axis_check == P_CENTER)); } + dx = dx*(P_WIDTH/2+(nomov_axis_check == P_CENTER)); + dy = dy*(P_HEIGHT/2+(nomov_axis_check == P_CENTER)); /* The tile he will go to. */ int player_tile_x = (player->x+dx)/T_WIDTH; int player_tile_y = (player->y+dy)/T_HEIGHT; From 86430b853a3fce52b56fa105b0c075078a4f2143 Mon Sep 17 00:00:00 2001 From: mibi88 <76903855+mibi88@users.noreply.github.com> Date: Sun, 9 Jul 2023 15:45:46 +0200 Subject: [PATCH 3/3] Collisions are now completely working, just need to fill the array of all tiles where the player can't go through. --- src/map.c | 4 ++-- src/player.c | 16 +++++++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/map.c b/src/map.c index 0e86663..bae29d9 100644 --- a/src/map.c +++ b/src/map.c @@ -78,8 +78,8 @@ void render_map(Player *player, Map *map_level) { ytile = (tile / map_level->tileset_size) * T_HEIGHT; /* render */ dsubimage(x*T_WIDTH-mx, y*T_HEIGHT-my, - map_level->tileset, xtile, ytile, T_WIDTH, T_HEIGHT, - DIMAGE_NONE); + map_level->tileset, xtile, ytile, T_WIDTH, + T_HEIGHT, DIMAGE_NONE); } } } diff --git a/src/player.c b/src/player.c index bc2efcc..5a9a2e9 100644 --- a/src/player.c +++ b/src/player.c @@ -43,7 +43,8 @@ void player_move(Map *map_level, Player *player, Direction direction) { /* How this player movement will modify the player x and y. */ const char dx = one_px_mov[direction*2]*SPEED; const char dy = one_px_mov[direction*2+1]*SPEED; - /* If the player will collide with a hard tile. */ + /* If the player will collide with a hard tile or if the will go outside of + * the map. */ if(player_collision(map_level, player, direction, P_CENTER)){ /* If the will collide with the center of the player. */ player_fix_position(player, dx, dy); @@ -79,11 +80,16 @@ bool player_collision(Map *map_level, Player *player, Direction direction, }else if(!dy){ dy += nomov_axis_check; } - dx = dx*(P_WIDTH/2+(nomov_axis_check == P_CENTER)); - dy = dy*(P_HEIGHT/2+(nomov_axis_check == P_CENTER)); + dx = dx*(P_WIDTH/2+1); + dy = dy*(P_HEIGHT/2+1); /* The tile he will go to. */ - int player_tile_x = (player->x+dx)/T_WIDTH; - int player_tile_y = (player->y+dy)/T_HEIGHT; + int player_tile_x = player->x+dx; + int player_tile_y = player->y+dy; + /* Handle a negative position diffrently than a positive one. */ + if(player_tile_x < 0) player_tile_x = player_tile_x/T_WIDTH-1; + else player_tile_x = player_tile_x/T_WIDTH; + if(player_tile_y < 0) player_tile_y = player_tile_y/T_HEIGHT-1; + else player_tile_y = player_tile_y/T_HEIGHT; for(i=0;inblayers;i++){ /* if he's on a hard tile */ if(is_in((short int*)hard_tiles, HARD_TILES_AMOUNT,