forked from tas/major_tom
Redesign asteroids: cold moonrock art, bigger impact explosions
Replace warm brown asteroid sprites with cold grey cratered moonrock using irregular silhouettes and crater detail. No burning/fire trail since there is no atmosphere on the moon — trail is now grey dust debris. Ground impact uses a 4-layer explosion: rock shrapnel, dust plume, ground-level dust spread, and a brief white flash. Player-hit also gets shrapnel + dust cloud instead of the old small puff.
This commit is contained in:
3
Containerfile
Normal file
3
Containerfile
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
FROM scratch
|
||||||
|
ENTRYPOINT ["/game.wasm"]
|
||||||
|
COPY /src/dist-web/jnr.wasm /game.wasm
|
||||||
@@ -52,6 +52,6 @@ LAYER collision
|
|||||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||||
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||||
1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 0 0 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 0 0 0 1 1 1 1 1 1 1 2 1 1 1 1 1 0 0 0 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1 0 0 0 0 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1 0 0 0 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1 0 0 0 0 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 0 0 0 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1
|
1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 0 0 0 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 0 0 0 1 1 1 1 1 1 1 2 1 1 1 1 1 0 0 0 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1 0 0 0 0 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1 0 0 0 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1 0 0 0 0 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 0 0 0 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 2 1 1 1
|
||||||
1 1 1 1 3 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 3 1 1 1 0 0 1 1 1 3 1 1 1 1 1 1 1 1 3 1 1 0 0 0 1 1 1 3 1 1 1 1 1 1 1 1 3 0 0 0 1 1 1 1 1 3 1 1 1 1 1 1 1 1 3 1 1 0 0 0 0 1 1 3 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 3 0 0 0 1 1 1 1 1 3 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1
|
1 1 1 1 3 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 3 1 1 0 0 0 1 1 1 3 1 1 1 1 1 1 1 1 3 1 1 0 0 0 1 1 1 3 1 1 1 1 1 1 1 1 3 0 0 0 1 1 1 1 1 3 1 1 1 1 1 1 1 1 3 1 1 0 0 0 0 1 1 3 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 3 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 3 0 0 0 1 1 1 1 1 3 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1
|
||||||
|
|||||||
@@ -648,28 +648,28 @@ static void asteroid_update(Entity *self, float dt, const Tilemap *map) {
|
|||||||
/* Tumble animation */
|
/* Tumble animation */
|
||||||
animation_update(&self->anim, dt);
|
animation_update(&self->anim, dt);
|
||||||
|
|
||||||
/* Smoke trail particles */
|
/* Debris trail — cold grey dust kicked off the tumbling rock */
|
||||||
ad->trail_timer -= dt;
|
ad->trail_timer -= dt;
|
||||||
if (ad->trail_timer <= 0) {
|
if (ad->trail_timer <= 0) {
|
||||||
ad->trail_timer = 0.04f;
|
ad->trail_timer = 0.06f;
|
||||||
Vec2 center = vec2(
|
Vec2 center = vec2(
|
||||||
self->body.pos.x + self->body.size.x * 0.5f,
|
self->body.pos.x + self->body.size.x * 0.5f,
|
||||||
self->body.pos.y
|
self->body.pos.y
|
||||||
);
|
);
|
||||||
ParticleBurst trail = {
|
ParticleBurst trail = {
|
||||||
.origin = center,
|
.origin = center,
|
||||||
.count = 2,
|
.count = 3,
|
||||||
.speed_min = 5.0f,
|
.speed_min = 8.0f,
|
||||||
.speed_max = 20.0f,
|
.speed_max = 30.0f,
|
||||||
.life_min = 0.2f,
|
.life_min = 0.15f,
|
||||||
.life_max = 0.5f,
|
.life_max = 0.4f,
|
||||||
.size_min = 1.0f,
|
.size_min = 1.0f,
|
||||||
.size_max = 2.0f,
|
.size_max = 2.5f,
|
||||||
.spread = 0.5f,
|
.spread = 0.8f,
|
||||||
.direction = -(float)M_PI / 2.0f, /* upward */
|
.direction = -(float)M_PI / 2.0f, /* upward */
|
||||||
.drag = 2.0f,
|
.drag = 2.5f,
|
||||||
.gravity_scale = 0.0f,
|
.gravity_scale = 0.0f,
|
||||||
.color = {140, 110, 80, 180},
|
.color = {160, 160, 165, 150}, /* cold grey dust */
|
||||||
.color_vary = true,
|
.color_vary = true,
|
||||||
};
|
};
|
||||||
particle_emit(&trail);
|
particle_emit(&trail);
|
||||||
@@ -703,8 +703,44 @@ static void asteroid_update(Entity *self, float dt, const Tilemap *map) {
|
|||||||
player->body.pos.x + player->body.size.x * 0.5f,
|
player->body.pos.x + player->body.size.x * 0.5f,
|
||||||
player->body.pos.y + player->body.size.y * 0.5f
|
player->body.pos.y + player->body.size.y * 0.5f
|
||||||
);
|
);
|
||||||
particle_emit_spark(hit_pos, (SDL_Color){180, 140, 80, 255});
|
|
||||||
particle_emit_death_puff(hit_pos, (SDL_Color){140, 110, 80, 255});
|
/* Rock shrapnel — fast grey chunks */
|
||||||
|
ParticleBurst shrapnel = {
|
||||||
|
.origin = hit_pos,
|
||||||
|
.count = 10,
|
||||||
|
.speed_min = 60.0f,
|
||||||
|
.speed_max = 180.0f,
|
||||||
|
.life_min = 0.2f,
|
||||||
|
.life_max = 0.5f,
|
||||||
|
.size_min = 1.5f,
|
||||||
|
.size_max = 3.0f,
|
||||||
|
.spread = (float)M_PI,
|
||||||
|
.direction = 0,
|
||||||
|
.drag = 2.0f,
|
||||||
|
.gravity_scale = 0.4f,
|
||||||
|
.color = {150, 150, 155, 255},
|
||||||
|
.color_vary = true,
|
||||||
|
};
|
||||||
|
particle_emit(&shrapnel);
|
||||||
|
|
||||||
|
/* Dust cloud */
|
||||||
|
ParticleBurst dust = {
|
||||||
|
.origin = hit_pos,
|
||||||
|
.count = 8,
|
||||||
|
.speed_min = 20.0f,
|
||||||
|
.speed_max = 60.0f,
|
||||||
|
.life_min = 0.3f,
|
||||||
|
.life_max = 0.6f,
|
||||||
|
.size_min = 2.0f,
|
||||||
|
.size_max = 4.0f,
|
||||||
|
.spread = (float)M_PI,
|
||||||
|
.direction = 0,
|
||||||
|
.drag = 4.0f,
|
||||||
|
.gravity_scale = 0.0f,
|
||||||
|
.color = {130, 130, 135, 180},
|
||||||
|
.color_vary = true,
|
||||||
|
};
|
||||||
|
particle_emit(&dust);
|
||||||
|
|
||||||
if (s_asteroid_sfx_loaded) {
|
if (s_asteroid_sfx_loaded) {
|
||||||
audio_play_sound_at(s_sfx_asteroid_impact, 80, hit_pos, 0);
|
audio_play_sound_at(s_sfx_asteroid_impact, 80, hit_pos, 0);
|
||||||
@@ -726,12 +762,88 @@ static void asteroid_update(Entity *self, float dt, const Tilemap *map) {
|
|||||||
/* Also despawn if far below level */
|
/* Also despawn if far below level */
|
||||||
float level_bottom = (float)(map->height * TILE_SIZE) + 32.0f;
|
float level_bottom = (float)(map->height * TILE_SIZE) + 32.0f;
|
||||||
if (hit_ground || self->body.pos.y > level_bottom) {
|
if (hit_ground || self->body.pos.y > level_bottom) {
|
||||||
/* Impact effect */
|
|
||||||
Vec2 impact_pos = vec2(
|
Vec2 impact_pos = vec2(
|
||||||
self->body.pos.x + self->body.size.x * 0.5f,
|
self->body.pos.x + self->body.size.x * 0.5f,
|
||||||
self->body.pos.y + self->body.size.y
|
self->body.pos.y + self->body.size.y
|
||||||
);
|
);
|
||||||
particle_emit_death_puff(impact_pos, (SDL_Color){140, 110, 80, 255});
|
|
||||||
|
/* Rock shrapnel — fast chunks flying outward */
|
||||||
|
ParticleBurst shrapnel = {
|
||||||
|
.origin = impact_pos,
|
||||||
|
.count = 16,
|
||||||
|
.speed_min = 80.0f,
|
||||||
|
.speed_max = 220.0f,
|
||||||
|
.life_min = 0.3f,
|
||||||
|
.life_max = 0.7f,
|
||||||
|
.size_min = 1.5f,
|
||||||
|
.size_max = 3.5f,
|
||||||
|
.spread = (float)M_PI,
|
||||||
|
.direction = 0,
|
||||||
|
.drag = 1.5f,
|
||||||
|
.gravity_scale = 0.5f,
|
||||||
|
.color = {140, 140, 145, 255},
|
||||||
|
.color_vary = true,
|
||||||
|
};
|
||||||
|
particle_emit(&shrapnel);
|
||||||
|
|
||||||
|
/* Dust plume — big, slow, billowing upward */
|
||||||
|
ParticleBurst dust_plume = {
|
||||||
|
.origin = impact_pos,
|
||||||
|
.count = 14,
|
||||||
|
.speed_min = 30.0f,
|
||||||
|
.speed_max = 80.0f,
|
||||||
|
.life_min = 0.4f,
|
||||||
|
.life_max = 0.9f,
|
||||||
|
.size_min = 2.5f,
|
||||||
|
.size_max = 5.0f,
|
||||||
|
.spread = 1.2f,
|
||||||
|
.direction = -(float)M_PI / 2.0f, /* upward */
|
||||||
|
.drag = 3.0f,
|
||||||
|
.gravity_scale = -0.1f,
|
||||||
|
.color = {120, 120, 125, 160},
|
||||||
|
.color_vary = true,
|
||||||
|
};
|
||||||
|
particle_emit(&dust_plume);
|
||||||
|
|
||||||
|
/* Ground-level dust spread — hugs the surface */
|
||||||
|
ParticleBurst ground_dust = {
|
||||||
|
.origin = impact_pos,
|
||||||
|
.count = 10,
|
||||||
|
.speed_min = 40.0f,
|
||||||
|
.speed_max = 120.0f,
|
||||||
|
.life_min = 0.3f,
|
||||||
|
.life_max = 0.6f,
|
||||||
|
.size_min = 2.0f,
|
||||||
|
.size_max = 3.5f,
|
||||||
|
.spread = 0.3f,
|
||||||
|
.direction = (float)M_PI, /* leftward half */
|
||||||
|
.drag = 3.5f,
|
||||||
|
.gravity_scale = 0.0f,
|
||||||
|
.color = {150, 150, 155, 140},
|
||||||
|
.color_vary = true,
|
||||||
|
};
|
||||||
|
particle_emit(&ground_dust);
|
||||||
|
ground_dust.direction = 0; /* rightward half */
|
||||||
|
particle_emit(&ground_dust);
|
||||||
|
|
||||||
|
/* Bright flash — brief white pop at impact point */
|
||||||
|
ParticleBurst flash = {
|
||||||
|
.origin = impact_pos,
|
||||||
|
.count = 4,
|
||||||
|
.speed_min = 5.0f,
|
||||||
|
.speed_max = 15.0f,
|
||||||
|
.life_min = 0.04f,
|
||||||
|
.life_max = 0.08f,
|
||||||
|
.size_min = 3.0f,
|
||||||
|
.size_max = 5.0f,
|
||||||
|
.spread = (float)M_PI,
|
||||||
|
.direction = 0,
|
||||||
|
.drag = 8.0f,
|
||||||
|
.gravity_scale = 0.0f,
|
||||||
|
.color = {220, 220, 230, 255},
|
||||||
|
.color_vary = false,
|
||||||
|
};
|
||||||
|
particle_emit(&flash);
|
||||||
|
|
||||||
if (s_asteroid_sfx_loaded) {
|
if (s_asteroid_sfx_loaded) {
|
||||||
audio_play_sound_at(s_sfx_asteroid_impact, 60, impact_pos, 0);
|
audio_play_sound_at(s_sfx_asteroid_impact, 60, impact_pos, 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user