diff --git a/engine/breeze/world/map.c b/engine/breeze/world/map.c index c541ccb..e3e58d7 100644 --- a/engine/breeze/world/map.c +++ b/engine/breeze/world/map.c @@ -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]; +} diff --git a/engine/breeze/world/map.h b/engine/breeze/world/map.h index 6aa6b9d..fe96069 100644 --- a/engine/breeze/world/map.h +++ b/engine/breeze/world/map.h @@ -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); diff --git a/game/main.c b/game/main.c index 27c2c10..5e95ac1 100644 --- a/game/main.c +++ b/game/main.c @@ -92,6 +92,7 @@ void render(float dt, Game *game) { ClearBackground(RAYWHITE); bzTileMapDraw(&game->map); + bzTileMapDrawColliders(&game->map); Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera); int tileX = (int) worldPos.x / 16;