Add collider map

This commit is contained in:
2023-11-09 09:32:02 +01:00
parent fa79af2a17
commit 913a365a21
3 changed files with 90 additions and 5 deletions

View File

@@ -61,13 +61,41 @@ static void handleTileObjectLayer(BzTileObjectLayer *layer, cute_tiled_layer_t *
}
static i32 findSlot(const char *name, const BzTileLayerDesc desc[BZ_MAX_MAP_LAYERS]) {
for (i32 i = 0; i < BZ_MAX_MAP_LAYERS; i++) {
if (!desc[i].name) break;
if (strcmp(name, desc[i].name) == 0) return i;
static void createColliders(BzTileMap *map) {
map->collidersCount = map->width * map->height;
map->colliderMap = bzAlloc(map->collidersCount * sizeof(*map->colliderMap));
for (i32 i = 0; i < map->collidersCount; i++) {
map->colliderMap[i] = (BzTileCollider) {{BZ_TILE_SHAPE_NONE}};
}
return -1;
// Top-most layer takes priority
for (i32 i = map->layerCount - 1; i >= 0; i--) {
BzTileLayer *layer = map->layers + i;
if (layer->tilesetIdx == -1) continue;
BzTileset *tileset = map->tilesets + layer->tilesetIdx;
for (i32 y = 0; y < map->height; y++) {
for (i32 x = 0; x < map->width; x++) {
i32 tile = bzTileLayerGetTile(layer, x, y);
BzTileShape tilesetShape = bzTilesetGetTileCollider(tileset, tile);
if (tilesetShape.type == BZ_TILE_SHAPE_NONE ||
tilesetShape.type == BZ_TILE_SHAPE_POINT)
continue;
tilesetShape.x += layer->offsetX;
tilesetShape.y += layer->offsetY;
i32 colliderIdx = y * map->width + x;
BzTileCollider *collider = map->colliderMap + colliderIdx;
for (i32 sIdx = 0; sIdx < BZ_MAP_COLLIDER_DEPTH; sIdx++) {
BzTileShape *shape = collider->shapes + sIdx;
if (shape->type == BZ_TILE_SHAPE_NONE) {
*shape = tilesetShape;
break;
}
}
}
}
}
}
BzTileMap bzTileMapCreate(const BzTileMapDesc *desc) {
@@ -163,6 +191,8 @@ BzTileMap bzTileMapCreate(const BzTileMapDesc *desc) {
cute_tiled_free_map(cuteMap);
createColliders(&map);
map.isValid = true;
return map;
}
@@ -209,6 +239,45 @@ void bzTileMapDraw(BzTileMap *map) {
}
}
void bzTileMapDrawColliders(BzTileMap *map) {
Color color = RED;
color.a = 150;
for (i32 y = 0; y < map->height; y++) {
for (i32 x = 0; x < map->width; x++) {
i32 idx = y * map->width + x;
BzTileCollider collider = map->colliderMap[idx];
for (i32 i = 0; i < BZ_MAP_COLLIDER_DEPTH; i++) {
BzTileShape shape = collider.shapes[i];
if (shape.type == BZ_TILE_SHAPE_NONE)
break;
i32 posX = x * map->tileWidth + shape.x;
i32 posY = y * map->tileHeight + shape.y;
f32 sizeX = shape.sizeX;
f32 sizeY = shape.sizeY;
switch (shape.type) {
case BZ_TILE_SHAPE_NONE:
break;
case BZ_TILE_SHAPE_POINT:
DrawCircle(posX, posY, 1.0f, color);
break;
case BZ_TILE_SHAPE_RECT:
DrawRectangle(posX, posY, sizeX, sizeY, color);
break;
case BZ_TILE_SHAPE_ELLIPSE:
sizeX *= 0.5f;
sizeY *= 0.5f;
DrawEllipse(posX + sizeX, posY + sizeY, sizeX, sizeY, color);
break;
}
}
}
}
}
bool bzTileMapCanPlace(BzTileMap *map, i32 tileX, i32 tileY, i32 sizeX, i32 sizeY) {
for (i32 y = tileY; y < tileY + sizeY; y++) {
for (i32 x = tileX; x < tileX + sizeX; x++) {
@@ -229,3 +298,8 @@ bool bzTileMapCanPlace(BzTileMap *map, i32 tileX, i32 tileY, i32 sizeX, i32 size
return true;
}
BzTileCollider bzTileMapGetCollider(BzTileMap *map, i32 x, i32 y) {
i32 idx = y * map->width + x;
BZ_ASSERT(idx < 0 && idx < map->collidersCount);
return map->colliderMap[idx];
}

View File

@@ -6,6 +6,7 @@
#define BZ_MAX_MAP_LAYERS 8
#define BZ_MAX_MAP_TILESETS 8
#define BZ_MAP_COLLIDER_DEPTH 3
typedef struct BzTileLayer {
@@ -58,6 +59,10 @@ typedef struct BzTileMapDesc {
BzTileObjectsDesc objectLayers[BZ_MAX_MAP_LAYERS];
} BzTileMapDesc;
typedef struct BzTileCollider {
BzTileShape shapes[BZ_MAP_COLLIDER_DEPTH];
} BzTileCollider;
typedef struct BzTileMap {
Color backgroundColor;
@@ -66,6 +71,9 @@ typedef struct BzTileMap {
i32 tileWidth;
i32 tileHeight;
BzTileCollider *colliderMap;
i32 collidersCount;
BzTileLayer layers[BZ_MAX_MAP_LAYERS];
i32 layerCount;
@@ -86,7 +94,9 @@ BzTileMap bzTileMapCreate(const BzTileMapDesc *desc);
void bzTileMapDestroy(BzTileMap *tilemap);
void bzTileMapDraw(BzTileMap *map);
void bzTileMapDrawColliders(BzTileMap *map);
bool bzTileMapCanPlace(BzTileMap *map, i32 tileX, i32 tileY, i32 sizeX, i32 sizeY);
BzTileCollider bzTileMapGetCollider(BzTileMap *map, i32 x, i32 y);