Refactor asteroid generation

This commit is contained in:
Camden Dixie O'Brien
2025-10-14 16:09:38 +01:00
parent 1291ec191f
commit 57f5b345f8

94
game.c
View File

@@ -19,6 +19,12 @@
#define ASTEROID_OMG_JITTER 0.005 #define ASTEROID_OMG_JITTER 0.005
#define INIT_ASTEROIDS 8 #define INIT_ASTEROIDS 8
#define ASTEROID_SMALL 0.05
#define ASTEROID_MEDIUM 0.1
#define ASTEROID_LARGE 0.15
#define ASTEROID_R_JITTER 0.02
#define ASTEROID_MIN_DIST 0.5
#define LIN_PWR 0.0001 #define LIN_PWR 0.0001
#define ROT_PWR 0.002 #define ROT_PWR 0.002
@@ -48,11 +54,6 @@ typedef struct {
uint8_t flags; uint8_t flags;
} shape_t; } shape_t;
typedef enum {
ASTEROID_SMALL,
ASTEROID_MEDIUM,
ASTEROID_LARGE,
} asteroid_size_t;
static const vec2_t ship_verts[] = { static const vec2_t ship_verts[] = {
{ 0.0, 0.11 }, { 0.0, 0.11 },
@@ -124,63 +125,52 @@ static void shoot()
memcpy(s->verts, shot_verts, sizeof(shot_verts)); memcpy(s->verts, shot_verts, sizeof(shot_verts));
} }
static void gen_asteroid_shape(asteroid_size_t size, shape_t *out) static entity_t *gen_asteroid(float r_mean)
{
float r_mean, r_jitter;
switch (size) {
case ASTEROID_SMALL:
r_mean = 0.05;
r_jitter = 0.02;
break;
case ASTEROID_MEDIUM:
r_mean = 0.1;
r_jitter = 0.02;
break;
case ASTEROID_LARGE:
r_mean = 0.15;
r_jitter = 0.05;
}
const unsigned n
= ASTEROID_MIN_VERTS + rng_uint32() % (ASTEROID_VERT_RANGE);
out->vert_count = n;
const float da = 2.0f * PI / n;
for (unsigned i = 0; i < n; ++i) {
const float r = r_mean + rng_plusminus() * r_jitter;
const float a
= i * da + ASTEROID_A_JITTER * rng_plusminus() * da / 2;
out->verts[i] = (vec2_t) { r * cosf(a), r * sinf(a) };
}
}
static void add_asteroid()
{ {
unsigned id; unsigned id;
entity_t *e = add_entity(&id); entity_t *e = add_entity(&id);
e->wrap = true; e->wrap = true;
e->pos.y = rng_plusminus();
e->pos.x = aspect * rng_plusminus();
e->vel = (vec2_t) {
ASTEROID_VEL_JITTER * rng_plusminus(),
ASTEROID_VEL_JITTER * rng_plusminus(),
};
e->omg = ASTEROID_OMG_JITTER * rng_plusminus();
shape_t *s = add_shape(id, nullptr); shape_t *s = add_shape(id, nullptr);
s->visible = true; s->visible = true;
s->flags = WRAP | CONNECT; s->flags = WRAP | CONNECT;
asteroid_size_t size; const unsigned n
const float r = rng_canon(); = ASTEROID_MIN_VERTS + rng_uint32() % ASTEROID_VERT_RANGE;
if (r < 0.2) s->vert_count = n;
size = ASTEROID_SMALL;
else if (r < 0.5)
size = ASTEROID_MEDIUM;
else
size = ASTEROID_LARGE;
gen_asteroid_shape(size, s); const float da = 2.0f * PI / n;
for (unsigned i = 0; i < n; ++i) {
const float r = r_mean + rng_plusminus() * ASTEROID_R_JITTER;
const float a
= i * da + ASTEROID_A_JITTER * rng_plusminus() * da / 2;
s->verts[i] = (vec2_t) { r * cosf(a), r * sinf(a) };
}
return e;
}
static void add_asteroid()
{
float r;
const float rnd = rng_canon();
if (rnd < 0.2)
r = ASTEROID_SMALL;
else if (rnd < 0.6)
r = ASTEROID_MEDIUM;
else
r = ASTEROID_LARGE;
entity_t *e = gen_asteroid(r);
do {
e->pos.y = rng_plusminus();
e->pos.x = aspect * rng_plusminus();
} while (vec2_len(e->pos) < ASTEROID_MIN_DIST);
e->vel = (vec2_t) {
ASTEROID_VEL_JITTER * rng_plusminus(),
ASTEROID_VEL_JITTER * rng_plusminus(),
};
e->omg = ASTEROID_OMG_JITTER * rng_plusminus();
} }
static void remove_shape(unsigned id) static void remove_shape(unsigned id)