forked from tas/major_tom
Add Earth sprite to moon parallax background
Render earth.png as a non-tiling feature sprite in the moon sky, drawn between the far starfield and near crater terrain layers. Introduce ParallaxFeature struct for single-instance background sprites that scroll with the camera but never tile. Clean up the feature reference in parallax_free to prevent stale pointers between level transitions.
This commit is contained in:
BIN
assets/sprites/earth.png
Normal file
BIN
assets/sprites/earth.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
@@ -1,4 +1,5 @@
|
||||
#include "engine/parallax.h"
|
||||
#include "engine/assets.h"
|
||||
#include "engine/camera.h"
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
@@ -795,6 +796,21 @@ static void generate_moon_far(Parallax *p, SDL_Renderer *renderer) {
|
||||
p->far_layer.scroll_y = 0.03f;
|
||||
p->far_layer.active = true;
|
||||
p->far_layer.owns_texture = true;
|
||||
|
||||
/* Earth in the sky — non-tiling feature sprite */
|
||||
SDL_Texture *earth_tex = assets_get_texture("assets/sprites/earth.png");
|
||||
if (earth_tex) {
|
||||
int ew, eh;
|
||||
SDL_QueryTexture(earth_tex, NULL, NULL, &ew, &eh);
|
||||
p->feature.texture = earth_tex;
|
||||
p->feature.tex_w = ew;
|
||||
p->feature.tex_h = eh;
|
||||
p->feature.x = (float)(w / 4);
|
||||
p->feature.y = (float)(h * 0.08f);
|
||||
p->feature.scroll_x = 0.03f; /* same as far layer */
|
||||
p->feature.scroll_y = 0.03f;
|
||||
p->feature.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void generate_moon_near(Parallax *p, SDL_Renderer *renderer) {
|
||||
@@ -953,9 +969,25 @@ static void render_layer(const ParallaxLayer *layer, const Camera *cam,
|
||||
}
|
||||
}
|
||||
|
||||
static void render_feature(const ParallaxFeature *f, const Camera *cam,
|
||||
SDL_Renderer *renderer) {
|
||||
if (!f->active || !f->texture) return;
|
||||
|
||||
/* Scroll with camera but do not tile */
|
||||
int draw_x = (int)(f->x - cam->pos.x * f->scroll_x);
|
||||
int draw_y = (int)(f->y - cam->pos.y * f->scroll_y);
|
||||
|
||||
SDL_Rect dst = {draw_x, draw_y, f->tex_w, f->tex_h};
|
||||
if (dst.x + dst.w < 0 || dst.x >= SCREEN_WIDTH) return;
|
||||
if (dst.y + dst.h < 0 || dst.y >= SCREEN_HEIGHT) return;
|
||||
|
||||
SDL_RenderCopy(renderer, f->texture, NULL, &dst);
|
||||
}
|
||||
|
||||
void parallax_render(const Parallax *p, const Camera *cam, SDL_Renderer *renderer) {
|
||||
if (!p || !cam) return;
|
||||
render_layer(&p->far_layer, cam, renderer);
|
||||
render_feature(&p->feature, cam, renderer);
|
||||
render_layer(&p->near_layer, cam, renderer);
|
||||
}
|
||||
|
||||
@@ -974,4 +1006,8 @@ void parallax_free(Parallax *p) {
|
||||
}
|
||||
p->near_layer.texture = NULL;
|
||||
p->near_layer.active = false;
|
||||
|
||||
/* Feature sprite is asset-manager-owned — just clear the reference */
|
||||
p->feature.texture = NULL;
|
||||
p->feature.active = false;
|
||||
}
|
||||
|
||||
@@ -18,10 +18,21 @@ typedef struct ParallaxLayer {
|
||||
bool owns_texture; /* true if we generated it (must free) */
|
||||
} ParallaxLayer;
|
||||
|
||||
/* Parallax background system — up to two layers */
|
||||
/* A non-tiling sprite drawn once in the background (e.g. Earth from moon) */
|
||||
typedef struct ParallaxFeature {
|
||||
SDL_Texture *texture; /* sprite image */
|
||||
int tex_w, tex_h; /* sprite dimensions */
|
||||
float x, y; /* base position (pixels, screen) */
|
||||
float scroll_x; /* horizontal scroll factor */
|
||||
float scroll_y; /* vertical scroll factor */
|
||||
bool active;
|
||||
} ParallaxFeature;
|
||||
|
||||
/* Parallax background system — two tiling layers + optional feature sprite */
|
||||
typedef struct Parallax {
|
||||
ParallaxLayer far_layer; /* distant background (stars) */
|
||||
ParallaxLayer near_layer; /* mid-ground background (nebula) */
|
||||
ParallaxFeature feature; /* non-tiling overlay (planet, etc.) */
|
||||
} Parallax;
|
||||
|
||||
/* Initialize parallax (zeroes everything) */
|
||||
|
||||
Reference in New Issue
Block a user