#include "player.h" #include "map.h" #include "config.h" #include const char one_px_mov[8] = { 0, -1, /* Up */ 0, 1, /* Down */ -1, 0, /* Left */ 1, 0 /* Right */ }; /* TODO: Search for all hard tiles in the tileset. hard_tiles is a list of their * IDs */ /* The speed of the player on the diffrent tiles in the walkable layer. */ #define WALKABLE_TILE_MAX 4 const short int walkable_speed[WALKABLE_TILE_MAX] = { SPEED, 0, PXSIZE, PXSIZE }; /* How much damage the player takes on the diffrent tiles in the walkable * layer. */ const char damage_taken_walkable[WALKABLE_TILE_MAX] = { 0, 0, 5, 0 }; extern bopti_image_t demo_player_img; void player_draw(Player *player) { dimage(player->px-P_WIDTH/2, player->py-P_HEIGHT/2, &demo_player_img); } void player_move(Map *map_level, Player *player, Direction direction) { /* How this player movement will modify the player x and y. */ char dx, dy; /* 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. */ dx = one_px_mov[direction*2]*player->speed; dy = one_px_mov[direction*2+1]*player->speed; player_fix_position(player, dx, dy); }else{ 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! */ dx = one_px_mov[direction*2]*player->speed; dy = one_px_mov[direction*2+1]*player->speed; player_fix_position(player, dx==0, dy==0); } /* If he won't collide with the center, so I just move him normally */ dx = one_px_mov[direction*2]*player->speed; dy = one_px_mov[direction*2+1]*player->speed; player->x += dx; player->y += dy; } } void player_action(Player *player) { /**/ } bool player_collision(Map *map_level, Player *player, Direction direction, Checkpos nomov_axis_check) { /* Where is the tile where he will go to from his position. */ char dx = one_px_mov[direction*2]; 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. */ 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; int on_walkable = get_walkable(map_level, player_tile_x, player_tile_y); int speed = on_walkable >= 0 && on_walkable < WALKABLE_TILE_MAX ? walkable_speed[on_walkable] : 0; /* if he's on a hard tile */ if(!speed){ return true; /* He will collide with it. */ } player->speed = speed; return false; /* He won't collide with a hard tile. */ } void player_fix_position(Player *player, bool fix_x, bool fix_y) { /* I fix his poition on x or/and on y if y need to, so that he won't be over * the hard tile that he collided with. */ if(fix_x) player->x = player->x/T_WIDTH*T_WIDTH+P_WIDTH/2; if(fix_y) player->y = player->y/T_HEIGHT*T_HEIGHT+P_HEIGHT/2; } void player_damage(Player *player, int amount) { player->life-=amount; /* TODO: Let the player dye if life < 1. */ };