From 3c8254c6f626e358dad3c2ece4574cef90dd1209 Mon Sep 17 00:00:00 2001 From: Klemen Plestenjak Date: Sat, 11 Nov 2023 09:21:59 +0100 Subject: [PATCH] Add support for objects with tiles --- assets/entities.png | Bin 0 -> 19549 bytes assets/entities.tsj | 14 +++++++++++ assets/maps/test.tmj | 20 ++++++++++++++-- engine/breeze/map/map.c | 50 +++++++++++++++++++++++++++++++--------- engine/breeze/map/map.h | 20 +++++++++------- game/main.c | 11 +++++++-- rawAssets/entities.kra | Bin 0 -> 102994 bytes rawAssets/entities.png | Bin 0 -> 19549 bytes tiled/entities.tsx | 4 ++++ tiled/test.tmx | 7 ++++-- 10 files changed, 101 insertions(+), 25 deletions(-) create mode 100644 assets/entities.png create mode 100644 assets/entities.tsj create mode 100644 rawAssets/entities.kra create mode 100644 rawAssets/entities.png create mode 100644 tiled/entities.tsx diff --git a/assets/entities.png b/assets/entities.png new file mode 100644 index 0000000000000000000000000000000000000000..1961067b29d699671e68dd687e3d7c2d8905f211 GIT binary patch literal 19549 zcmeI)doOybv;oKM`NPrP`5L%kT}| zvq~pW#lQc0cMHoPBI8B+mUt(%+%nSbc}sn4p6GV3ELl&~rfPVyrOZ554r_@4D6hn`U*kR-Q%t=4Ipb zO1{8ZWS(_;njvgf+x4hSLEL`UZf?g4<%YE+mq$h2_OFdHu9KC7%62+hj^Ygir&AWI z^}U=>4p(mcZ0&I3Ggs$D3}z%4oDO1oaRM#5U9ZfeV~1<|y` ztIuxi`&{gI^KH@%(juGGbvf(1>zq~mc07v;Y}(uunR?l`@YZo@N_NshtvvcXUi$ch zQICoA6Uvr3sbl_vptNw6lJGlwt37{CuI-}cue)1ip_pG?A7t~i_;sLMnea$c>metr zSV{uB&#S-As!#2%@v}PL2rWT0s`ZXj9`8HXL=asxks#6|BaV37JD~kd)SVJ1yfxm}DN&b2+wXUI zT}+HUA*ao?X0v<}sm5r9oDaTKm!(gNYtvq?PPe^wv1!^y;&qaKlzx&PTgntZI8HAY zO8YAP^2Yg%6=XsT!p*`fsw}Yz`@2T}eeUe=HRm!jGp*gbIy*ZzK73~`S-rKFg#C*< z;hB2x1)@N8vcn}IDj=;(``XJizQu~i{OQcAMT#vaLK5_=Z!2MD;_gw>UTB{zFMd2a zX)98*owin%OVqPugm_gNN;qjdwKnSrc?T~Z57c3}){V@^ERvZge_kD_leqyVY!`}} zu()eZ6S?bfds(cXxx+LzA}de)l|hA{)CIhIr3A5vLow_bBuJ)?%y)P>9BSrYOTz|# zKvmNXx!y(mQO1C%&vt6>hSkPPhhqIF)aymI&mKvIFAqAi{(Q^ zD20YxS5M<`_;Q(_T&qt8raYd59HM8?6_Rw=ADofU1?+k;9~KE4m9M3wx` z|CBRj@}a9bVOf1jnyG$m?QP*Mck(1pw}$;t{>4uPZ~5P2&X3s4*_R;( z6*S}n)m!anGpY*z@Dz>FhPSspd@emQthu3LuaxO+Kc-f9M%8q|cSA;JvqqnCuw#6p z3AplMK?HGGiu17>%I>PDVB^4@SnP3BDhZeGP|z- ztBs2(JwHwu2r{mpnMtSCQK?x$qbkER^n+zuXS4Rsk9Hwk4-OQJa}8qXsE>B z_(6lHn{69bBnju0`-A( zve-pIgHq~Yges;FHt1TF*A%K^e#bm2Unp+wkYAhfvt=(*$0UP&>$s1 z0Vn_kpa2wr0#E=7KmjNK1)u;FfC5ke3P1rU00p1`6#NGiuzTt){(2Swd&dTMJ#g0p zH=dvX6o3Ly017|>C;$bZ02F`%Pyh-*0Vn_kpa2wr0#E=7KmjNK1)u;FfC5nPEhobjects; for (i32 i = 0; i < layer->objectCount; i++) { layer->objects[i].id = hashFunc(object->name.ptr); + + layer->objects[i].gid = object->gid; + if (layer->minGID > object->gid) layer->minGID = object->gid; + else if (layer->maxGID < object->gid) layer->maxGID = object->gid; + layer->objects[i].shape = bzCuteObjectToTileShape(object); object = object->next; } @@ -142,7 +147,7 @@ static void createColliders(BzTileMap *map) { BzTileMap bzTileMapCreate(const BzTileMapDesc *desc) { BzTileMap map = {}; // Auto detect tileset count. - for (i32 i = 0; i < BZ_MAX_MAP_TILESETS; i++) { + for (i32 i = 0; i < BZ_MAP_MAX_TILESETS; i++) { if (!desc->tilesets[i].isValid) break; map.tilesetCount++; @@ -162,12 +167,12 @@ BzTileMap bzTileMapCreate(const BzTileMapDesc *desc) { cute_tiled_layer_t *cuteLayer = cuteMap->layers; while (cuteLayer) { - BZ_ASSERT(map.layerCount < BZ_MAX_MAP_LAYERS); - BZ_ASSERT(map.objectGroupCount < BZ_MAX_MAP_LAYERS); + BZ_ASSERT(map.layerCount < BZ_MAP_MAX_LAYERS); + BZ_ASSERT(map.objectGroupCount < BZ_MAP_MAX_LAYERS); // Find slot i32 slot = -1; - for (i32 i = 0; i < BZ_MAX_MAP_LAYERS; i++) { + for (i32 i = 0; i < BZ_MAP_MAX_LAYERS; i++) { const BzTileLayerDesc *layerDesc = desc->layers + i; const BzTileObjectsDesc *objectsDesc = desc->objectGroups + i; if (layerDesc->name && strcmp(layerDesc->name, cuteLayer->name.ptr) == 0 || @@ -216,17 +221,29 @@ BzTileMap bzTileMapCreate(const BzTileMapDesc *desc) { } // Assign tilesets to layers - for (i32 i = 0; i < map.layerCount; i++) { + for (i32 i = 0; i < BZ_MAP_MAX_LAYERS; i++) { BzTileLayer *layer = map.layers + i; layer->tilesetIdx = -1; + BzTileObjectGroup *objects = map.objectGroups + i; + objects->tilesetIdx = -1; + + bool hasLayer = i < map.layerCount; + bool hasObjects = i < map.objectGroupCount; + for (i32 j = map.tilesetCount - 1; j >= 0; j--) { BzTileset *tileset = map.tilesets + j; - if (tileset->startID >= layer->minData && + if (hasLayer && tileset->startID >= layer->minData && tileset->startID <= layer->maxData) { layer->tilesetIdx = j; - break; + hasLayer = false; } + if (hasObjects && tileset->startID >= objects->minGID && + tileset->startID <= objects->maxGID) { + objects->tilesetIdx = j; + hasObjects = false; + } + if (!hasLayer && !hasObjects) break; } } cute_tiled_free_map(cuteMap); @@ -316,10 +333,11 @@ static void drawLayer(BzTileLayer *layer, BzTileset *tileset) { } -static void drawObjectLayer(BzTileObjectGroup *objectLayer) { +static void drawObjectLayer(BzTileObjectGroup *objectLayer, BzTileset *tileset) { Color color = ORANGE; for (int i = 0; i < objectLayer->objectCount; i++) { - BzTileShape shape = objectLayer->objects[i].shape; + BzTileObject object = objectLayer->objects[i]; + BzTileShape shape = object.shape; switch (shape.type) { case BZ_TILE_SHAPE_NONE: break; @@ -327,7 +345,13 @@ static void drawObjectLayer(BzTileObjectGroup *objectLayer) { DrawCircle(shape.x, shape.y, 2.0f, color); break; case BZ_TILE_SHAPE_RECT: - DrawRectangle(shape.x, shape.y, shape.sizeX, shape.sizeY, color); + if (object.gid) { + Rectangle rec = bzTilesetGetTileRegion(tileset, object.gid); + Rectangle dest = {shape.x, shape.y, shape.sizeX, shape.sizeY}; + DrawTexturePro(tileset->tiles, rec, dest, (Vector2) {0.0f, 0.0f}, 0.0f, WHITE); + } else { + DrawRectangle(shape.x, shape.y, shape.sizeX, shape.sizeY, color); + } break; case BZ_TILE_SHAPE_ELLIPSE: DrawEllipse(shape.x, shape.y, shape.sizeX, shape.sizeY, color); @@ -358,8 +382,12 @@ void bzTileMapDraw(BzTileMap *map) { for (i32 i = 0; i < map->objectGroupCount; i++) { BzTileObjectGroup *objectLayer = map->objectGroups + i; + BzTileset *tileset = NULL; + if (objectLayer->tilesetIdx != -1) { + tileset = map->tilesets + objectLayer->tilesetIdx; + } if (!objectLayer->objects) continue; - drawObjectLayer(objectLayer); + drawObjectLayer(objectLayer, tileset); } } diff --git a/engine/breeze/map/map.h b/engine/breeze/map/map.h index 04c35ea..0d38ec7 100644 --- a/engine/breeze/map/map.h +++ b/engine/breeze/map/map.h @@ -4,8 +4,8 @@ #include "tileset.h" #include "../utils/string.h" -#define BZ_MAX_MAP_LAYERS 8 -#define BZ_MAX_MAP_TILESETS 8 +#define BZ_MAP_MAX_LAYERS 8 +#define BZ_MAP_MAX_TILESETS 8 #define BZ_MAP_COLLIDER_DEPTH 2 typedef struct BzTileLayer BzTileLayer; @@ -30,10 +30,10 @@ typedef struct BzTileObjectsDesc { typedef struct BzTileMapDesc { const char *path; - BzTileset tilesets[BZ_MAX_MAP_TILESETS]; + BzTileset tilesets[BZ_MAP_MAX_TILESETS]; - BzTileLayerDesc layers[BZ_MAX_MAP_LAYERS]; - BzTileObjectsDesc objectGroups[BZ_MAX_MAP_LAYERS]; + BzTileLayerDesc layers[BZ_MAP_MAX_LAYERS]; + BzTileObjectsDesc objectGroups[BZ_MAP_MAX_LAYERS]; } BzTileMapDesc; typedef struct BzTileLayer { @@ -59,12 +59,16 @@ typedef struct BzTileLayer { typedef struct BzTileObject { u32 id; + BzTile gid; BzTileShape shape; } BzTileObject; typedef struct BzTileObjectGroup { BzTileObject *objects; i32 objectCount; + BzTile minGID; + BzTile maxGID; + i32 tilesetIdx; BzTileObjectsDesc desc; bool hasOwnership; @@ -86,13 +90,13 @@ typedef struct BzTileMap { BzTileCollider *colliderMap; i32 collidersCount; - BzTileLayer layers[BZ_MAX_MAP_LAYERS]; + BzTileLayer layers[BZ_MAP_MAX_LAYERS]; i32 layerCount; - BzTileObjectGroup objectGroups[BZ_MAX_MAP_LAYERS]; + BzTileObjectGroup objectGroups[BZ_MAP_MAX_LAYERS]; i32 objectGroupCount; - BzTileset tilesets[BZ_MAX_MAP_TILESETS]; + BzTileset tilesets[BZ_MAP_MAX_TILESETS]; i32 tilesetCount; bool isValid; diff --git a/game/main.c b/game/main.c index f9a516f..c247464 100644 --- a/game/main.c +++ b/game/main.c @@ -27,6 +27,7 @@ typedef struct Game { Camera2D camera; BzTileset terrainTileset; BzTileset buildingsTileset; + BzTileset entitiesTileset; BzTileMap map; } Game; @@ -204,11 +205,16 @@ bool init(Game *game) { .path="assets/buildings.tsj", .texturePath="assets/buildings.png" }); + game->entitiesTileset = bzTilesetCreate(&(BzTilesetDesc) { + .path="assets/entities.tsj", + .texturePath="assets/entities.png" + }); game->map = bzTileMapCreate(&(BzTileMapDesc) { .path="assets/maps/test.tmj", .tilesets[0]=game->terrainTileset, .tilesets[1]=game->buildingsTileset, + .tilesets[2]=game->entitiesTileset, .layers[LAYER_TERRAIN]=(BzTileLayerDesc) {"Terrain"}, .layers[LAYER_FOLIAGE]=(BzTileLayerDesc) {"Foliage"}, @@ -224,15 +230,16 @@ bool init(Game *game) { bzTileMapOverrideLayer(&game->map, LAYER_BUILDING_OWNER, prepareBuildings); bzTileMapOverrideObjectGroup(&game->map, OBJECTS_GAME, handleGameObjects); - bzTileMapOverrideObjectGroup(&game->map, OBJECTS_ENTITIES, BZ_TILE_OBJECTS_CLEAR); + //bzTileMapOverrideObjectGroup(&game->map, OBJECTS_ENTITIES, BZ_TILE_OBJECTS_CLEAR); return true; } void deinit(Game *game) { + bzTileMapDestroy(&game->map); bzTilesetDestroy(&game->terrainTileset); bzTilesetDestroy(&game->buildingsTileset); - bzTileMapDestroy(&game->map); + bzTilesetDestroy(&game->entitiesTileset); rlImGuiShutdown(); } diff --git a/rawAssets/entities.kra b/rawAssets/entities.kra new file mode 100644 index 0000000000000000000000000000000000000000..5c20fff612a568723403ce1d5f9ddb0ef3bf3053 GIT binary patch literal 102994 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 literal 0 HcmV?d00001 diff --git a/rawAssets/entities.png b/rawAssets/entities.png new file mode 100644 index 0000000000000000000000000000000000000000..1961067b29d699671e68dd687e3d7c2d8905f211 GIT binary patch literal 19549 zcmeI)doOybv;oKM`NPrP`5L%kT}| zvq~pW#lQc0cMHoPBI8B+mUt(%+%nSbc}sn4p6GV3ELl&~rfPVyrOZ554r_@4D6hn`U*kR-Q%t=4Ipb zO1{8ZWS(_;njvgf+x4hSLEL`UZf?g4<%YE+mq$h2_OFdHu9KC7%62+hj^Ygir&AWI z^}U=>4p(mcZ0&I3Ggs$D3}z%4oDO1oaRM#5U9ZfeV~1<|y` ztIuxi`&{gI^KH@%(juGGbvf(1>zq~mc07v;Y}(uunR?l`@YZo@N_NshtvvcXUi$ch zQICoA6Uvr3sbl_vptNw6lJGlwt37{CuI-}cue)1ip_pG?A7t~i_;sLMnea$c>metr zSV{uB&#S-As!#2%@v}PL2rWT0s`ZXj9`8HXL=asxks#6|BaV37JD~kd)SVJ1yfxm}DN&b2+wXUI zT}+HUA*ao?X0v<}sm5r9oDaTKm!(gNYtvq?PPe^wv1!^y;&qaKlzx&PTgntZI8HAY zO8YAP^2Yg%6=XsT!p*`fsw}Yz`@2T}eeUe=HRm!jGp*gbIy*ZzK73~`S-rKFg#C*< z;hB2x1)@N8vcn}IDj=;(``XJizQu~i{OQcAMT#vaLK5_=Z!2MD;_gw>UTB{zFMd2a zX)98*owin%OVqPugm_gNN;qjdwKnSrc?T~Z57c3}){V@^ERvZge_kD_leqyVY!`}} zu()eZ6S?bfds(cXxx+LzA}de)l|hA{)CIhIr3A5vLow_bBuJ)?%y)P>9BSrYOTz|# zKvmNXx!y(mQO1C%&vt6>hSkPPhhqIF)aymI&mKvIFAqAi{(Q^ zD20YxS5M<`_;Q(_T&qt8raYd59HM8?6_Rw=ADofU1?+k;9~KE4m9M3wx` z|CBRj@}a9bVOf1jnyG$m?QP*Mck(1pw}$;t{>4uPZ~5P2&X3s4*_R;( z6*S}n)m!anGpY*z@Dz>FhPSspd@emQthu3LuaxO+Kc-f9M%8q|cSA;JvqqnCuw#6p z3AplMK?HGGiu17>%I>PDVB^4@SnP3BDhZeGP|z- ztBs2(JwHwu2r{mpnMtSCQK?x$qbkER^n+zuXS4Rsk9Hwk4-OQJa}8qXsE>B z_(6lHn{69bBnju0`-A( zve-pIgHq~Yges;FHt1TF*A%K^e#bm2Unp+wkYAhfvt=(*$0UP&>$s1 z0Vn_kpa2wr0#E=7KmjNK1)u;FfC5ke3P1rU00p1`6#NGiuzTt){(2Swd&dTMJ#g0p zH=dvX6o3Ly017|>C;$bZ02F`%Pyh-*0Vn_kpa2wr0#E=7KmjNK1)u;FfC5nPEh + + + diff --git a/tiled/test.tmx b/tiled/test.tmx index 6249f7f..e4d242e 100644 --- a/tiled/test.tmx +++ b/tiled/test.tmx @@ -1,10 +1,11 @@ - + + 1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2, @@ -329,7 +330,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 - + + +