2020-08-20 17:04:31 +02:00
|
|
|
#include <gint/display.h>
|
|
|
|
#include <gint/keyboard.h>
|
|
|
|
#include "engine.h"
|
|
|
|
|
|
|
|
#define CELL_X(x) (-2 + 10 * (x))
|
|
|
|
#define CELL_Y(y) (-3 + 10 * (y))
|
|
|
|
|
2020-08-21 11:15:33 +02:00
|
|
|
//---
|
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-20 17:04:31 +02:00
|
|
|
//---
|
|
|
|
// Rendering
|
|
|
|
//---
|
|
|
|
|
|
|
|
static void engine_draw_player(struct player const *player)
|
|
|
|
{
|
2020-08-21 11:15:33 +02:00
|
|
|
dframe(CELL_X(player->x) - 1 + player->anim.dx,
|
|
|
|
CELL_Y(player->y) - 5 + player->anim.dy,
|
|
|
|
player->anim.img);
|
2020-08-20 17:04:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void engine_draw(struct game const *game)
|
|
|
|
{
|
|
|
|
dclear(C_WHITE);
|
2020-12-22 17:01:59 +01:00
|
|
|
dimage(0, 0, game->map->img);
|
2020-08-20 17:04:31 +02:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2020-12-22 17:01:59 +01:00
|
|
|
int tile = map->tiles[y * map->w + x];
|
|
|
|
return (tile != TILE_WALL);
|
2020-08-20 17:04:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2020-08-21 11:15:33 +02:00
|
|
|
int olddir = player->dir;
|
2020-08-20 17:04:31 +02:00
|
|
|
|
2020-08-21 11:15:33 +02:00
|
|
|
/* Don't move players that are already moving */
|
|
|
|
if(!player->idle) return 0;
|
|
|
|
|
|
|
|
/* Update the direction */
|
2020-08-20 17:04:31 +02:00
|
|
|
player->dir = dir;
|
2020-08-21 11:15:33 +02:00
|
|
|
player->anim.dir = dir;
|
2020-08-20 17:04:31 +02:00
|
|
|
|
|
|
|
/* Only move the player if the destination is walkable */
|
2020-08-21 11:15:33 +02:00
|
|
|
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;
|
|
|
|
}
|
2020-08-20 17:04:31 +02:00
|
|
|
|
|
|
|
player->x += dx;
|
|
|
|
player->y += dy;
|
|
|
|
|
2020-08-21 11:15:33 +02:00
|
|
|
/* Set the walking animation */
|
|
|
|
player->idle = !anim_player_walking(&player->anim, 1);
|
|
|
|
|
2020-08-20 17:04:31 +02:00
|
|
|
return 1;
|
|
|
|
}
|