aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2023-05-04 10:15:19 +1000
committerquou <quou@disroot.org>2023-05-04 10:15:19 +1000
commitc4ac81cffcf925963acb0c02584ab22626427a73 (patch)
tree7d6421405e53a92baada909355c5398f21e91864
parentc4ee81da673208fe7b3e3638692fd466acf61c3f (diff)
Add an animation system.
-rw-r--r--Makefile2
-rw-r--r--animation.c50
-rw-r--r--animation.h22
-rw-r--r--animation_system.c33
-rw-r--r--components.h11
-rw-r--r--config.h2
-rw-r--r--game_config.h6
-rw-r--r--main.c1
-rw-r--r--player.c52
-rw-r--r--player.h1
-rw-r--r--systems.h1
-rw-r--r--world.h3
12 files changed, 177 insertions, 7 deletions
diff --git a/Makefile b/Makefile
index 5bc01bf..d9c53b0 100644
--- a/Makefile
+++ b/Makefile
@@ -85,6 +85,8 @@ endif
all: $(target)
sources = \
+ animation.c \
+ animation_system.c \
asset.c \
main.c \
malware.c \
diff --git a/animation.c b/animation.c
new file mode 100644
index 0000000..6dbb08f
--- /dev/null
+++ b/animation.c
@@ -0,0 +1,50 @@
+#include "animation.h"
+
+static const Animation animations[] = {
+ /* animation_player_walk_left */
+ {
+ {
+ { 0, 16, 16, 16 },
+ { 16, 16, 16, 16 },
+ { 16, 16, 16, 16 },
+ { 0, 16, 16, 16 },
+ { 32, 16, 16, 16 },
+ { 32, 16, 16, 16 }
+ },
+ 6,
+ 3
+ },
+ /* animation_player_walk_right */
+ {
+ {
+ { 0, 0, 16, 16 },
+ { 16, 0, 16, 16 },
+ { 16, 0, 16, 16 },
+ { 0, 0, 16, 16 },
+ { 32, 0, 16, 16 },
+ { 32, 0, 16, 16 }
+ },
+ 6,
+ 3
+ },
+ /* animation_player_idle_left */
+ {
+ {
+ { 0, 16, 16, 16 },
+ },
+ 1,
+ 1
+ },
+ /* animation__player_idle_right */
+ {
+ {
+ { 0, 0, 16, 16 },
+ },
+ 1,
+ 1
+ },
+};
+
+const Animation* get_animation(Animation_ID id) {
+ return &animations[id];
+}
diff --git a/animation.h b/animation.h
new file mode 100644
index 0000000..e9e1399
--- /dev/null
+++ b/animation.h
@@ -0,0 +1,22 @@
+#ifndef animation_h
+#define animation_h
+
+#include "config.h"
+#include "rect.h"
+
+typedef enum {
+ animation_player_walk_left = 0,
+ animation_player_walk_right,
+ animation_player_idle_left,
+ animation_player_idle_right
+} Animation_ID;
+
+typedef struct {
+ Rectangle frames[animation_max_frames];
+ int frame_count;
+ int slowness;
+} Animation;
+
+const Animation* get_animation(Animation_ID id);
+
+#endif
diff --git a/animation_system.c b/animation_system.c
new file mode 100644
index 0000000..22317ac
--- /dev/null
+++ b/animation_system.c
@@ -0,0 +1,33 @@
+#include "animation.h"
+#include "components.h"
+#include "world.h"
+
+void animation_system(World* world) {
+ int i;
+ unsigned bits;
+ CSprite* sprite;
+ CAnimated* animated;
+ const Animation* animation;
+
+ for (i = 0; i < world->entity_count; i++) {
+ bits = world->bitmask[i];
+ if ((bits & ctype_sprite) && (bits & ctype_animated)) {
+ sprite = &world->sprites[i];
+ animated = &world->animateds[i];
+ animation = get_animation(animated->id);
+
+ animated->timer++;
+ if (animated->timer > animation->slowness) {
+ animated->frame++;
+ animated->timer = 0;
+ }
+
+ if (animated->frame >= animation->frame_count) {
+ animated->frame = 0;
+ animated->timer = 0;
+ }
+
+ sprite->rect = animation->frames[animated->frame];
+ }
+ }
+}
diff --git a/components.h b/components.h
index cdd7c46..84cfc54 100644
--- a/components.h
+++ b/components.h
@@ -1,6 +1,7 @@
#ifndef components_h
#define components_h
+#include "animation.h"
#include "asset.h"
#include "rect.h"
@@ -13,9 +14,17 @@ typedef struct {
Rectangle rect;
} CSprite;
+typedef struct {
+ Animation_ID id;
+
+ int frame;
+ int timer;
+} CAnimated;
+
typedef enum {
ctype_sprite = 1 << 0,
- ctype_position = 1 << 1
+ ctype_position = 1 << 1,
+ ctype_animated = 1 << 2
} CType;
#endif
diff --git a/config.h b/config.h
index 91363a9..273f9a5 100644
--- a/config.h
+++ b/config.h
@@ -15,4 +15,6 @@
/* 16 KB should be enough. */
#define asset_memory (1024 * 1024 * 16)
+#define animation_max_frames 8
+
#endif
diff --git a/game_config.h b/game_config.h
new file mode 100644
index 0000000..c4efee7
--- /dev/null
+++ b/game_config.h
@@ -0,0 +1,6 @@
+#ifndef game_config_h
+#define game_config_h
+
+#define player_move_speed (3 << fbits)
+
+#endif
diff --git a/main.c b/main.c
index b106978..7cfaf83 100644
--- a/main.c
+++ b/main.c
@@ -22,6 +22,7 @@ void on_init(int argc, char** argv) {
void on_update() {
renderer_begin_frame();
update_player(&world.player, &world);
+ animation_system(&world);
sprite_system(&world);
}
diff --git a/player.c b/player.c
index e5a0853..801dc33 100644
--- a/player.c
+++ b/player.c
@@ -1,4 +1,6 @@
+#include "animation.h"
#include "components.h"
+#include "game_config.h"
#include "input.h"
#include "player.h"
#include "standard.h"
@@ -7,28 +9,45 @@
void init_player(Player* player, World* world) {
CSprite* sprite;
CPosition* pos;
+ CAnimated* animated;
Entity e;
e = new_entity(world);
player->entity = e;
- add_components(world, e, ctype_sprite | ctype_position);
+ add_components(
+ world,
+ e,
+ ctype_sprite |
+ ctype_position |
+ ctype_animated
+ );
+ pos = &world->positions[e];
sprite = &world->sprites[e];
+ animated = &world->animateds[e];
- pos = &world->positions[e];
pos->x = 32;
pos->y = 70;
sprite->id = asset_id_char;
sprite->rect = make_rect(0, 16, 16, 16);
+
+ animated->id = animation_player_walk_left;
+ animated->frame = 0;
+ animated->timer = 0;
+
+ player->face = 0;
}
void update_player(Player* player, World* world) {
int dx, dy;
+ int face, moving = 0;
Entity e;
CPosition* pos;
+ CAnimated* animated;
e = player->entity;
pos = &world->positions[e];
+ animated = &world->animateds[e];
dx = dy = 0;
if (button_pressed(btn_dpad_left)) {
@@ -47,10 +66,33 @@ void update_player(Player* player, World* world) {
dy += 1 << fbits;
}
- if (dx != 0 || dy != 0) {
+ if (dx || dy) {
vec_nrmise(&dx, &dy);
- pos->x += dx;
- pos->y += dy;
+ if (dx) {
+ face = dx < 0 ? 0 : 1;
+ } else {
+ face = player->face;
+ }
+
+ pos->x += (dx * player_move_speed) >> fbits;
+ pos->y += (dy * player_move_speed) >> fbits;
+
+ moving = 1;
+ }
+
+ if (!moving) {
+ animated->frame = 0;
+ animated->id =
+ player->face ?
+ animation_player_idle_right :
+ animation_player_idle_left;
+ } else {
+ player->face = face;
+
+ animated->id =
+ player->face ?
+ animation_player_walk_right :
+ animation_player_walk_left;
}
}
diff --git a/player.h b/player.h
index 37a7f2a..8412bde 100644
--- a/player.h
+++ b/player.h
@@ -5,6 +5,7 @@ struct World;
typedef struct {
int entity;
+ int face;
} Player;
void init_player(Player* player, struct World* world);
diff --git a/systems.h b/systems.h
index 15abce1..24bc9c2 100644
--- a/systems.h
+++ b/systems.h
@@ -3,6 +3,7 @@
#include "world.h"
+void animation_system(World* world);
void sprite_system(const World* world);
#endif
diff --git a/world.h b/world.h
index 7dbcb4d..9871e9b 100644
--- a/world.h
+++ b/world.h
@@ -15,8 +15,9 @@ struct World {
unsigned char bitmask[max_entities];
- CSprite sprites[max_entities];
+ CSprite sprites [max_entities];
CPosition positions[max_entities];
+ CAnimated animateds[max_entities];
Player player;
};