changeset 580:459ff09c09b3

core: animation can be looped
author David Demelier <markand@malikania.fr>
date Sat, 11 Mar 2023 21:20:33 +0100
parents 0407f746a571
children cedfdbc0e9a7
files examples/example-animation/example-animation.c libmlk-core/mlk/core/animation.c libmlk-core/mlk/core/animation.h libmlk-example/CMakeLists.txt libmlk-example/assets/sprites/cat-running.png libmlk-example/mlk/example/registry.c libmlk-example/mlk/example/registry.h
diffstat 7 files changed, 78 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/examples/example-animation/example-animation.c	Sat Mar 11 11:22:47 2023 +0100
+++ b/examples/example-animation/example-animation.c	Sat Mar 11 21:20:33 2023 +0100
@@ -36,16 +36,21 @@
 #include <mlk/example/registry.h>
 
 static struct mlk_label label = {
-	.text = "Keys: <Space> start or reset the animation.",
+	.text = "Keys: <Space> standard animation, <l> loop animation.",
 	.x = 10,
 	.y = 10,
 };
 
-static struct mlk_animation animation = {
+static struct mlk_animation explosion = {
 	.sprite = &mlk_registry_sprites[MLK_REGISTRY_TEXTURE_EXPLOSION],
-	.delay = 25
+	.delay  = 25
 };
-static int completed = 1;
+static struct mlk_animation loop = {
+	.sprite = &mlk_registry_sprites[MLK_REGISTRY_TEXTURE_CAT_RUNNING],
+	.delay  = 1000 / 16,
+	.flags  = MLK_ANIMATION_FLAGS_LOOP
+};
+static struct mlk_animation *animation;
 
 static void
 init(void)
@@ -59,16 +64,25 @@
 {
 	(void)st;
 
+	int changed = 0;
+
 	switch (ev->type) {
 	case MLK_EVENT_KEYDOWN:
 		switch (ev->key.key) {
 		case MLK_KEY_SPACE:
-			mlk_animation_start(&animation);
-			completed = mlk_animation_completed(&animation);
+			animation = &explosion;
+			changed = 1;
+			break;
+		case MLK_KEY_L:
+			animation = &loop;
+			changed = 1;
 			break;
 		default:
 			break;
 		}
+
+		if (animation && changed)
+			mlk_animation_start(animation);
 		break;
 	case MLK_EVENT_QUIT:
 		mlk_game_quit();
@@ -83,8 +97,8 @@
 {
 	(void)st;
 
-	if (!completed)
-		completed = mlk_animation_update(&animation, ticks);
+	if (animation && mlk_animation_update(animation, ticks))
+		animation = NULL;
 }
 
 static void
@@ -94,15 +108,15 @@
 
 	unsigned int cellw, cellh;
 
-	cellw = animation.sprite->cellw;
-	cellh = animation.sprite->cellh;
-
 	mlk_painter_set_color(MLK_EXAMPLE_BG);
 	mlk_painter_clear();
 	mlk_label_draw(&label);
 
-	if (!completed)
-		mlk_animation_draw(&animation, (mlk_window.w - cellw) / 2, (mlk_window.h - cellh) / 2);
+	if (animation) {
+		cellw = animation->sprite->cellw;
+		cellh = animation->sprite->cellh;
+		mlk_animation_draw(animation, (mlk_window.w - cellw) / 2, (mlk_window.h - cellh) / 2);
+	}
 
 	mlk_painter_present();
 }
--- a/libmlk-core/mlk/core/animation.c	Sat Mar 11 11:22:47 2023 +0100
+++ b/libmlk-core/mlk/core/animation.c	Sat Mar 11 21:20:33 2023 +0100
@@ -48,6 +48,8 @@
 	assert(an);
 	assert(!mlk_animation_completed(an));
 
+	int complete;
+
 	an->elapsed += ticks;
 
 	if (an->elapsed < an->delay)
@@ -66,7 +68,15 @@
 	} else
 		an->elapsed = 0;
 
-	return mlk_animation_completed(an);
+	complete = mlk_animation_completed(an);
+
+	/* Animation looping? Reset automatically. */
+	if (complete && (an->flags & MLK_ANIMATION_FLAGS_LOOP)) {
+		mlk_animation_start(an);
+		complete = 0;
+	}
+
+	return complete;
 }
 
 int
--- a/libmlk-core/mlk/core/animation.h	Sat Mar 11 11:22:47 2023 +0100
+++ b/libmlk-core/mlk/core/animation.h	Sat Mar 11 21:20:33 2023 +0100
@@ -27,11 +27,32 @@
  *
  * Animations are small objects using a ::mlk_sprite to update themselves and
  * draw next frames depending on delay set.
