Support for colliders

This commit is contained in:
2023-11-08 16:41:00 +01:00
parent e56c2a067e
commit 50241f9c26
10 changed files with 255 additions and 27 deletions

View File

@@ -7,6 +7,11 @@
BzTileMap BZ_TILEMAP_INVALID = {.isValid = false};
int16_t bzTileLayerGetTile(BzTileLayer *layer, i32 x, i32 y) {
return layer->data[layer->width * y + x];
}
BzTileMap bzTileMapCreate(const BzTileMapDesc *desc) {
BzTileMap map = {};
i32 tilesetCount = desc->tilesetCount;
@@ -97,6 +102,17 @@ BzTileMap bzTileMapCreate(const BzTileMapDesc *desc) {
return map;
}
void bzTileMapDestroy(BzTileMap *tilemap) {
for (i32 i = 0; i < tilemap->layerCount; i++) {
BzTileLayer *layer = tilemap->layers + i;
bzFree(layer->data);
layer->data = NULL;
layer->dataCount = 0;
}
*tilemap = BZ_TILEMAP_INVALID;
}
static void drawLayer(BzTileLayer *layer, BzTileset *tileset) {
if (!tileset) return;
if (layer->minData == layer->maxData) return;
@@ -128,17 +144,23 @@ void bzTileMapDraw(BzTileMap *map) {
}
}
void bzTileMapDestroy(BzTileMap *tilemap) {
for (i32 i = 0; i < tilemap->layerCount; i++) {
BzTileLayer *layer = tilemap->layers + i;
bzFree(layer->data);
layer->data = NULL;
layer->dataCount = 0;
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++) {
for (i32 i = 0; i < map->layerCount; i++) {
BzTileLayer *layer = map->layers + i;
if (layer->tilesetIdx == -1) continue;
BzTileset *tileset = map->tilesets + layer->tilesetIdx;
i16 tile = bzTileLayerGetTile(layer, x, y);
BzTileCollider collider = bzTilesetGetTileCollider(tileset, tile);
if (collider.type != BZ_TILE_COLLIDER_NONE)
return false;
}
}
}
*tilemap = BZ_TILEMAP_INVALID;
}
int16_t bzTileLayerGetTile(BzTileLayer *layer, i32 x, i32 y) {
return layer->data[layer->width * y + x];
return true;
}

View File

@@ -54,9 +54,11 @@ extern BzTileMap BZ_TILEMAP_INVALID;
int16_t bzTileLayerGetTile(BzTileLayer *layer, i32 x, i32 y);
BzTileMap bzTileMapCreate(const BzTileMapDesc *desc);
void bzTileMapDraw(BzTileMap *map);
void bzTileMapDestroy(BzTileMap *tilemap);
void bzTileMapDraw(BzTileMap *map);
bool bzTileMapCanPlace(BzTileMap *map, i32 tileX, i32 tileY, i32 sizeX, i32 sizeY);
#endif //BREEZE_MAP_H

View File

