diff --git a/inc/conf.h b/inc/conf.h index 495eb0f..e679506 100644 --- a/inc/conf.h +++ b/inc/conf.h @@ -22,6 +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) diff --git a/inc/missile.h b/inc/missile.h index 0bd528b..322faba 100644 --- a/inc/missile.h +++ b/inc/missile.h @@ -1,4 +1,5 @@ #pragma once +#include "player.h" #include "vec.h" struct Missile { @@ -16,3 +17,4 @@ 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); +int missile_collide_player(const struct Player *); diff --git a/src/missile.c b/src/missile.c index 8c4bf9a..d7c86ed 100644 --- a/src/missile.c +++ b/src/missile.c @@ -1,6 +1,8 @@ #include "missile.h" #include "conf.h" #include "level.h" +#include "polarity.h" +#include "tile.h" #include #include @@ -8,6 +10,8 @@ static struct MissileManager manager = {.missiles = NULL}; 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); +static int collide_stopper(int x, int y); void missile_manager_init(void) @@ -65,6 +69,23 @@ missile_new(int x, int y) return m; } +int +missile_collide_player(const struct Player *p) +{ + const float x1 = p->pos.x; + const float y1 = p->pos.y; + const float x2 = x1 + PLAYER_WIDTH - 1.0f; + const float y2 = y1 + PLAYER_HEIGHT - 1.0f; + int i = manager.n_missiles; + while (i-- > 0) { + const struct Missile *m = &manager.missiles[i]; + if (m->active && m->pos.x > x1 && m->pos.x < x2 && + m->pos.y > y1 && m->pos.y < y2) + return 1; + } + return 0; +} + static void missile_update(struct Missile *m, struct VecF target) { @@ -82,10 +103,34 @@ missile_update(struct Missile *m, struct VecF target) /* move */ m->pos.x += m->spd.x; m->pos.y += m->spd.y; + + /* destroy */ + if (collide_stopper(m->pos.x + 0.5f, m->pos.y + 0.5f)) + m->active = false; } static void missile_draw(const struct Missile *m) { - dpixel(m->pos.x + 0.5f, m->pos.y + 0.5f, C_RED); + 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); +} + +static int +collide(int x, int y, int tile) +{ + return level_get_px(x, y) == tile; +} + +static int +collide_stopper(int x, int y) +{ + return collide(x, y, TILE_SOLID) || + (!polarity() && collide(x, y, TILE_RED)) || + (polarity() && collide(x, y, TILE_BLUE)); } diff --git a/src/player.c b/src/player.c index 67b60d0..6be5726 100644 --- a/src/player.c +++ b/src/player.c @@ -3,6 +3,7 @@ #include "draw.h" #include "input.h" #include "level.h" +#include "missile.h" #include "polarity.h" #include "tile.h" #include "util.h" @@ -16,6 +17,7 @@ static int collide(int x, int y, int tile); static int collide_solid(int x, int y); static int collide_burn(int x, int y); static int collide_collect(int x, int y, int tile, int margin); +static void death(void); void player_spawn(struct Player *p) @@ -123,12 +125,16 @@ player_update(struct Player *p) /* burn and death */ if (collide_burn(p->pos.x, p->pos.y)) { if (++p->burn >= BURN_DEATH) { - level_reload(); + death(); return; } } else if (p->burn) { p->burn--; } + if (missile_collide_player(p)) { + death(); + return; + } /* next level */ if (collide(p->pos.x, p->pos.y, TILE_EXIT)) { @@ -283,3 +289,9 @@ collide_collect(int x, int y, int tile, int margin) { return collide_opt(x, y, tile, margin, 1); } + +static void +death(void) +{ + level_reload(); +}