#include #include #include "engine.h" #define CELL_X(x) (-2 + 10 * (x)) #define CELL_Y(y) (-3 + 10 * (y)) //--- // Animations //--- void engine_tick(struct game *game, int dt) { game->time += dt; /* Update the animations for every player */ for(int p = 0; game->players[p]; p++) { struct player *player = game->players[p]; player->anim.duration -= dt; if(player->anim.duration > 0) continue; /* Call the animation function to generate the next frame */ player->idle = !player->anim.function(&player->anim, 0); } } //--- // Rendering //--- static void engine_draw_player(struct player const *player) { dframe(CELL_X(player->x) - 1 + player->anim.dx, CELL_Y(player->y) - 5 + player->anim.dy, player->anim.img); } void engine_draw(struct game const *game) { dclear(C_WHITE); dimage(0, 0, game->map->img); for(int p = 0; game->players[p]; p++) { engine_draw_player(game->players[p]); } } //--- // Physics //--- /* Check whether a cell of the map is walkable */ static int map_walkable(struct map const *map, int x, int y) { int tile = map->tiles[y * map->w + x]; return (tile != TILE_WALL); } int engine_move(struct game *game, struct player *player, int dir) { int dx = (dir == DIR_RIGHT) - (dir == DIR_LEFT); int dy = (dir == DIR_DOWN) - (dir == DIR_UP); int olddir = player->dir; /* Don't move players that are already moving */ if(!player->idle) return 0; /* Update the direction */ player->dir = dir; player->anim.dir = dir; /* Only move the player if the destination is walkable */ if(!map_walkable(game->map, player->x + dx, player->y + dy)) { /* If not, set the new idle animation */ if(dir != olddir) { player->idle = !anim_player_idle(&player->anim,1); } return 0; } player->x += dx; player->y += dy; /* Set the walking animation */ player->idle = !anim_player_walking(&player->anim, 1); return 1; }