diff --git a/CMakeLists.txt b/CMakeLists.txt index ff3e9dd..46bf132 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ set(SOURCES set(ASSETS res/tileset.png + res/missile.png res/editor_cursor.png res/test.kble res/burn.kble diff --git a/inc/conf.h b/inc/conf.h index e679506..85f169c 100644 --- a/inc/conf.h +++ b/inc/conf.h @@ -22,7 +22,7 @@ #define BOUNCE_SPEED -2.0f #define DRAW_OFF_X -2 #define GRAVS_MARGIN 0 -#define MISSILE_SIZE 6 #define MISSILE_MAX_SPEED 4.0f #define MISSILE_ACCEL 0.06f #define MISSILE_FRICTION (MISSILE_ACCEL / MISSILE_MAX_SPEED) +#define MISSILE_COOLDOWN (TARGET_FPS / 2) diff --git a/inc/missile.h b/inc/missile.h index 322faba..61b2c97 100644 --- a/inc/missile.h +++ b/inc/missile.h @@ -3,8 +3,8 @@ #include "vec.h" struct Missile { - int active; - struct VecF pos, spd; + int active, cooldown; + struct VecF spawn, pos, spd; }; struct MissileManager { @@ -16,5 +16,5 @@ void missile_manager_init(void); void missile_manager_free(void); void missile_manager_update(struct VecF target); void missile_manager_draw(void); -struct Missile *missile_new(int x, int y); +void missile_new(int x, int y); int missile_collide_player(const struct Player *); diff --git a/res/editor_cursor.png b/res/editor_cursor.png index 6ce82c7..95e0403 100644 Binary files a/res/editor_cursor.png and b/res/editor_cursor.png differ diff --git a/res/missile.png b/res/missile.png new file mode 100644 index 0000000..e59e3a3 Binary files /dev/null and b/res/missile.png differ diff --git a/res/tileset.png b/res/tileset.png index 4b8806d..ea428d6 100644 Binary files a/res/tileset.png and b/res/tileset.png differ diff --git a/src/level.c b/src/level.c index a1375b2..0cca348 100644 --- a/src/level.c +++ b/src/level.c @@ -63,7 +63,15 @@ level_load(int id) polarity_reset(); level_regen_visual_data(0); player_spawn(level.player); + + /* missiles */ missile_manager_init(); + i = level.size; + while (i-- > 0) + if (level.data[i] == TILE_MISSILE_LAUNCHER) + missile_new(i % level.width * TILE_SIZE + TILE_SIZE / 2, + (int)(i / level.width) * TILE_SIZE + + TILE_SIZE / 2); } void diff --git a/src/main.c b/src/main.c index 62f8aab..d912f04 100644 --- a/src/main.c +++ b/src/main.c @@ -84,8 +84,6 @@ update(void) player_update(&player); /* enter editor */ if (input_pressed(K_EDITOR)) editor(); - /* debug: spawn missile */ - if (input_pressed(K_DEBUG)) missile_new(DWIDTH / 2, DHEIGHT / 2); } static void diff --git a/src/missile.c b/src/missile.c index d7c86ed..f8a67f8 100644 --- a/src/missile.c +++ b/src/missile.c @@ -8,6 +8,7 @@ static struct MissileManager manager = {.missiles = NULL}; +static void missile_init(struct Missile *); static void missile_update(struct Missile *, struct VecF target); static void missile_draw(const struct Missile *); static int collide(int x, int y, int tile); @@ -18,13 +19,14 @@ missile_manager_init(void) { int i; missile_manager_free(); - /* debug: remove the `1 + ` later on */ - manager.n_missiles = 1 + level_count(TILE_MISSILE_LAUNCHER); + manager.n_missiles = level_count(TILE_MISSILE_LAUNCHER); manager.missiles = malloc(manager.n_missiles * sizeof(struct Missile)); i = manager.n_missiles; - while (i-- > 0) + while (i-- > 0) { manager.missiles[i].active = 0; + manager.missiles[i].cooldown = MISSILE_COOLDOWN; + } } void @@ -37,9 +39,13 @@ void missile_manager_update(struct VecF target) { int i = manager.n_missiles; - while (i-- > 0) - if (manager.missiles[i].active) - missile_update(&manager.missiles[i], target); + while (i-- > 0) { + struct Missile *const m = &manager.missiles[i]; + if (m->active) + missile_update(m, target); + else if (m->cooldown && !--m->cooldown) + missile_init(m); + } } void @@ -51,7 +57,7 @@ missile_manager_draw(void) missile_draw(&manager.missiles[i]); } -struct Missile * +void missile_new(int x, int y) { int i = manager.n_missiles; @@ -60,13 +66,20 @@ missile_new(int x, int y) ; m = &manager.missiles[(i > 0) ? (i) : (0)]; + m->spawn.x = x; + m->spawn.y = y; + missile_init(m); +} + +void +missile_init(struct Missile *m) +{ m->active = 1; - m->pos.x = x; - m->pos.y = y; + m->cooldown = MISSILE_COOLDOWN; + m->pos.x = m->spawn.x; + m->pos.y = m->spawn.y; m->spd.x = 0.0f; m->spd.y = 0.0f; - - return m; } int @@ -112,13 +125,10 @@ missile_update(struct Missile *m, struct VecF target) static void missile_draw(const struct Missile *m) { - const int x = m->pos.x + 0.5f; - const int y = m->pos.y + 0.5f; - const int x1 = x - MISSILE_SIZE / 2; - const int x2 = x + MISSILE_SIZE / 2 - 1; - const int y1 = y - MISSILE_SIZE / 2; - const int y2 = y + MISSILE_SIZE / 2 - 1; - drect(x1, y1, x2, y2, C_RED); + extern bopti_image_t bimg_missile; + const int x = (int)(m->pos.x + 0.5f) - bimg_missile.width / 2; + const int y = (int)(m->pos.y + 0.5f) - bimg_missile.height / 2; + dimage(x, y, &bimg_missile); } static int