1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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
|