#include #include "player.h" #include "vec.h" #include "conf.h" #include "camera.h" #include "input.h" #include "collide.h" #define SGN(x) ((x > 0) ? (1) : ((x < 0) ? (-1) : (0))) void player_move(Player *player, const Level *level) { /* Try to move the player to a destination, and stop their * momentum if they hit a wall. The player can move if they're * stuck in a block, to avoid softlock in some situations. If * the destination is solid and they aren't in a block, then we * use the costy player_move function to snap them and reset * their speed accordingly. */ Vec destination; vec_cpy(&destination, player->pos); vec_add(&destination, player->spd); if (collide_full(player, player->pos, level, level->solid_layer) || !collide_full(player, destination, level, level->solid_layer)) { vec_cpy(&player->pos, destination); } else { /* TODO * Player can't move to destination, snap them. First * move on x axis, then y axis. */ uint i = 0; } } void player_step(Player *player, Input *input, const Level *level) { Vec move = { (input_is_down(input, K_RIGHT) - input_is_down(input, K_LEFT)), (input_is_down(input, K_DOWN) - input_is_down(input, K_UP)) }; vec_mul(&move, 32 * PXS); /* calculate speed */ vec_cpy(&player->spd, move); player_move(player, level); } void player_draw(Player *player, Camera *camera) { Vec tl; /* top left */ Vec br; /* bottom right */ /* The rest of this function calculates the player on screen * position and draw it. */ vec_cpy(&tl, player->pos); vec_sub(&tl, player->origin); vec_cpy(&br, tl); vec_div(&tl, VEC_PRECISION); vec_div(&br, VEC_PRECISION); vec_add(&br, player->vbox); vec_sub(&tl, camera->offset); vec_sub(&br, camera->offset); vec_mul(&tl, SCALE); vec_mul(&br, SCALE); vec_add(&br, (Vec){SCALE - 1, SCALE - 1}); /* draw code here */ vec_drect(tl, br, C_BLACK); } void player_draw_debug(Player *player, uint step, const Level *level, uint layer_id) { /* This debug function displays more or less usefull * informations for debugging player movement. */ dprint(0, 0, C_BLACK, "x: %d", player->pos.x); dprint(0, 10, C_BLACK, "y: %d", player->pos.y); dprint(0, 20, C_BLACK, "vp: %d", VEC_PRECISION); dprint(0, 30, C_BLACK, "st: %u", step); dprint(0, 40, C_BLACK, "cx: %d", player->pos.x / TILE_SIZE); dprint(0, 50, C_BLACK, "cy: %d", player->pos.y / TILE_SIZE); dprint(0, 60, C_BLACK, "cl: %d", collide_point(player->pos, level, layer_id)); }