diff --git a/CMakeLists.txt b/CMakeLists.txt index b7f33cd..08bdc3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,8 @@ set(SOURCES src/util.c src/camera.c src/anim.c + src/shatter.c + src/particles.c ) set(LEVELS @@ -27,6 +29,7 @@ set(LEVELS set(ASSETS res/tileset.png + res/shatter.png ${LEVELS} ) diff --git a/inc/anim.h b/inc/anim.h index d9da82b..0d92e2c 100644 --- a/inc/anim.h +++ b/inc/anim.h @@ -11,6 +11,7 @@ struct Anim { int life_ini; int life; int loop; + void (*callback)(struct Anim *); }; struct Anim anim_new(bopti_image_t *, int x, int y, int frame_width, diff --git a/inc/particles.h b/inc/particles.h new file mode 100644 index 0000000..51fbd0f --- /dev/null +++ b/inc/particles.h @@ -0,0 +1,9 @@ +#pragma once +#include "anim.h" + +#define MAX_PARTICLES 64 + +void particles_init(void); +void particles_add(struct Anim); +void particles_update(void); +void particles_draw(void); diff --git a/inc/shatter.h b/inc/shatter.h new file mode 100644 index 0000000..427357d --- /dev/null +++ b/inc/shatter.h @@ -0,0 +1,3 @@ +#pragma once + +void shatter(int x, int y); diff --git a/res/fxconv-metadata.txt b/res/fxconv-metadata.txt index 8134606..89bd603 100644 --- a/res/fxconv-metadata.txt +++ b/res/fxconv-metadata.txt @@ -1,3 +1,6 @@ tileset.png: type: bopti-image name: bimg_tileset +shatter.png: + type: bopti-image + name: bimg_shatter diff --git a/res/shatter.png b/res/shatter.png new file mode 100644 index 0000000..0535cc9 Binary files /dev/null and b/res/shatter.png differ diff --git a/src/anim.c b/src/anim.c index a824779..ee92571 100644 --- a/src/anim.c +++ b/src/anim.c @@ -16,6 +16,7 @@ anim_new(bopti_image_t *texture, int x, int y, int frame_width, anim.life_ini = frame_duration * texture->width / frame_width; anim.life = anim.life_ini; anim.loop = loop; + anim.callback = NULL; return anim; } @@ -27,6 +28,8 @@ anim_update(struct Anim *a) a->life--; if (a->life % a->frame_duration == 0) a->frame++; + if (!a->life && a->callback != NULL) + a->callback(a); /* loop */ if (!a->life && a->loop) { a->frame = 0; diff --git a/src/level.c b/src/level.c index 9ea9294..288f5dc 100644 --- a/src/level.c +++ b/src/level.c @@ -87,7 +87,7 @@ level_set(int x, int y, enum Tile v) { if (x < 0 || y < 0 || x >= self.width || y >= self.height) return; - self.data[x + y * self.size] = v; + self.data[x + y * self.width] = v; } void diff --git a/src/main.c b/src/main.c index b265d0b..9a5beab 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ #include "conf.h" #include "input.h" #include "level.h" +#include "particles.h" #include "player.h" #include "vec.h" #include @@ -25,6 +26,7 @@ main(void) GINT_CALL(callback, &has_ticked)); timer_start(timer); input_init(); + particles_init(); level_load(&lvl_test); player_init(level_find(TILE_PLAYER)); camera_init(player_pos()); @@ -52,6 +54,7 @@ main(void) static void update(void) { + particles_update(); input_update(); player_update(); camera_update(); @@ -63,6 +66,7 @@ draw(void) dclear(C_BLACK); level_draw(); player_draw(); + particles_draw(); dupdate(); } diff --git a/src/particles.c b/src/particles.c new file mode 100644 index 0000000..3cce7ac --- /dev/null +++ b/src/particles.c @@ -0,0 +1,39 @@ +#include "particles.h" +#include "anim.h" + +static struct Anim particles[MAX_PARTICLES]; + +void +particles_init(void) +{ + int i = MAX_PARTICLES; + while (i-- > 0) + particles[i] = anim_new(NULL, 0, 0, 1, 0, 0); +} + +void +particles_add(struct Anim a) +{ + /* find empty spot */ + int i = MAX_PARTICLES; + while (i-- > 0) + if (!particles[i].life) + break; + particles[i] = a; +} + +void +particles_update(void) +{ + int i = MAX_PARTICLES; + while (i-- > 0) + anim_update(&particles[i]); +} + +void +particles_draw(void) +{ + int i = MAX_PARTICLES; + while (i-- > 0) + anim_draw(&particles[i]); +} diff --git a/src/player.c b/src/player.c index 70d3454..752dd4d 100644 --- a/src/player.c +++ b/src/player.c @@ -3,6 +3,7 @@ #include "conf.h" #include "input.h" #include "level.h" +#include "shatter.h" #include "util.h" #include "vec.h" #include @@ -41,6 +42,9 @@ player_update(void) self.spd.y *= 1.0f - AIR_RESISTANCE; self.spd.y += GRAVITY; + if (input_pressed(K_DOWN)) + shatter(self.pos.x, self.pos.y + PLAYER_HEIGHT); + player_move(player_update_rem()); } diff --git a/src/shatter.c b/src/shatter.c new file mode 100644 index 0000000..4fd0edd --- /dev/null +++ b/src/shatter.c @@ -0,0 +1,27 @@ +#include "shatter.h" +#include "anim.h" +#include "conf.h" +#include "level.h" +#include "particles.h" +#include "tile.h" +#include "vec.h" +#include + +static void callback(struct Anim *); + +void +shatter(int x, int y) +{ + extern bopti_image_t bimg_shatter; + const int ax = (int)(x / TILE_SIZE) * TILE_SIZE; + const int ay = (int)(y / TILE_SIZE) * TILE_SIZE; + struct Anim p = anim_new(&bimg_shatter, ax, ay, TILE_SIZE, 2, false); + p.callback = callback; + particles_add(p); +} + +static void +callback(struct Anim *a) +{ + level_set_px(a->pos.x, a->pos.y, TILE_PLAYER); +}