diff options
Diffstat (limited to 'collision_system.c')
-rw-r--r-- | collision_system.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/collision_system.c b/collision_system.c new file mode 100644 index 0000000..abd5dc9 --- /dev/null +++ b/collision_system.c @@ -0,0 +1,105 @@ +#ifndef systems_h +#define systems_h + +#include "config.h" +#include "fx.h" +#include "rect.h" +#include "world.h" + +static void handle_bullet_vs_player( + World* world, + Entity bullet, + Entity player +) { + const CPosition* pos; + + pos = &world->positions[bullet]; + + destroy_entity(world, bullet); + new_enemy_bullet_explosion(world, pos->x, pos->y); +} + +static void handle_bullet_vs_enemy( + World* world, + Entity bullet, + Entity enemy +) { + CEnemy* e; + + e = &world->enemies[enemy]; + e->hp--; + destroy_entity(world, bullet); +} + +static void handle(World* world, Entity a, Entity b) { + unsigned ab, bb; + + ab = world->bitmask[a]; + bb = world->bitmask[b]; + + if ((ab & ctype_enemy_bullet) && (bb & ctype_player)) { + handle_bullet_vs_player(world, a, b); + return; + } + + if ((ab & ctype_player) && (bb & ctype_enemy_bullet)) { + handle_bullet_vs_player(world, b, a); + return; + } + + if ((ab & ctype_player_bullet) && (bb & ctype_enemy)) { + handle_bullet_vs_enemy(world, a, b); + return; + } + + if ((ab & ctype_enemy) && (bb & ctype_player_bullet)) { + handle_bullet_vs_enemy(world, b, a); + return; + } +} + +void collision_system(World* world) { + int i, j, p0x, p0y; + unsigned bits; + const CPosition* pos0, * pos1; + const CCollider* col0, * col1; + + for (i = 0; i < world->entity_count; i++) { + bits = world->bitmask[i]; + if ( + !(bits & ctype_collider) || + !(bits & ctype_position) + ) { continue; } + + pos0 = &world->positions[i]; + col0 = &world->colliders[i]; + p0x = pos0->x + col0->x; + p0y = pos0->y + col0->y; + + for (j = i + 1; j < world->entity_count; j++) { + bits = world->bitmask[j]; + if ( + !(bits & ctype_collider) || + !(bits & ctype_position) + ) { continue; } + + pos1 = &world->positions[j]; + col1 = &world->colliders[j]; + + if (rects_overlap2( + p0x, + p0y, + col0->w, + col0->h, + pos1->x + col1->x, + pos1->y + col1->y, + col1->w, + col1->h + )) { + handle(world, i, j); + } + } + } +} + +#endif |