Support for colliders
This commit is contained in:
@@ -8,6 +8,34 @@
|
||||
"tilecount":297,
|
||||
"tiledversion":"1.10.2",
|
||||
"tileheight":16,
|
||||
"tiles":[
|
||||
{
|
||||
"id":185,
|
||||
"objectgroup":
|
||||
{
|
||||
"draworder":"index",
|
||||
"id":2,
|
||||
"name":"",
|
||||
"objects":[
|
||||
{
|
||||
"ellipse":true,
|
||||
"height":6,
|
||||
"id":1,
|
||||
"name":"collision",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":6,
|
||||
"x":5,
|
||||
"y":8
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"x":0,
|
||||
"y":0
|
||||
}
|
||||
}],
|
||||
"tilewidth":16,
|
||||
"type":"tileset",
|
||||
"version":"1.10",
|
||||
|
||||
59
assets/test.json
Normal file
59
assets/test.json
Normal file
@@ -0,0 +1,59 @@
|
||||
{ "columns":18,
|
||||
"image":"tilemap_packed.png",
|
||||
"imageheight":176,
|
||||
"imagewidth":288,
|
||||
"margin":0,
|
||||
"name":"test",
|
||||
"spacing":0,
|
||||
"tilecount":198,
|
||||
"tiledversion":"1.10.2",
|
||||
"tileheight":16,
|
||||
"tiles":[
|
||||
{
|
||||
"id":0,
|
||||
"objectgroup":
|
||||
{
|
||||
"draworder":"index",
|
||||
"id":2,
|
||||
"name":"",
|
||||
"objects":[
|
||||
{
|
||||
"height":12,
|
||||
"id":1,
|
||||
"name":"test",
|
||||
"properties":[
|
||||
{
|
||||
"name":"test",
|
||||
"type":"string",
|
||||
"value":"123"
|
||||
}],
|
||||
"rotation":0,
|
||||
"type":"test",
|
||||
"visible":true,
|
||||
"width":12,
|
||||
"x":2,
|
||||
"y":2
|
||||
},
|
||||
{
|
||||
"height":4,
|
||||
"id":2,
|
||||
"name":"",
|
||||
"rotation":0,
|
||||
"type":"",
|
||||
"visible":true,
|
||||
"width":4,
|
||||
"x":6,
|
||||
"y":6
|
||||
}],
|
||||
"opacity":1,
|
||||
"type":"objectgroup",
|
||||
"visible":true,
|
||||
"x":0,
|
||||
"y":0
|
||||
},
|
||||
"type":"grass"
|
||||
}],
|
||||
"tilewidth":16,
|
||||
"type":"tileset",
|
||||
"version":"1.10"
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
26
engine/tests/cute_tiled_test.c
Normal file
26
engine/tests/cute_tiled_test.c
Normal 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);
|
||||
}
|
||||
29
game/main.c
29
game/main.c
@@ -47,6 +47,10 @@ void deinit(Game *game) {
|
||||
bzTilesetDestroy(&game->buildingsTileset);
|
||||
bzTileMapDestroy(&game->map);
|
||||
}
|
||||
|
||||
int sizeX = 1;
|
||||
int sizeY = 1;
|
||||
|
||||
void render(float dt, Game *game) {
|
||||
Camera2D *camera = &game->camera;
|
||||
if (IsKeyDown(KEY_W)) camera->target.y -= 20;
|
||||
@@ -64,15 +68,34 @@ void render(float dt, Game *game) {
|
||||
|
||||
bzTileMapDraw(&game->map);
|
||||
|
||||
Vector2 worldPos = GetScreenToWorld2D(GetMousePosition(), game->camera);
|
||||
int tileX = (int) worldPos.x / 16;
|
||||
int tileY = (int) worldPos.y / 16;
|
||||
|
||||
if (tileX != 0 && tileY != 0) {
|
||||
|
||||
bool canPlace = bzTileMapCanPlace(&game->map, tileX, tileY, sizeX, sizeY);
|
||||
Color placeColor = canPlace ?
|
||||
(Color) {0, 255, 0, 200} :
|
||||
(Color) {255, 0, 0, 200};
|
||||
|
||||
DrawRectangleLines(tileX * 16, tileY * 16, sizeX * 16, sizeY * 16, placeColor);
|
||||
}
|
||||
|
||||
EndMode2D();
|
||||
|
||||
if (nk_begin(NK, "Show", nk_rect(50, 50, 220, 220),
|
||||
NK_WINDOW_BORDER|NK_WINDOW_MOVABLE|NK_WINDOW_CLOSABLE)) {
|
||||
// fixed widget pixel width
|
||||
nk_layout_row_static(NK, 30, 80, 1);
|
||||
if (nk_button_label(NK, "button")) {
|
||||
// event handling
|
||||
}
|
||||
nk_labelf(NK, NK_TEXT_LEFT, "tileX: %d", tileX);
|
||||
nk_labelf(NK, NK_TEXT_LEFT, "tileY: %d", tileY);
|
||||
|
||||
nk_labelf(NK, NK_TEXT_LEFT, "x: %d", sizeX);
|
||||
nk_labelf(NK, NK_TEXT_LEFT, "y: %d", sizeY);
|
||||
nk_slider_int(NK, 0, &sizeX, 10, 1);
|
||||
nk_slider_int(NK, 0, &sizeY, 10, 1);
|
||||
|
||||
}
|
||||
nk_end(NK);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<tileset version="1.10" tiledversion="1.10.2" name="terrain" tilewidth="16" tileheight="16" tilecount="297" columns="27">
|
||||
<editorsettings>
|
||||
<export target="../assets/terrain.tsj" format="json"/>
|
||||
</editorsettings>
|
||||
<image source="../assets/terrain.png" width="432" height="176"/>
|
||||
<tile id="185">
|
||||
<objectgroup draworder="index" id="2">
|
||||
<object id="1" x="5" y="8" width="6" height="6">
|
||||
<ellipse/>
|
||||
</object>
|
||||
</objectgroup>
|
||||
</tile>
|
||||
<wangsets>
|
||||
<wangset name="River" type="edge" tile="-1">
|
||||
<wangcolor name="" color="#1c95ff" tile="-1" probability="1"/>
|
||||
|
||||
Reference in New Issue
Block a user