Implement asteroid bouncing

This commit is contained in:
Camden Dixie O'Brien
2025-10-14 17:19:02 +01:00
parent b05a4b3fe4
commit 47a0c9ffad
3 changed files with 38 additions and 1 deletions

23
game.c
View File

@@ -261,6 +261,24 @@ static unsigned check_collisions(collision_t *out)
return count;
}
static void bounce_asteroids(entity_t *a, entity_t *b)
{
const float ma = a->radius * a->radius;
const float mb = b->radius * b->radius;
const float m = ma + mb;
const vec2_t n = vec2_norm(vec2_sub(b->pos, a->pos));
const float va1 = vec2_dot(a->vel, n);
const float vb1 = vec2_dot(b->vel, n);
const float va2 = (va1 * (ma - mb) + 2 * mb * vb1) / m;
const float vb2 = (vb1 * (mb - ma) + 2 * ma * va1) / m;
a->vel = vec2_add(a->vel, vec2_scale(n, va2 - va1));
b->vel = vec2_add(b->vel, vec2_scale(n, vb2 - vb1));
}
static void handle_collisions(const collision_t *collisions, unsigned count)
{
for (unsigned i = 0; i < count; ++i) {
@@ -276,7 +294,10 @@ static void handle_collisions(const collision_t *collisions, unsigned count)
if (a->tag == COLLISION_SHOT && b->tag == COLLISION_SHOT)
continue;
if (a->tag == COLLISION_ASTEROID && b->tag == COLLISION_ASTEROID) { }
if (a->tag == COLLISION_ASTEROID && b->tag == COLLISION_ASTEROID) {
bounce_asteroids(a, b);
continue;
}
if (a->tag == COLLISION_SHOT) {
a->dead = true;

14
maths.c
View File

@@ -27,6 +27,20 @@ vec3_t vec2_extend(vec2_t v)
return (vec3_t) { v.x, v.y, 1 };
}
vec2_t vec2_norm(vec2_t v)
{
const float l = vec2_len(v);
return (vec2_t) {
v.x / l,
v.y / l,
};
}
float vec2_dot(vec2_t v1, vec2_t v2)
{
return v1.x * v2.x + v1.y * v2.y;
}
mat2_t mat2_rotation(float theta)
{
return (mat2_t) {

View File

@@ -24,6 +24,8 @@ vec2_t vec2_add(vec2_t v1, vec2_t v2);
vec2_t vec2_sub(vec2_t v1, vec2_t v2);
vec2_t vec2_scale(vec2_t v, float s);
vec3_t vec2_extend(vec2_t v);
vec2_t vec2_norm(vec2_t v);
float vec2_dot(vec2_t v1, vec2_t v2);
mat2_t mat2_rotation(float theta);
vec2_t mat2_mul_vec2(mat2_t m, vec2_t v);