Mercurial > molko
changeset 183:604fad63bd9c
core: fix animation delay
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 02 Nov 2020 13:42:51 +0100 |
parents | f6497ec74b49 |
children | c92957c3b82b |
files | examples/CMakeLists.txt examples/example-animation.c libcore/core/animation.c libcore/core/animation.h |
diffstat | 4 files changed, 166 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/CMakeLists.txt Tue Oct 27 16:54:18 2020 +0100 +++ b/examples/CMakeLists.txt Mon Nov 02 13:42:51 2020 +0100 @@ -29,6 +29,15 @@ ) molko_define_executable( + TARGET example-animation + SOURCES example-animation.c + FOLDER examples + ASSETS + ${examples_SOURCE_DIR}/assets/sprites/numbers.png + LIBRARIES libui +) + +molko_define_executable( TARGET example-cursor SOURCES example-cursor.c FOLDER examples
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example-animation.c Mon Nov 02 13:42:51 2020 +0100 @@ -0,0 +1,132 @@ +/* + * example-animation.c -- example on how to use animations + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <core/animation.h> +#include <core/clock.h> +#include <core/core.h> +#include <core/event.h> +#include <core/image.h> +#include <core/sys.h> +#include <core/window.h> +#include <core/painter.h> +#include <core/panic.h> +#include <core/sprite.h> +#include <core/texture.h> +#include <core/util.h> + +#include <ui/label.h> +#include <ui/ui.h> + +#include <assets/sprites/numbers.h> + +#define W 1280 +#define H 720 + +static struct texture numbers; + +static struct label label = { + .text = "Keys: <Space> start or reset the animation.", + .x = 10, + .y = 10, + .flags = LABEL_FLAGS_SHADOW +}; + +static void +init(void) +{ + if (!core_init() || !ui_init()) + panic(); + if (!window_open("Example - Animation", W, H)) + panic(); + if (!image_openmem(&numbers, sprites_numbers, sizeof (sprites_numbers))) + panic(); +} + +static void +run(void) +{ + struct clock clock = {0}; + struct animation animation; + struct sprite sprite; + bool completed = true; + + clock_start(&clock); + sprite_init(&sprite, &numbers, 128, 128); + animation_init(&animation, &sprite, 1000); + + for (;;) { + union event ev; + unsigned int elapsed = clock_elapsed(&clock); + + clock_start(&clock); + + while (event_poll(&ev)) { + switch (ev.type) { + case EVENT_KEYDOWN: + switch (ev.key.key) { + case KEY_SPACE: + animation_start(&animation); + completed = animation_completed(&animation); + break; + default: + break; + } + break; + case EVENT_QUIT: + return; + default: + break; + } + } + + if (!completed) + completed = animation_update(&animation, elapsed); + + painter_set_color(0x4f8fbaff); + painter_clear(); + label_draw(&label); + + if (!completed) + animation_draw(&animation, (window.w - sprite.cellw) / 2, (window.h - sprite.cellh) / 2); + + painter_present(); + + if ((elapsed = clock_elapsed(&clock)) < 20) + delay(20 - elapsed); + } +} + +static void +quit(void) +{ + window_finish(); + ui_finish(); + core_finish(); +} + +int +main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + init(); + run(); + quit(); +} +
--- a/libcore/core/animation.c Tue Oct 27 16:54:18 2020 +0100 +++ b/libcore/core/animation.c Mon Nov 02 13:42:51 2020 +0100 @@ -59,6 +59,14 @@ } bool +animation_completed(const struct animation *an) +{ + return an->elapsed >= an->delay && + an->row >= an->sprite->nrows && + an->column >= an->sprite->ncols; +} + +bool animation_update(struct animation *an, unsigned int ticks) { assert(an); @@ -77,16 +85,15 @@ if (++an->row >= an->sprite->nrows) an->row = an->sprite->nrows; else - an->column = 0; - } + an->column = an->elapsed = 0; + } else + an->elapsed = 0; - return an->elapsed >= an->delay && - an->row >= an->sprite->nrows && - an->column >= an->sprite->ncols; + return animation_completed(an); } bool -animation_draw(struct animation *an, int x, int y) +animation_draw(const struct animation *an, int x, int y) { return sprite_draw(an->sprite, an->row, an->column, x, y); }
--- a/libcore/core/animation.h Tue Oct 27 16:54:18 2020 +0100 +++ b/libcore/core/animation.h Mon Nov 02 13:42:51 2020 +0100 @@ -66,6 +66,16 @@ animation_start(struct animation *an); /** + * Tells if the animation has completed. + * + * \pre an != NULL + * \param an the animation + * \return True if the animation shown all images. + */ +bool +animation_completed(const struct animation *an); + +/** * Update the animation. * * You must call this function at each loop iteration to update the animation @@ -82,14 +92,14 @@ /** * Draw the animation. * - * \pre an != NULL + * \pre an != NULL && !animation_completed(an) * \param an the animation * \param x the X coordinate * \param y the Y coordinate * \return False in case of rendering error. */ bool -animation_draw(struct animation *an, int x, int y); +animation_draw(const struct animation *an, int x, int y); /** * Create a drawable from an animation.