+ *
+ * Using the ::MLK_ANIMATION_FLAGS_LOOP, animations can be permanent and they
+ * reset automatically on update.
  */
 
 struct mlk_sprite;
 
 /**
+ * \enum mlk_animation_flags
+ * \brief Animation flags.
+ *
+ * This enumeration is implemented as a bitmask.
+ */
+enum mlk_animation_flags {
+	/**
+	 * No flags, default.
+	 */
+	MLK_ANIMATION_FLAGS_NONE,
+
+	/**
+	 * Animation never ends.
+	 */
+	MLK_ANIMATION_FLAGS_LOOP = (1 << 0)
+};
+
+/**
  * \struct mlk_animation
  * \brief Animation structure
  */
@@ -50,6 +71,13 @@
 	 */
 	unsigned int delay;
 
+	/**
+	 * (read-write)
+	 *
+	 * Optional animation flags.
+	 */
+	enum mlk_animation_flags flags;
+
 	/** \cond MLK_PRIVATE_DECLS */
 	unsigned int elapsed;
 	unsigned int row;
@@ -85,6 +113,9 @@
  *
  * This function MUST not be called if the animation is complete.
  *
+ * If the animation has ::MLK_ANIMATION_FLAGS_LOOP, this function will always
+ * return 0.
+ *
  * \pre animation != NULL and animation is not complete
  * \param animation the animation
  * \param ticks frame ticks
--- a/libmlk-example/CMakeLists.txt	Sat Mar 11 11:22:47 2023 +0100
+++ b/libmlk-example/CMakeLists.txt	Sat Mar 11 21:20:33 2023 +0100
@@ -39,6 +39,7 @@
 	${libmlk-example_SOURCE_DIR}/assets/music/vabsounds-romance.ogg
 	${libmlk-example_SOURCE_DIR}/assets/sounds/fire.wav
 	${libmlk-example_SOURCE_DIR}/assets/sounds/open-chest.wav
+	${libmlk-example_SOURCE_DIR}/assets/sprites/cat-running.png
 	${libmlk-example_SOURCE_DIR}/assets/sprites/chest.png
 	${libmlk-example_SOURCE_DIR}/assets/sprites/explosion.png
 	${libmlk-example_SOURCE_DIR}/assets/sprites/john-sword.png
Binary file libmlk-example/assets/sprites/cat-running.png has changed
--- a/libmlk-example/mlk/example/registry.c	Sat Mar 11 11:22:47 2023 +0100
+++ b/libmlk-example/mlk/example/registry.c	Sat Mar 11 21:20:33 2023 +0100
@@ -31,6 +31,7 @@
 #include <assets/sounds/fire.h>
 #include <assets/sounds/open-chest.h>
 
+#include <assets/sprites/cat-running.h>
 #include <assets/sprites/chest.h>
 #include <assets/sprites/explosion.h>
 #include <assets/sprites/john-sword.h>
@@ -76,18 +77,19 @@
 	unsigned int cellw;
 	unsigned int cellh;
 } textures[] = {
+	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_BLACK_CAT, assets_images_black_cat, 0, 0),
+	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_CAT_RUNNING, assets_sprites_cat_running, 512, 256),
+	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_CHEST, assets_sprites_chest, 32, 32),
 	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_CURSOR, assets_sprites_ui_cursor, 24, 24),
 	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_EXPLOSION, assets_sprites_explosion, 256, 256),
-	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_WATER, assets_sprites_water, 48, 48),
+	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_HAUNTED_WOOD, assets_images_haunted_wood, 0, 0),
 	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_JOHN, assets_sprites_john, 48, 48),
 	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_JOHN_SWORD, assets_sprites_john_sword, 256, 256),
 	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_JOHN_WALK, assets_sprites_john_walk, 256, 256),
-	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_HAUNTED_WOOD, assets_images_haunted_wood, 0, 0),
-	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_BLACK_CAT, assets_images_black_cat, 0, 0),
-	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_CHEST, assets_sprites_chest, 32, 32),
 	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_NUMBERS, assets_sprites_numbers, 48, 48),
+	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_PEOPLE, assets_sprites_people, 48, 48),
 	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_SWORD, assets_images_sword, 0, 0),
-	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_PEOPLE, assets_sprites_people, 48, 48),
+	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_WATER, assets_sprites_water, 48, 48),
 	MLK_REGISTRY_TEXTURE(MLK_REGISTRY_TEXTURE_WORLD, assets_sprites_world, 48, 48)
 };
 
--- a/libmlk-example/mlk/example/registry.h	Sat Mar 11 11:22:47 2023 +0100
+++ b/libmlk-example/mlk/example/registry.h	Sat Mar 11 21:20:33 2023 +0100
@@ -32,6 +32,7 @@
 	/* Animations. */
 	MLK_REGISTRY_TEXTURE_EXPLOSION,
 	MLK_REGISTRY_TEXTURE_WATER,
+	MLK_REGISTRY_TEXTURE_CAT_RUNNING,
 
 	/* Characters. */
 	MLK_REGISTRY_TEXTURE_JOHN,