loading a tileset now also loads it's collision information

This commit is contained in:
Sara 2023-10-25 20:28:07 +02:00
parent 34b08282fc
commit 38e277c3ae
2 changed files with 60 additions and 7 deletions

View file

@ -4,11 +4,13 @@
#include "assets.h"
#include "render.h"
#include "SDL2/SDL_image.h"
#include <cjson/cJSON.h>
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;
}

View file

@ -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;