animated tileset
This commit is contained in:
parent
5d6b313d96
commit
3c3883b076
|
@ -460,14 +460,64 @@ def convert_tiled_tileset(input, output, params):
|
|||
|
||||
tilewidth = int(tileset.attrib["tilewidth"])
|
||||
tileheight = int(tileset.attrib["tileheight"])
|
||||
tilecount = int(tileset.attrib["tilecount"])
|
||||
|
||||
# In Rogue Life there is only 16x16 :)
|
||||
assert tilewidth == 16 and tileheight == 16
|
||||
|
||||
# Current we just convert the image, but we could do more later (especially
|
||||
# if this converter gets reused in other projects)
|
||||
def plane_id(plane_str):
|
||||
return ["WALL", "FLOOR", "CEILING"].index(plane_str)
|
||||
|
||||
o = fxconv.Structure()
|
||||
info = fxconv.Structure()
|
||||
frames = fxconv.Structure()
|
||||
frames_start = 0
|
||||
|
||||
# Tile sheet
|
||||
source = os.path.join(os.path.dirname(input), image.attrib["source"])
|
||||
return fxconv.convert_bopti_cg(source, params)
|
||||
sheet = Image.open(source)
|
||||
o += fxconv.u32(sheet.width // 16)
|
||||
o += fxconv.u32(sheet.height // 16)
|
||||
o += fxconv.ptr(fxconv.convert_bopti_cg(sheet, params))
|
||||
|
||||
# Analyze tile metadata and animation
|
||||
for i in range(tilecount):
|
||||
tile = tileset.findall(f".//tile[@id='{i}']")
|
||||
assert len(tile) in [0,1]
|
||||
|
||||
plane = "FLOOR"
|
||||
anim_length = 0
|
||||
anim_start = frames_start
|
||||
solid = 0
|
||||
|
||||
if tile:
|
||||
for prop in tile[0].findall("./properties/property"):
|
||||
name = prop.attrib["name"]
|
||||
type = prop.attrib.get("type", "string")
|
||||
value = prop.attrib["value"]
|
||||
|
||||
if name == "plane" and type == "string":
|
||||
plane = value
|
||||
elif name == "solid" and type == "bool":
|
||||
solid = int(value == "true")
|
||||
else:
|
||||
raise fxconv.FxconvError(
|
||||
f"Unknown tile property '{name}' with type '{type}'")
|
||||
|
||||
for frame in tile[0].findall("./animation/frame"):
|
||||
frames += fxconv.u16(int(frame.attrib["tileid"]))
|
||||
frames += fxconv.u16(int(frame.attrib["duration"]))
|
||||
frames_start += 1
|
||||
anim_length += 1
|
||||
|
||||
info += fxconv.u8(plane_id(plane))
|
||||
info += fxconv.u8(anim_length)
|
||||
info += fxconv.u8(anim_start)
|
||||
info += fxconv.u8(solid)
|
||||
|
||||
o += fxconv.ptr(info)
|
||||
o += fxconv.ptr(frames)
|
||||
return o
|
||||
|
||||
def convert_tiled_map(input, output, params):
|
||||
tree = xml.etree.ElementTree.parse(input)
|
||||
|
@ -495,51 +545,16 @@ def convert_tiled_map(input, output, params):
|
|||
assert len(data1) == width * height
|
||||
assert len(data2) == width * height
|
||||
|
||||
#---
|
||||
|
||||
tileset = xml.etree.ElementTree.parse(
|
||||
os.path.join(os.path.dirname(input), tileset.attrib["source"]))
|
||||
tileprops = dict()
|
||||
for tile in tileset.findall("tile"):
|
||||
tile_id = int(tile.attrib["id"])
|
||||
p = dict()
|
||||
for prop in tile.find("properties").findall("property"):
|
||||
name = prop.attrib["name"]
|
||||
type = prop.attrib.get("type", "string")
|
||||
value = prop.attrib["value"]
|
||||
|
||||
if type == "bool":
|
||||
value = (value == "true")
|
||||
elif type == "float":
|
||||
value = float(value)
|
||||
elif type == "file":
|
||||
pass
|
||||
elif type == "int":
|
||||
value = int(value)
|
||||
elif type == "string":
|
||||
pass
|
||||
else: # including "color" and "object"
|
||||
raise Exception(f"unknown tile property type {type}")
|
||||
p[name] = value
|
||||
tileprops[tile_id] = p
|
||||
|
||||
#---
|
||||
|
||||
tiles = bytes()
|
||||
for i in range(width * height):
|
||||
t1 = data1[i] & 0x0fffffff
|
||||
t2 = data2[i] & 0x0fffffff
|
||||
# We expect tileset index 0 to be empty
|
||||
# We turn empty tiles into index 0
|
||||
t1 = 0 if t1 < tileset_base else t1 - tileset_base
|
||||
t2 = 0 if t2 < tileset_base else t2 - tileset_base
|
||||
|
||||
solid = 0
|
||||
plane = "FLOOR"
|
||||
if t1 in tileprops:
|
||||
solid = (tileprops[t1].get("solid", False) == True)
|
||||
plane = tileprops[t1].get("plane", "FLOOR")
|
||||
plane = ["WALL", "FLOOR", "CEILING"].index(plane)
|
||||
tiles += bytes([solid, plane, t1, t2])
|
||||
tiles += fxconv.u8(t1)
|
||||
tiles += fxconv.u8(t2)
|
||||
|
||||
o = fxconv.Structure()
|
||||
o += fxconv.u16(width)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<map version="1.5" tiledversion="1.7.2" orientation="orthogonal" renderorder="right-down" width="24" height="11" tilewidth="16" tileheight="16" infinite="0" nextlayerid="5" nextobjectid="1">
|
||||
<map version="1.8" tiledversion="1.8.0" orientation="orthogonal" renderorder="right-down" width="24" height="11" tilewidth="16" tileheight="16" infinite="0" nextlayerid="5" nextobjectid="1">
|
||||
<tileset firstgid="1" source="../tilesets/cavern.tsx"/>
|
||||
<layer id="4" name="Ground" width="24" height="11">
|
||||
<data encoding="csv">
|
||||
|
@ -23,9 +23,9 @@
|
|||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0,10,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,0,0,
|
||||
0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,11,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,20,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
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,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.5" tiledversion="1.7.2" name="cavern" tilewidth="16" tileheight="16" tilecount="16" columns="8">
|
||||
<image source="cavern.png" width="128" height="32"/>
|
||||
<tileset version="1.8" tiledversion="1.8.0" name="cavern" tilewidth="16" tileheight="16" tilecount="24" columns="8">
|
||||
<image source="cavern.png" width="128" height="48"/>
|
||||
<tile id="1">
|
||||
<properties>
|
||||
<property name="plane" value="CEILING"/>
|
||||
|
@ -23,22 +23,54 @@
|
|||
<properties>
|
||||
<property name="plane" value="WALL"/>
|
||||
</properties>
|
||||
<animation>
|
||||
<frame tileid="8" duration="3000"/>
|
||||
<frame tileid="16" duration="100"/>
|
||||
<frame tileid="17" duration="100"/>
|
||||
<frame tileid="18" duration="100"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="9">
|
||||
<properties>
|
||||
<property name="plane" value="WALL"/>
|
||||
</properties>
|
||||
<animation>
|
||||
<frame tileid="9" duration="300"/>
|
||||
<frame tileid="10" duration="300"/>
|
||||
<frame tileid="11" duration="300"/>
|
||||
<frame tileid="12" duration="300"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="14">
|
||||
<properties>
|
||||
<property name="plane" value="WALL"/>
|
||||
<property name="solid" type="bool" value="true"/>
|
||||
</properties>
|
||||
<animation>
|
||||
<frame tileid="14" duration="3000"/>
|
||||
<frame tileid="22" duration="300"/>
|
||||
<frame tileid="14" duration="70"/>
|
||||
<frame tileid="22" duration="70"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="15">
|
||||
<properties>
|
||||
<property name="plane" value="WALL"/>
|
||||
<property name="solid" type="bool" value="true"/>
|
||||
</properties>
|
||||
<animation>
|
||||
<frame tileid="15" duration="3000"/>
|
||||
<frame tileid="23" duration="300"/>
|
||||
<frame tileid="15" duration="70"/>
|
||||
<frame tileid="23" duration="70"/>
|
||||
</animation>
|
||||
</tile>
|
||||
<tile id="19">
|
||||
<animation>
|
||||
<frame tileid="19" duration="1000"/>
|
||||
<frame tileid="20" duration="1000"/>
|
||||
<frame tileid="21" duration="1000"/>
|
||||
<frame tileid="20" duration="1000"/>
|
||||
</animation>
|
||||
</tile>
|
||||
</tileset>
|
||||
|
|
10
src/game.c
10
src/game.c
|
@ -20,6 +20,11 @@ bool game_load(game_t *g, level_t const *level)
|
|||
g->map = level->map;
|
||||
g->occupation = malloc(g->map->width * g->map->height *
|
||||
sizeof *g->occupation);
|
||||
g->map_anim = malloc(g->map->width * g->map->height *
|
||||
sizeof *g->map_anim);
|
||||
|
||||
for(int i = 0; i < g->map->width * g->map->height; i++)
|
||||
g->map_anim[i] = rand() & 4095;
|
||||
|
||||
camera_init(&g->camera, g->map);
|
||||
|
||||
|
@ -46,6 +51,8 @@ void game_unload(game_t *g)
|
|||
g->map = NULL;
|
||||
free(g->occupation);
|
||||
g->occupation = NULL;
|
||||
free(g->map_anim);
|
||||
g->map_anim = NULL;
|
||||
|
||||
for(int i = 0; i < g->entity_count; i++)
|
||||
entity_destroy(g->entities[i]);
|
||||
|
@ -373,6 +380,9 @@ void game_update_animations(game_t *g, fixed_t dt)
|
|||
visible_update(e, dt);
|
||||
}
|
||||
|
||||
for(int i = 0; i < g->map->width * g->map->height; i++)
|
||||
g->map_anim[i] += fround(dt * 1000);
|
||||
|
||||
anim_state_update(&g->hud_xp_anim, dt);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,8 +19,13 @@ typedef struct game {
|
|||
map_t const *map;
|
||||
/* Number of entities currently on each cell of the map */
|
||||
uint8_t *occupation;
|
||||
/* Position of each map cell in its animation cycle, in ms. Cells have
|
||||
random offsets so animations are not all synchronized. We ignore the
|
||||
wrapping effect entirely. */
|
||||
uint16_t *map_anim;
|
||||
/* User's camera */
|
||||
camera_t camera;
|
||||
|
||||
/* Time played */
|
||||
fixed_t time_total;
|
||||
/* Time when victory was reached or defeat was dealt */
|
||||
|
|
29
src/map.c
29
src/map.c
|
@ -1,9 +1,10 @@
|
|||
#include "map.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
rect tile_shape(tile_t const *tile)
|
||||
rect tile_shape(tileset_t const *tileset, int id)
|
||||
{
|
||||
if(!tile->solid) return (rect){ 0 };
|
||||
if(!tileset->tiles[id].solid)
|
||||
return (rect){ 0 };
|
||||
|
||||
return (rect){
|
||||
.l = -fix(0.5),
|
||||
|
@ -13,12 +14,12 @@ rect tile_shape(tile_t const *tile)
|
|||
};
|
||||
}
|
||||
|
||||
tile_t *map_tile(map_t const *m, int x, int y)
|
||||
map_cell_t *map_cell(map_t const *m, int x, int y)
|
||||
{
|
||||
if((unsigned)x >= m->width || (unsigned)y >= m->height)
|
||||
return NULL;
|
||||
|
||||
return &m->tiles[y * m->width + x];
|
||||
return &m->cells[y * m->width + x];
|
||||
}
|
||||
|
||||
bool map_collides(map_t const *m, rect hitbox)
|
||||
|
@ -31,14 +32,22 @@ bool map_collides(map_t const *m, rect hitbox)
|
|||
/* Collisions against walls and static objects */
|
||||
for(int y = y_min; y < y_max; y++)
|
||||
for(int x = x_min; x < x_max; x++) {
|
||||
tile_t *t = map_tile(m, x, y);
|
||||
if(!t || !t->solid) continue;
|
||||
map_cell_t *t = map_cell(m, x, y);
|
||||
if(!t) continue;
|
||||
|
||||
vec2 center = { fix(x) + fix(0.5), fix(y) + fix(0.5) };
|
||||
rect tile_hitbox = rect_translate(tile_shape(t), center);
|
||||
vec2 c = { fix(x) + fix(0.5), fix(y) + fix(0.5) };
|
||||
rect tile_hitbox;
|
||||
|
||||
if(rect_collide(hitbox, tile_hitbox))
|
||||
return true;
|
||||
if(m->tileset->tiles[t->base].solid) {
|
||||
tile_hitbox = rect_translate(tile_shape(m->tileset, t->base), c);
|
||||
if(rect_collide(hitbox, tile_hitbox))
|
||||
return true;
|
||||
}
|
||||
if(m->tileset->tiles[t->decor].solid) {
|
||||
tile_hitbox = rect_translate(tile_shape(m->tileset, t->decor), c);
|
||||
if(rect_collide(hitbox, tile_hitbox))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
69
src/map.h
69
src/map.h
|
@ -18,28 +18,65 @@
|
|||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
//---
|
||||
// Tileset
|
||||
//---
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Rendering plane */
|
||||
uint8_t plane;
|
||||
/* Length of animation cycle. This is only defined for the first tile of
|
||||
each cycle, because the cycle can use the same tile several times. If
|
||||
anim_length=0 there is no animation; anim_length=1 is useless. */
|
||||
uint8_t anim_length;
|
||||
/* Index in the tileset's animation array where this tile's animation cycle
|
||||
starts; it spans the range [anim_start .. anim_start+anim_length). */
|
||||
uint8_t anim_start;
|
||||
/* Hitbox. TODO: Allow any collision rectangle for tiles, for decor */
|
||||
bool solid;
|
||||
|
||||
} tile_info_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* ID of the tile visible during this frame */
|
||||
uint16_t tile_id;
|
||||
/* Duration before next frame, in ms */
|
||||
uint16_t duration_ms;
|
||||
|
||||
} tile_animation_frame_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int width, height;
|
||||
bopti_image_t const *sheet;
|
||||
|
||||
/* Tile information */
|
||||
tile_info_t *tiles;
|
||||
|
||||
/* Animations */
|
||||
tile_animation_frame_t *anim;
|
||||
|
||||
} tileset_t;
|
||||
|
||||
/* Shape for a tile; this lives in a coordinate system whose (0,0) ends up at
|
||||
the middle of the tile in the map space (which is a point with half-integer
|
||||
coordinates) */
|
||||
rect tile_shape(tileset_t const *tileset, int id);
|
||||
|
||||
//---
|
||||
// Tiles
|
||||
//---
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* TODO: Layers of objects, stuff, dynamic elements, etc? */
|
||||
/* TODO: Allow any collision shape for the tile! */
|
||||
bool solid;
|
||||
/* Rendering plane for that tile */
|
||||
uint8_t plane;
|
||||
/* Base layer: floor/wall pattern */
|
||||
uint8_t base;
|
||||
/* Decoration layer */
|
||||
uint8_t decor;
|
||||
|
||||
} tile_t;
|
||||
|
||||
/* Shape for a tile; this lives in a coordinate system whose (0,0) ends up at
|
||||
the middle of the tile in the map space (which is a point with half-integer
|
||||
coordinates) */
|
||||
rect tile_shape(tile_t const *tile);
|
||||
} map_cell_t;
|
||||
|
||||
//---
|
||||
// Map grid, tiles location in space, and entities
|
||||
|
@ -50,14 +87,14 @@ typedef struct
|
|||
/* Dimensions, columns are 0 to width-1, rows are 0 to height-1 */
|
||||
uint16_t width, height;
|
||||
/* Tileset base (first layer), tileset decor (second layer) */
|
||||
bopti_image_t *tileset;
|
||||
/* All tiles */
|
||||
tile_t *tiles;
|
||||
tileset_t *tileset;
|
||||
/* All cells */
|
||||
map_cell_t *cells;
|
||||
|
||||
} map_t;
|
||||
|
||||
/* Get a pointer to the tile at (x,y) in map; NULL if out of bounds. */
|
||||
tile_t *map_tile(map_t const *m, int x, int y);
|
||||
/* Get a pointer to the cell at (x,y) in map; NULL if out of bounds. */
|
||||
map_cell_t *map_cell(map_t const *m, int x, int y);
|
||||
|
||||
/* Check whether a hitbox collides with the map. */
|
||||
bool map_collides(map_t const *m, rect hitbox);
|
||||
|
|
|
@ -77,8 +77,13 @@ pfg_all2one_t pfg_dijkstra(map_t const *map, ivec2 center, uint8_t *occupation)
|
|||
int dx = dx_array[dir];
|
||||
int dy = dy_array[dir];
|
||||
|
||||
tile_t *tile = map_tile(map, point.x+dx, point.y+dy);
|
||||
if(!tile || tile->solid) continue;
|
||||
map_cell_t *cell = map_cell(map, point.x+dx, point.y+dy);
|
||||
if(!cell) continue;
|
||||
|
||||
if(map->tileset->tiles[cell->base].solid)
|
||||
continue;
|
||||
if(cell->decor && map->tileset->tiles[cell->decor].solid)
|
||||
continue;
|
||||
|
||||
int next_i = idx(point.x+dx, point.y+dy);
|
||||
int occ = occupation ? occupation[next_i] : 0;
|
||||
|
@ -170,8 +175,14 @@ bool raycast_clear(map_t const *map, vec2 start, vec2 end)
|
|||
perfectly) */
|
||||
int current_x = ffloor(x-(u.x < 0));
|
||||
int current_y = ffloor(y-(u.y < 0));
|
||||
tile_t *tile = map_tile(map, current_x, current_y);
|
||||
if(tile && tile->solid) return false;
|
||||
|
||||
map_cell_t *cell = map_cell(map, current_x, current_y);
|
||||
if(!cell)
|
||||
return false;
|
||||
if(map->tileset->tiles[cell->base].solid)
|
||||
return false;
|
||||
if(cell->decor && map->tileset->tiles[cell->decor].solid)
|
||||
return false;
|
||||
|
||||
/* Distance to the next horizontal, and vertical line */
|
||||
fixed_t dist_y = (u.y >= 0) ? fix(1) - fdec(y) : -(fdec(y-1) + 1);
|
||||
|
@ -196,8 +207,13 @@ bool raycast_clear(map_t const *map, vec2 start, vec2 end)
|
|||
}
|
||||
|
||||
if(t > fix(1)) break;
|
||||
tile = map_tile(map, next_x, next_y);
|
||||
if(tile && tile->solid) return false;
|
||||
cell = map_cell(map, next_x, next_y);
|
||||
if(!cell)
|
||||
return false;
|
||||
if(map->tileset->tiles[cell->base].solid)
|
||||
return false;
|
||||
if(cell->decor && map->tileset->tiles[cell->decor].solid)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
72
src/render.c
72
src/render.c
|
@ -122,31 +122,60 @@ fixed_t camera_ppu(camera_t const *c)
|
|||
// Rendering
|
||||
//---
|
||||
|
||||
static void render_map_layer(map_t const *m, camera_t const *c, int ss_x,
|
||||
static inline void render_tile(int x, int y, tileset_t const *tileset,
|
||||
int tile_id, int time_ms)
|
||||
{
|
||||
/* If the tile is animated, find the position in the cycle */
|
||||
if(tileset->tiles[tile_id].anim_length > 0) {
|
||||
int start = tileset->tiles[tile_id].anim_start;
|
||||
tile_animation_frame_t *frames = &tileset->anim[start];
|
||||
|
||||
int cycle_duration_ms = 0;
|
||||
for(int i = 0; i < tileset->tiles[tile_id].anim_length; i++)
|
||||
cycle_duration_ms += frames[i].duration_ms;
|
||||
|
||||
time_ms %= cycle_duration_ms;
|
||||
int i = 0;
|
||||
while(time_ms >= 0) {
|
||||
time_ms -= frames[i].duration_ms;
|
||||
i++;
|
||||
}
|
||||
|
||||
tile_id = frames[i-1].tile_id;
|
||||
}
|
||||
|
||||
dsubimage(x, y, tileset->sheet,
|
||||
TILE_WIDTH * (tile_id % tileset->width),
|
||||
TILE_HEIGHT * (tile_id / tileset->width),
|
||||
TILE_WIDTH, TILE_HEIGHT, DIMAGE_NOCLIP);
|
||||
}
|
||||
|
||||
static void render_map_layer(game_t const *game, camera_t const *c, int ss_x,
|
||||
int ss_y, int layer)
|
||||
{
|
||||
map_t const *map = game->map;
|
||||
|
||||
/* Render floor and walls */
|
||||
for(int row = -2; row < m->height + 2; row++)
|
||||
for(int col = -1; col < m->width + 1; col++) {
|
||||
tile_t *t = map_tile(m, col, row);
|
||||
for(int row = -2; row < map->height + 2; row++)
|
||||
for(int col = -1; col < map->width + 1; col++) {
|
||||
map_cell_t *cell = map_cell(map, col, row);
|
||||
vec2 tile_pos = { fix(col), fix(row) };
|
||||
ivec2 p = camera_map2screen(c, tile_pos);
|
||||
p.x += ss_x;
|
||||
p.y += ss_y;
|
||||
|
||||
if(!t && layer == CEILING) {
|
||||
drect(p.x, p.y, p.x+15, p.y+15, C_BLACK);
|
||||
if(!cell) {
|
||||
if(layer == CEILING)
|
||||
drect(p.x, p.y, p.x+15, p.y+15, C_BLACK);
|
||||
continue;
|
||||
}
|
||||
if(t->plane != layer)
|
||||
continue;
|
||||
|
||||
dsubimage(p.x, p.y, m->tileset,
|
||||
TILE_WIDTH * (t->base % 8), TILE_HEIGHT * (t->base / 8),
|
||||
TILE_WIDTH, TILE_HEIGHT, DIMAGE_NOCLIP);
|
||||
if(t->decor) dsubimage(p.x, p.y, m->tileset,
|
||||
TILE_WIDTH * (t->decor % 8), TILE_HEIGHT * (t->decor / 8),
|
||||
TILE_WIDTH, TILE_HEIGHT, DIMAGE_NOCLIP);
|
||||
int time_ms = game->map_anim[map->width * row + col];
|
||||
|
||||
if(map->tileset->tiles[cell->base].plane == layer)
|
||||
render_tile(p.x, p.y, map->tileset, cell->base, time_ms);
|
||||
if(cell->decor && map->tileset->tiles[cell->decor].plane == layer)
|
||||
render_tile(p.x, p.y, map->tileset, cell->decor, time_ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,16 +397,16 @@ void render_game(game_t const *g, bool show_hitboxes)
|
|||
prof_enter(ctx);
|
||||
|
||||
/* Render map floor and floor entities */
|
||||
render_map_layer(g->map, camera, ss_x, ss_y, HORIZONTAL);
|
||||
render_map_layer(g, camera, ss_x, ss_y, HORIZONTAL);
|
||||
render_entities(g, camera, floor_depth_measure, ss_x, ss_y, show_hitboxes);
|
||||
|
||||
/* Render map walls and vertical entities
|
||||
TODO ECS: Sort walls and wall entities together for proper ordering!*/
|
||||
render_map_layer(g->map, camera, ss_x, ss_y, VERTICAL);
|
||||
render_map_layer(g, camera, ss_x, ss_y, VERTICAL);
|
||||
render_entities(g, camera, wall_depth_measure, ss_x, ss_y, show_hitboxes);
|
||||
|
||||
/* Render ceiling tiles (including out of bounds) and ceiling entities */
|
||||
render_map_layer(g->map, camera, ss_x, ss_y, CEILING);
|
||||
render_map_layer(g, camera, ss_x, ss_y, CEILING);
|
||||
render_entities(g, camera, ceiling_depth_measure, ss_x,ss_y,show_hitboxes);
|
||||
|
||||
prof_leave(ctx);
|
||||
|
@ -470,8 +499,13 @@ void render_pfg_all2one(pfg_all2one_t const *paths, camera_t const *c,
|
|||
{
|
||||
for(int row = 0; row < paths->map->height; row++)
|
||||
for(int col = 0; col < paths->map->width; col++) {
|
||||
tile_t *tile = map_tile(paths->map, col, row);
|
||||
if(!tile || tile->solid) continue;
|
||||
map_cell_t *cell = map_cell(paths->map, col, row);
|
||||
if(!cell)
|
||||
continue;
|
||||
if(paths->map->tileset->tiles[cell->base].solid)
|
||||
continue;
|
||||
if(cell->decor && paths->map->tileset->tiles[cell->decor].solid)
|
||||
continue;
|
||||
|
||||
vec2 fp = vec_i2f_center((ivec2){ col, row });
|
||||
ivec2 p = camera_map2screen(c, fp);
|
||||
|
|
Loading…
Reference in New Issue