From 38e277c3aef8fc1c4642a72b919b75fc8f8e39f6 Mon Sep 17 00:00:00 2001 From: Sara Date: Wed, 25 Oct 2023 20:28:07 +0200 Subject: [PATCH] loading a tileset now also loads it's collision information --- src/tileset.c | 61 +++++++++++++++++++++++++++++++++++++++++++++------ src/tileset.h | 6 +++++ 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/src/tileset.c b/src/tileset.c index 445d73f..aae35f5 100644 --- a/src/tileset.c +++ b/src/tileset.c @@ -4,11 +4,13 @@ #include "assets.h" #include "render.h" #include "SDL2/SDL_image.h" +#include struct TileDef { size_t tid; Sprite* sprite; - Shape* collision; + Shape* shape; + TileCollision collision; }; struct Tileset { @@ -76,15 +78,18 @@ void _internal_tileset_store(Tileset* self) { } Tileset* tileset_from_json(cJSON* json) { + // required uid, atlas path and grid size elements cJSON* uid = cJSON_GetObjectItem(json, "uid"); ASSERT_RETURN(uid != NULL && cJSON_IsNumber(uid), NULL, "Failed to find uid while loading tileset"); - cJSON* path = cJSON_GetObjectItem(json, "relPath"); ASSERT_RETURN(path != NULL && cJSON_IsString(path), NULL, "Failed to find relPath while loading tileset"); - cJSON* gridsize = cJSON_GetObjectItem(json, "tileGridSize"); ASSERT_RETURN(gridsize != NULL && cJSON_IsNumber(gridsize), NULL, "Failed to find tileGridSize while loading tileset"); + // Optional tags and custom data arrays + cJSON* tags = cJSON_GetObjectItem(json, "enumTags"); + cJSON* custom_data = cJSON_GetObjectItem(json, "customData"); + SDL_Surface* atlas_surface = IMG_Load(path->valuestring); ASSERT_RETURN(atlas_surface != NULL, NULL, "Failed to load atlas image while loading tileset"); @@ -120,13 +125,55 @@ Tileset* tileset_from_json(cJSON* json) { self->tiledefs[tid] = (TileDef) { .tid = tid, .sprite = sprite_from_spritesheet(self->atlas, tid), - .collision = shape_new_square(OneVector) + // default is no collision + .collision = TILE_COL_NONE, + .shape = NULL }; sprite_set_origin(self->tiledefs[tid].sprite, ZeroVector); - // TODO: generate/read collision information + } + SDL_FreeSurface(atlas_surface); + + cJSON* tag; + cJSON_ArrayForEach(tag, tags) { + cJSON* ids = cJSON_GetObjectItem(tag, "tileIds"); + cJSON* tagval = cJSON_GetObjectItem(tag, "enumValueId"); + cJSON* id; + if(strcmp(tagval->valuestring, "fullrect") == 0) { + cJSON_ArrayForEach(id, ids) { + self->tiledefs[id->valueint].shape = shape_new_square(OneVector); + self->tiledefs[id->valueint].collision = TILE_COL_RECT; + } + } else if(strcmp(tagval->valuestring, "pointshape") == 0) { + cJSON_ArrayForEach(id, ids) { + self->tiledefs[id->valueint].collision = TILE_COL_SHAPE; + } + } } - SDL_FreeSurface(atlas_surface); + cJSON* data_tuple; + cJSON_ArrayForEach(data_tuple, custom_data) { + cJSON* id = cJSON_GetObjectItem(data_tuple, "tileId"); + TileDef* def = self->tiledefs + id->valueint; + + CHECK(def->collision == TILE_COL_SHAPE, "Shape with shape description has to have tile collision type set to 'pointshape'"); + + cJSON* data_string = cJSON_GetObjectItem(data_tuple, "data"); + cJSON* data_json = cJSON_Parse(data_string->valuestring); + + ASSERT_RETURN(data_json != NULL, self, "Failed to get shape data for tile of tid %d", id->valueint); + + cJSON* shape_data = cJSON_GetObjectItem(data_json, "collisionShape"); + CHECK(shape_data != NULL, "could not find shape data"); + cJSON* vertex_json; + self->tiledefs[id->valueint].shape = shape_new(NULL, 0); + CHECK(def->shape != NULL, "Failed to create a shape for tiledef"); + cJSON_ArrayForEach(vertex_json, shape_data) { + Vector vertex = json_array_to_vector(vertex_json); + LOG_INFO("vertex %f %f", vertex.x, vertex.y); + shape_add_point(self->tiledefs[id->valueint].shape, vertex); + } + cJSON_Delete(data_json); + } return self; } @@ -172,5 +219,5 @@ Sprite* tiledef_get_sprite(const TileDef* self) { } Shape* tiledef_get_shape(TileDef* self) { - return self->collision; + return self->shape; } \ No newline at end of file diff --git a/src/tileset.h b/src/tileset.h index 8f0dda7..020818b 100644 --- a/src/tileset.h +++ b/src/tileset.h @@ -5,6 +5,12 @@ #include "sprite.h" #include "shape.h" +typedef enum TileCollision { + TILE_COL_NONE, + TILE_COL_RECT, + TILE_COL_SHAPE +} TileCollision; + typedef struct TileDef TileDef; typedef struct Tileset Tileset;