@@ -1,31 +1,57 @@
#include <assert.h>
#include <cute_tiled.h>
#include <stdio.h>
#include <cute_tiled.h>
#include "tileset.h"
#include "../core/memory.h"
BzTileset BZ_TILESET_INVALID = {.isValid = false};
BzTileset bzTilesetCreate(const BzTilesetDesc *desc) {
BzTileset tileset = {};
cute_tiled_tileset_t *source = cute_tiled_load_external_tileset(desc->path, NULL);
cute_tiled_tileset_t *cuteTileset = cute_tiled_load_external_tileset(desc->path, NULL);
tileset.tiles = LoadTexture(desc->texturePath);
tileset.startID = source->firstgid;
tileset.tileWidth = source->tilewidth;
tileset.tileHeight = source->tileheight;
tileset.startID = cuteTileset->firstgid;
tileset.tileWidth = cuteTileset->tilewidth;
tileset.tileHeight = cuteTileset->tileheight;
tileset.offsetX = source->tileoffset_x;
tileset.offsetY = source->tileoffset_y;
tileset.offsetX = cuteTileset->tileoffset_x;
tileset.offsetY = cuteTileset->tileoffset_y;
tileset.width = tileset.tiles.width / tileset.tileWidth;
tileset.height = tileset.tiles.height / tileset.tileHeight;
cute_tiled_free_external_tileset(source);
tileset.tileCount = tileset.width * tileset.tileHeight;
tileset.tileColliders = bzAlloc(tileset.tileCount * sizeof(*tileset.tileColliders));
for (i32 i = 0; i < tileset.tileCount; i++) {
tileset.tileColliders[i] = (BzTileCollider) {BZ_TILE_COLLIDER_NONE};
}
if (tileset.tiles.width != source->imagewidth ||
tileset.tiles.height != source->imageheight) {
cute_tiled_tile_descriptor_t *cuteTile = cuteTileset->tiles;
while (cuteTile) {
if (!cuteTile->objectgroup) break;
cute_tiled_object_t *cuteObject = cuteTile->objectgroup->objects;
// NOTE: Only supporting single collider (integer values)
if (cuteObject) {
if (cuteObject->vertices) break;
BzTileCollider collider = {BZ_TILE_COLLIDER_RECT};
if (cuteObject->ellipse)
collider.type = BZ_TILE_COLLIDER_ELLIPSE;
collider.x = (i8) cuteObject->x;
collider.y = (i8) cuteObject->y;
collider.sizeX = (i8) cuteObject->width;
collider.sizeY = (i8) cuteObject->height;
tileset.tileColliders[cuteTile->tile_index] = collider;
}
cuteTile = cuteTile->next;
}
cute_tiled_free_external_tileset(cuteTileset);
if (tileset.tiles.width != cuteTileset->imagewidth ||
tileset.tiles.height != cuteTileset->imageheight) {
bzTilesetDestroy(&tileset);
return BZ_TILESET_INVALID;
}
@@ -36,11 +62,23 @@ BzTileset bzTilesetCreate(const BzTilesetDesc *desc) {
Rectangle bzTilesetGetTileRegion(BzTileset *tileset, int tileID) {
tileID = tileID - tileset->startID;
if (tileID < 0 || tileID >= tileset->tileCount) {
return (Rectangle){};
}
int posX = tileID % tileset->width;
int posY = tileID / tileset->width;
return (Rectangle) {posX * tileset->tileWidth, posY * tileset->tileHeight,
tileset->tileWidth, tileset->tileHeight};
}
BzTileCollider bzTilesetGetTileCollider(BzTileset *tileset, int tileID) {
tileID = tileID - tileset->startID;
if (tileID < 0 || tileID >= tileset->tileCount) {
return (BzTileCollider) {.type = BZ_TILE_COLLIDER_NONE};
}
return tileset->tileColliders[tileID];
}
void bzTilesetDestroy(BzTileset *tileset) {
UnloadTexture(tileset->tiles);

View File

@@ -10,8 +10,24 @@ typedef struct BzTilesetDesc {
const char *texturePath;
} BzTilesetDesc;
typedef enum BzTileColliderType {
BZ_TILE_COLLIDER_NONE,
BZ_TILE_COLLIDER_RECT,
BZ_TILE_COLLIDER_ELLIPSE
} BzTileColliderType;
typedef struct BzTileCollider {
BzTileColliderType type;
u8 x;
u8 y;
u8 sizeX;
u8 sizeY;
} BzTileCollider;
typedef struct BzTileset {
Texture2D tiles;
i32 tileCount;
BzTileCollider *tileColliders;
i32 startID;
i32 tileWidth;
i32 tileHeight;
@@ -27,6 +43,7 @@ extern BzTileset BZ_TILESET_INVALID;
BzTileset bzTilesetCreate(const BzTilesetDesc *desc);
Rectangle bzTilesetGetTileRegion(BzTileset *tileset, int tileID);
BzTileCollider bzTilesetGetTileCollider(BzTileset *tileset, int tileID);
void bzTilesetDestroy(BzTileset *tileset);

View File

@@ -5,3 +5,6 @@ target_link_libraries(window_test LINK_PRIVATE Breeze)
add_executable(nuklear_test nuklear_test.c)
target_link_libraries(nuklear_test LINK_PRIVATE Breeze)
add_executable(cute_tiled_test cute_tiled_test.c)
target_link_libraries(cute_tiled_test LINK_PRIVATE Breeze)

View File

@@ -0,0 +1,26 @@
#include <cute_tiled.h>
#include <stdio.h>
int main() {
cute_tiled_tileset_t *tileset = cute_tiled_load_external_tileset("test.json", NULL);
cute_tiled_tile_descriptor_t *tile = tileset->tiles;
printf("Tileset name: %p %s\n", tileset->name.ptr, tileset->name.ptr);
while (tile) {
cute_tiled_layer_t *layer = tile->objectgroup;
cute_tiled_object_t *object = layer->objects;
while (object) {
printf("[%p]: ellipse:%d x:%2.f y:%2.f w:%2.f h:%2.f\n",
object->name.ptr, object->ellipse,
object->x, object->y, object->width, object->height);
object = object->next;
}
tile = tile->next;
}
cute_tiled_free_external_tileset(tileset);
}