Mercurial > molko
changeset 481:4b99b760e99c
examples: add chest for simplicity
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 27 Feb 2023 17:57:13 +0100 |
parents | c1f64d451230 |
children | f78455f45bf6 |
files | examples/example-action/CMakeLists.txt examples/example-action/chest.c examples/example-action/chest.h examples/example-action/example-action.c |
diffstat | 4 files changed, 183 insertions(+), 85 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/example-action/CMakeLists.txt Mon Feb 27 17:26:00 2023 +0100 +++ b/examples/example-action/CMakeLists.txt Mon Feb 27 17:57:13 2023 +0100 @@ -20,6 +20,8 @@ set( SOURCES + ${example-action_SOURCE_DIR}/chest.c + ${example-action_SOURCE_DIR}/chest.h ${example-action_SOURCE_DIR}/example-action.c )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example-action/chest.c Mon Feb 27 17:57:13 2023 +0100 @@ -0,0 +1,115 @@ +/* + * chest.c -- animated chest + * + * Copyright (c) 2020-2023 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 <assert.h> + +#include <mlk/core/event.h> +#include <mlk/core/maths.h> +#include <mlk/core/sprite.h> + +#include <mlk/example/registry.h> + +#include "chest.h" + +#define CHEST_DELAY 80 + +static void +handle(struct mlk_action *act, const union mlk_event *ev) +{ + struct chest *chest = act->data; + unsigned int cw, ch; + + /* Make sure that we don't operate on a already opened chest. */ + if (chest->state == CHEST_STATE_OPENED) + return; + + /* + * We are only interested if the event is a click on the chest itself + * so we have to test because actions have no notion of geometry. + */ + if (ev->type != MLK_EVENT_CLICKDOWN) + return; + + cw = registry_sprites[REGISTRY_TEXTURE_CHEST].cellw; + ch = registry_sprites[REGISTRY_TEXTURE_CHEST].cellh; + + if (!mlk_maths_is_boxed(chest->x, chest->y, cw, ch, ev->click.x, ev->click.y)) + return; + + mlk_animation_start(&chest->animation); + chest->state = CHEST_STATE_OPENING; +} + +static int +update(struct mlk_action *act, unsigned int ticks) +{ + struct chest *chest = act->data; + + if (chest->state != CHEST_STATE_OPENING) + return 0; + + if (mlk_animation_update(&chest->animation, ticks)) { + chest->state = CHEST_STATE_OPENED; + + if (chest->run) + chest->run(chest); + } + + /* The chest never dies. */ + return 0; +} + +static void +draw(struct mlk_action *act) +{ + const struct chest *chest = act->data; + + switch (chest->state) { + case CHEST_STATE_CLOSED: + mlk_sprite_draw(chest->animation.sprite, 0, 0, chest->x, chest->y); + break; + case CHEST_STATE_OPENING: + mlk_animation_draw(&chest->animation, chest->x, chest->y); + break; + case CHEST_STATE_OPENED: + mlk_sprite_draw(chest->animation.sprite, + chest->animation.sprite->nrows - 1, + chest->animation.sprite->ncols - 1, + chest->x, + chest->y); + break; + default: + break; + } +} + +struct mlk_action * +chest_init(struct chest *chest) +{ + assert(chest); + + chest->state = CHEST_STATE_CLOSED; + chest->action.data = chest; + chest->action.handle = handle; + chest->action.update = update; + chest->action.draw = draw; + + mlk_animation_init(&chest->animation, ®istry_sprites[REGISTRY_TEXTURE_CHEST], CHEST_DELAY); + + return &chest->action; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example-action/chest.h Mon Feb 27 17:57:13 2023 +0100 @@ -0,0 +1,48 @@ +/* + * chest.h -- animated chest + * + * Copyright (c) 2020-2023 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. + */ + +#ifndef MLK_EXAMPLE_ACTION_CHEST_H +#define MLK_EXAMPLE_ACTION_CHEST_H + +#include <mlk/core/action.h> +#include <mlk/core/animation.h> + +enum chest_state { + CHEST_STATE_CLOSED, + CHEST_STATE_OPENING, + CHEST_STATE_OPENED +}; + +struct chest { + /* public */ + int x; + int y; + void *data; + enum chest_state state; + void (*run)(struct chest *); + void (*finish)(struct chest *); + + /* private */ + struct mlk_animation animation; + struct mlk_action action; +}; + +struct mlk_action * +chest_init(struct chest *chest); + +#endif /* !MLK_EXAMPLE_ACTION_CHEST_H */
--- a/examples/example-action/example-action.c Mon Feb 27 17:26:00 2023 +0100 +++ b/examples/example-action/example-action.c Mon Feb 27 17:57:13 2023 +0100 @@ -24,7 +24,6 @@ #include <mlk/core/err.h> #include <mlk/core/event.h> #include <mlk/core/game.h> -#include <mlk/core/maths.h> #include <mlk/core/painter.h> #include <mlk/core/panic.h> #include <mlk/core/sprite.h> @@ -41,6 +40,8 @@ #include <mlk/rpg/message.h> +#include "chest.h" + /* Message width is 80% of window width and height is auto computed. */ #define QMW (MLK_EXAMPLE_W * 0.8) @@ -61,33 +62,8 @@ * For convenience, we arrange those two chests into a mlk_action_stack to * avoid calling all mlk_action functions for every chests. */ -static void chest_handle(struct mlk_action *, const union mlk_event *); -static void chest_draw(struct mlk_action *); -static struct chest { - int x; - int y; - int open; - struct mlk_sprite *sprite; - struct mlk_action action; -} chests[2] = { - [0] = { - .sprite = ®istry_sprites[REGISTRY_TEXTURE_CHEST], - .action = { - .data = &chests[0], - .draw = chest_draw, - .handle = chest_handle, - } - }, - [1] = { - .sprite = ®istry_sprites[REGISTRY_TEXTURE_CHEST], - .action = { - .data = &chests[1], - .draw = chest_draw, - .handle = chest_handle, - } - } -}; +static struct chest chests[2]; /* * This structure is the item that will be pushed into the mlk_action_script @@ -119,9 +95,6 @@ static int item_update(struct mlk_action *, unsigned int); static void item_draw(struct mlk_action *); -static void script_init_quest1(void); -static void script_init_quest2(void); - static void response_quest1_start(struct mlk_action *); static void response_quest2_start(struct mlk_action *); @@ -244,59 +217,6 @@ static struct mlk_action_script script; static void -chest_handle(struct mlk_action *act, const union mlk_event *ev) -{ - struct chest *chest = act->data; - unsigned int cw, ch; - - /* Make sure that we don't operate on a already opened chest. */ - if (chest->open) - return; - - /* - * We are only interested if the event is a click on the chest itself - * so we have to test because actions have no notion of geometry. - */ - if (ev->type != MLK_EVENT_CLICKDOWN) - return; - - cw = registry_sprites[REGISTRY_TEXTURE_CHEST].cellw; - ch = registry_sprites[REGISTRY_TEXTURE_CHEST].cellh; - - if (!mlk_maths_is_boxed(chest->x, chest->y, cw, ch, ev->click.x, ev->click.y)) - return; - - /* Also, make sure that we don't operate on a already opened chest. */ - chest->open = 1; - - /* - * Now depending on the chest, update the main script with actual code - * we're interested in. - */ - memset(script_actions, 0, sizeof (script_actions)); - mlk_action_script_init(&script, script_actions, MLK_UTIL_SIZE(script_actions)); - - if (chest == &chests[0]) - script_init_quest1(); - else - script_init_quest2(); -} - -static void -chest_draw(struct mlk_action *act) -{ - const struct chest *chest = act->data; - int column; - - if (chest->open) - column = 3; - else - column = 0; - - mlk_sprite_draw(chest->sprite, 0, column, chest->x, chest->y); -} - -static void item_handle(struct mlk_action *act, const union mlk_event *ev) { message_handle(act->data, ev); @@ -319,6 +239,9 @@ { int err; + memset(script_actions, 0, sizeof (script_actions)); + mlk_action_script_init(&script, script_actions, MLK_UTIL_SIZE(script_actions)); + for (size_t i = 0; i < n; ++i) { m[i].msg.x = QMX; m[i].msg.y = QMY; @@ -337,14 +260,18 @@ } static void -script_init_quest1(void) +script_init_quest1(struct chest *chest) { + (void)chest; + script_init_quest(quest1, MLK_UTIL_SIZE(quest1)); } static void -script_init_quest2(void) +script_init_quest2(struct chest *chest) { + (void)chest; + script_init_quest(quest2, MLK_UTIL_SIZE(quest2)); } @@ -400,6 +327,12 @@ 0, 0, MLK_EXAMPLE_W / 2, MLK_EXAMPLE_H); align(ALIGN_CENTER, &chests[1].x, &chests[1].y, cw, ch, MLK_EXAMPLE_W / 2, 0, MLK_EXAMPLE_W / 2, MLK_EXAMPLE_H); + + chests[0].run = script_init_quest1; + chests[1].run = script_init_quest2; + + chest_init(&chests[0]); + chest_init(&chests[1]); } static void