Collisions are finally completely working

Fixed collisions, only items in the hard tiles array are missing, but they can be easily filled with Fcalva's list.
This commit is contained in:
mibi88 2023-07-09 16:17:33 +02:00
commit 7913b336b7
3 changed files with 48 additions and 17 deletions

View file

@ -78,8 +78,8 @@ void render_map(Player *player, Map *map_level) {
ytile = (tile / map_level->tileset_size) * T_HEIGHT; ytile = (tile / map_level->tileset_size) * T_HEIGHT;
/* render */ /* render */
dsubimage(x*T_WIDTH-mx, y*T_HEIGHT-my, dsubimage(x*T_WIDTH-mx, y*T_HEIGHT-my,
map_level->tileset, xtile, ytile, T_WIDTH, T_HEIGHT, map_level->tileset, xtile, ytile, T_WIDTH,
DIMAGE_NONE); T_HEIGHT, DIMAGE_NONE);
} }
} }
} }

View file

@ -43,12 +43,22 @@ void player_move(Map *map_level, Player *player, Direction direction) {
/* How this player movement will modify the player x and y. */ /* How this player movement will modify the player x and y. */
const char dx = one_px_mov[direction*2]*SPEED; const char dx = one_px_mov[direction*2]*SPEED;
const char dy = one_px_mov[direction*2+1]*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
if(player_collision(map_level, player, direction)){ * the map. */
/* I fix his position so he won't be partially in the tile. */ if(player_collision(map_level, player, direction, P_CENTER)){
player_fix_position(player, 1, 1); /* If the will collide with the center of the player. */
player_fix_position(player, dx, dy);
}else{ }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->x += dx;
player->y += dy; player->y += dy;
} }
@ -58,19 +68,32 @@ 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. */ /* What's the tile the player is going to. */
short int i; short int i;
/* Where is the tile where he will go to from his position. */ /* Where is the tile where he will go to from his position. */
const char dx = one_px_mov[direction*2]; char dx = one_px_mov[direction*2];
const char dy = one_px_mov[direction*2+1]; char dy = one_px_mov[direction*2+1];
if(!dx){
dx += nomov_axis_check;
}else if(!dy){
dy += nomov_axis_check;
}
dx = dx*(P_WIDTH/2+1);
dy = dy*(P_HEIGHT/2+1);
/* The tile he will go to. */ /* The tile he will go to. */
int player_tile_x = player->x/T_WIDTH; int player_tile_x = player->x+dx;
int player_tile_y = player->y/T_HEIGHT; 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;i<map_level->nblayers;i++){ for(i=0;i<map_level->nblayers;i++){
/* if he's on a hard tile */ /* if he's on a hard tile */
if(is_in((short int*)hard_tiles, HARD_TILES_AMOUNT, 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. */ return true; /* He will collide with it. */
} }
} }

View file

@ -14,10 +14,16 @@ typedef enum {
D_RIGHT D_RIGHT
} Direction; } Direction;
typedef enum {
P_LEFTUP = -1,
P_CENTER = 0,
P_RIGHTDOWN = 1
} Checkpos;
/* Struct that define player parameters */ /* Struct that define player parameters */
typedef struct { typedef struct {
unsigned int x, y; /* The position of the player */ int x, y; /* The position of the player */
unsigned int px, py; /* The position of the player on screen */ unsigned char px, py; /* The position of the player on screen */
unsigned short int life; /* How many lives the player still has between 0 unsigned short int life; /* How many lives the player still has between 0
* and 100. */ * and 100. */
} Player; } Player;
@ -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! */ /* (Mibi88) TODO: Describe this function please, I've no idea what she's for! */
void player_action(Player *player); void player_action(Player *player);
/* Check if the player is in collision with the map or a NPC. */ /* Check if the player is in collision with the map or a NPC. Checkpos is used
bool player_collision(Map *map_level, Player *player, Direction direction); * 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 /* Fix the position of the player so that he's not a bit inside of a hard block
* after a collision. */ * after a collision. */