Beginning of animation based on lephe's tutorial

This commit is contained in:
bgiraudr 2021-07-31 18:44:06 +02:00
parent 2b7281a40d
commit 484d83df19
7 changed files with 111 additions and 5 deletions

View File

@ -23,6 +23,7 @@ set(SOURCES
src/main.c
src/game.c
src/engine.c
src/animation.c
)
set(ASSETS_cg

27
include/animation.h Normal file
View File

@ -0,0 +1,27 @@
#pragma once
#include <gint/display.h>
struct anim_data;
typedef int (anim_function_t)(struct anim_data *data, int init);
anim_function_t anim_player_idle;
struct anim_frame
{
bopti_image_t *source;
int left, top;
int w, h;
};
struct anim_data
{
anim_function_t *function;
struct anim_frame img;
int dx, dy;
int dir;
int frame;
int duration;
};
void dframe(int x, int y, struct anim_frame const frame);
int anim_player_idle(struct anim_data *data, int init);

View File

@ -10,4 +10,5 @@ struct game {
void engine_draw(struct game const *game);
void engine_draw_player(struct player const *player);
void engine_move(struct game *game, int direction);
int map_walkable(struct map const *map, int x, int y);
int map_walkable(struct map const *map, int x, int y);
void engine_tick(struct game *game, int dt);

View File

@ -1,10 +1,13 @@
#pragma once
#include "animation.h"
struct player {
int x, y;
int direction;
int frame;
//struct animation const *anim;
int idle;
struct anim_data anim;
};
enum direction {

56
src/animation.c Normal file
View File

@ -0,0 +1,56 @@
#include <gint/display.h>
#include <gint/defs/util.h>
#include "animation.h"
#include "engine.h"
struct sheet
{
bopti_image_t *img;
int frame_w;
int frame_h;
};
extern bopti_image_t img_spritesheet;
struct sheet const anim_player = {
.img = &img_spritesheet,
.frame_w = 16,
.frame_h = 21,
};
static struct anim_frame anim_frame(struct sheet const *sheet, int col, int row)
{
struct anim_frame f = {
.source = sheet->img,
.left = sheet->frame_w * col,
.top = sheet->frame_h * row,
.w = sheet->frame_w,
.h = sheet->frame_h,
};
return f;
}
void dframe(int x, int y, struct anim_frame const frame)
{
dsubimage(x, y, frame.source, frame.left, frame.top, frame.w, frame.h,
DIMAGE_NONE);
}
int anim_player_idle(struct anim_data *data, int init)
{
if(init)
{
data->function = anim_player_idle;
data->frame = 0;
data->duration = 100;
}
else
{
data->frame = (data->frame + 1) % 2;
data->duration += 100;
}
data->img = anim_frame(&anim_player, data->dir, data->frame);
data->dx = 0;
data->dy = 0;
return 0;
}

View File

@ -4,6 +4,7 @@
#include "game.h"
#include "map.h"
#include "player.h"
#include "animation.h"
#define TILESET_WIDTH 29
#define HEIGHT_VISIBLE 14
@ -109,8 +110,7 @@ void engine_draw(struct game const *game) {
}
void engine_draw_player(struct player const *player) {
extern bopti_image_t img_spritesheet;
dsubimage(12 * 16, 7 * 16 - 5, &img_spritesheet, player->direction * 16, 0, 16, 21, DIMAGE_NONE);
dframe(12 * 16, 7 * 16 - 5, player->anim.img);
dprint(1,1,C_BLACK,"%d:%d",player->x, player->y);
}
@ -122,9 +122,22 @@ void engine_move(struct game *game, int direction) {
if(map_walkable(game->map, game->player->x + dx, game->player->y + dy)) {
game->player->x += dx;
game->player->y += dy;
} else {
game->player->idle = !anim_player_idle(&game->player->anim, 1);
}
} else {
game->player->direction = direction;
game->player->anim.dir = direction;
}
}
void engine_tick(struct game *game, int dt)
{
game->player->anim.duration -= dt;
/* Call the animation function to generate the next frame */
if(game->player->anim.duration <= 0) {
game->player->idle = !game->player->anim.function(&game->player->anim, 0);
}
}

View File

@ -4,6 +4,7 @@
#include "map.h"
#include "engine.h"
#include "player.h"
#include "animation.h"
#include <gint/timer.h>
#include <gint/clock.h>
@ -24,8 +25,11 @@ void play() {
struct player player = {
.x = 16,
.y = 7,
.direction = 0
.direction = DIR_DOWN,
.anim.function = anim_player_idle,
.anim.dir = DIR_DOWN
};
player.idle = !anim_player_idle(&player.anim, 1);
struct game game = {
.map = maps[0],
@ -48,6 +52,7 @@ void play() {
int dir = get_inputs();
if(dir >= 0)
engine_move(&game, dir);
engine_tick(&game, ENGINE_TICK);
}
if(t >= 0) timer_stop(t);
}