forked from tas/major_tom
Introduce moon01.lvl as the starting level — a pure jump-and-run intro with no gun and no enemies, just platforming over gaps and dodging falling asteroids. The player picks up their gun upon transitioning to level01. New features: - Moon tileset and PARALLAX_STYLE_MOON with crater terrain backgrounds - Asteroid entity (ENT_ASTEROID): falls from sky, damages on contact, explodes on ground with particles, respawns after delay - PLAYER_UNARMED directive disables gun for the level - Pit rescue mechanic: falling costs 1 HP and auto-dashes upward - Gun powerup entity type for future armed-pickup levels - Segment-based procedural level generator with themed rooms - Extended editor with entity palette and improved tile cycling - Web shell improvements for Emscripten builds
82 lines
3.2 KiB
C
82 lines
3.2 KiB
C
#ifndef JNR_TILEMAP_H
|
|
#define JNR_TILEMAP_H
|
|
|
|
#include <SDL2/SDL.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <math.h>
|
|
#include "config.h"
|
|
#include "util/vec2.h"
|
|
|
|
/* Forward declarations */
|
|
typedef struct Camera Camera;
|
|
|
|
typedef enum TileFlag {
|
|
TILE_SOLID = 1 << 0,
|
|
TILE_PLATFORM = 1 << 1, /* one-way, passable from below */
|
|
TILE_LADDER = 1 << 2,
|
|
TILE_HAZARD = 1 << 3, /* spikes, lava, etc. */
|
|
TILE_WATER = 1 << 4,
|
|
} TileFlag;
|
|
|
|
typedef struct TileDef {
|
|
uint16_t tex_x, tex_y; /* position in tileset (in tiles) */
|
|
uint32_t flags;
|
|
} TileDef;
|
|
|
|
/* Entity spawn entry read from .lvl files */
|
|
typedef struct EntitySpawn {
|
|
char type_name[32]; /* e.g. "grunt", "flyer" */
|
|
float x, y; /* world position (pixels) */
|
|
} EntitySpawn;
|
|
|
|
/* Exit zone — triggers level transition on player overlap */
|
|
typedef struct ExitZone {
|
|
float x, y, w, h; /* world-space bounding box */
|
|
char target[ASSET_PATH_MAX]; /* path to next level, or
|
|
* "generate" for procgen,
|
|
* or empty for "you win" */
|
|
} ExitZone;
|
|
|
|
typedef struct Tilemap {
|
|
int width, height; /* map size in tiles */
|
|
uint16_t *bg_layer; /* background tile IDs */
|
|
uint16_t *collision_layer; /* solid geometry tile IDs */
|
|
uint16_t *fg_layer; /* foreground decoration IDs */
|
|
TileDef tile_defs[MAX_TILE_DEFS];
|
|
int tile_def_count;
|
|
SDL_Texture *tileset;
|
|
int tileset_cols; /* columns in tileset image */
|
|
Vec2 player_spawn;
|
|
float gravity; /* level gravity (px/s^2), 0 = use default */
|
|
char music_path[ASSET_PATH_MAX]; /* level music file path */
|
|
SDL_Color bg_color; /* background clear color */
|
|
bool has_bg_color; /* true if BG_COLOR was set */
|
|
char parallax_far_path[ASSET_PATH_MAX]; /* far bg image path */
|
|
char parallax_near_path[ASSET_PATH_MAX]; /* near bg image path */
|
|
int parallax_style; /* procedural bg style (0=default) */
|
|
bool player_unarmed; /* if true, player starts without gun */
|
|
EntitySpawn entity_spawns[MAX_ENTITY_SPAWNS];
|
|
int entity_spawn_count;
|
|
ExitZone exit_zones[MAX_EXIT_ZONES];
|
|
int exit_zone_count;
|
|
} Tilemap;
|
|
|
|
bool tilemap_load(Tilemap *map, const char *path, SDL_Renderer *renderer);
|
|
void tilemap_render_layer(const Tilemap *map, const uint16_t *layer,
|
|
const Camera *cam, SDL_Renderer *renderer);
|
|
bool tilemap_is_solid(const Tilemap *map, int tile_x, int tile_y);
|
|
uint32_t tilemap_flags_at(const Tilemap *map, int tile_x, int tile_y);
|
|
void tilemap_free(Tilemap *map);
|
|
|
|
/* World-pixel to tile coordinate helpers */
|
|
static inline int world_to_tile(float world_coord) {
|
|
return (int)floorf(world_coord / TILE_SIZE);
|
|
}
|
|
|
|
static inline float tile_to_world(int tile_coord) {
|
|
return (float)(tile_coord * TILE_SIZE);
|
|
}
|
|
|
|
#endif /* JNR_TILEMAP_H */
|