Mercurial > molko
view examples/example-map/main.c @ 212:ddfe0a211169
rpg: experiment with map teleport
author | David Demelier <markand@malikania.fr> |
---|---|
date | Mon, 16 Nov 2020 14:26:13 +0100 |
parents | 70e6ed74940d |
children | 64f24b482722 |
line wrap: on
line source
/* * example-map.c -- show how to use maps * * 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 <stdio.h> #include <stdlib.h> #include <string.h> #include <core/alloc.h> #include <core/core.h> #include <core/event.h> #include <core/game.h> #include <core/image.h> #include <core/maths.h> #include <core/painter.h> #include <core/panic.h> #include <core/state.h> #include <core/texture.h> #include <core/window.h> #include <ui/ui.h> #include <rpg/map.h> #include <rpg/map-file.h> #include <rpg/rpg.h> #include <rpg/teleport.h> #include <assets/sprites/john.h> #define W (1280) #define H (720) static struct action *load_action(struct map *, int, int, int, int, const char *); struct map_state { struct map_file loader; struct map map; struct state state; }; static struct texture john_texture; static struct sprite john_sprite; static void map_state_start(struct state *st) { struct map_state *ms = st->data; game.inhibit &= ~(INHIBIT_STATE_INPUT); map_init(&ms->map); } static void map_state_update(struct state *st, unsigned int ticks) { struct map_state *ms = st->data; map_update(&ms->map, ticks); } static void map_state_handle(struct state *st, const union event *ev) { struct map_state *ms = st->data; switch (ev->type) { case EVENT_QUIT: game_quit(); break; default: map_handle(&ms->map, ev); break; } } static void map_state_draw(struct state *st) { struct map_state *ms = st->data; painter_set_color(0xffffffff); painter_clear(); map_draw(&ms->map); painter_present(); } static void map_state_finish(struct state *state) { struct map_state *ms = state->data; map_finish(&ms->map); map_file_finish(&ms->loader); } static struct state * map_state_new(const char *name) { char path[1024]; struct map_state *ms; ms = alloc_zero(1, sizeof (*ms)); ms->loader.load_action = load_action; snprintf(path, sizeof (path), "%s/%s.map", BINDIR, name); if (!map_file_open(&ms->loader, path, &ms->map)) panic(); /* TODO: we may need to add a function in loader. */ ms->map.player_sprite = &john_sprite; map_init(&ms->map); ms->state.data = ms; ms->state.start = map_state_start; ms->state.handle = map_state_handle; ms->state.update = map_state_update; ms->state.draw = map_state_draw; ms->state.finish = map_state_finish; return &ms->state; } struct teleport_effect { struct action act; struct teleport tp; }; static void teleport_effect_draw(struct action *act) { struct teleport_effect *fx = act->data; teleport_draw(&fx->tp); } static bool teleport_effect_update(struct action *act, unsigned int ticks) { struct teleport_effect *fx = act->data; return teleport_update(&fx->tp, ticks); } static void teleport_effect_finish(struct action *act) { struct teleport_effect *fx = act->data; teleport_finish(&fx->tp); } static void teleport_effect(struct map *current_map, const char *name) { struct teleport_effect *fx; fx = alloc_zero(1, sizeof (*fx)); fx->tp.state = map_state_new(name); fx->act.data = fx; fx->act.draw = teleport_effect_draw; fx->act.update = teleport_effect_update; fx->act.finish = teleport_effect_finish; /* Stop movement. */ current_map->player_movement = 0; /* Player isn't allowed to move anymore. */ game.inhibit = INHIBIT_STATE_INPUT; teleport_start(&fx->tp); action_stack_add(¤t_map->actions, &fx->act); } struct teleport_touch { struct action act; struct map *map; /* Current map. */ char name[256]; int x; int y; unsigned int w; unsigned int h; }; static bool teleport_touch_update(struct action *act, unsigned int ticks) { (void)ticks; const struct teleport_touch *touch = act->data; const int x = touch->x - touch->map->player_sprite->cellw; const int y = touch->y - touch->map->player_sprite->cellh; const unsigned int w = touch->w + touch->map->player_sprite->cellw; const unsigned int h = touch->h + touch->map->player_sprite->cellh; if (maths_is_boxed(x, y, w, h, touch->map->player_x, touch->map->player_y)) { teleport_effect(touch->map, touch->name); return true; } return false; } static void teleport_touch_finish(struct action *act) { free(act->data); } static struct action * teleport_touch_new(struct map *map, int x, int y, int w, int h, const char *name) { struct teleport_touch *touch; touch = alloc_zero(1, sizeof (*touch)); touch->map = map; touch->x = x; touch->y = y; touch->w = w; touch->h = h; snprintf(touch->name, sizeof (touch->name), "%s", name); touch->act.data = touch; touch->act.update = teleport_touch_update; touch->act.finish = teleport_touch_finish; return &touch->act; } static struct action * load_action(struct map *map, int x, int y, int w, int h, const char *id) { if (strncmp(id, "teleport:", 9) == 0) return teleport_touch_new(map, x, y, w, h, id + 9); return NULL; } static void init(void) { if (!core_init() || !ui_init()) panic(); if (!window_open("Example - Map", W, H)) panic(); if (!image_openmem(&john_texture, sprites_john, sizeof (sprites_john))) panic(); sprite_init(&john_sprite, &john_texture, 48, 48); } static void quit(void) { window_finish(); ui_finish(); core_finish(); } static void run(void) { game_switch(map_state_new("simple"), true); game_loop(); } int main(int argc, char **argv) { (void)argc; (void)argv; init(); run(); quit(); }