mystnb/src/engine.c

94 lines
1.9 KiB
C
Raw Normal View History

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;
}