#include "tilemap.h" #include "debug.h" #include "rigidbody.h" #include "tileset.h" #include "assets.h" #include "camera.h" #include "level.h" #include "render.h" #include "transform.h" #include #include struct TileInstance { Transform transform; TileDef* tiledef; Tilemap* parent_map; }; struct Tilemap { Transform transform; Tileset* set; TileInstance* map; size_t map_num; IVector map_size; RigidBody* rigidbody; }; Tilemap* tilemap_from_autolayer(cJSON* json) { cJSON* const tileset = cJSON_GetObjectItem(json, "__tilesetDefUid"); ASSERT_RETURN(tileset != NULL && cJSON_IsNumber(tileset), NULL, "Could not find __tilesetDefUid while loading tilemap"); cJSON* const tiles = cJSON_GetObjectItem(json, "autoLayerTiles"); ASSERT_RETURN(tiles != NULL && cJSON_IsArray(tiles), NULL, "Could not find autoLayerTiles while loading tilemap"); cJSON* const wid = cJSON_GetObjectItem(json, "__cWid"); ASSERT_RETURN(wid != NULL && cJSON_IsNumber(wid), NULL, "Could not find __cWid while loading tilemap"); cJSON* const hei = cJSON_GetObjectItem(json, "__cHei"); ASSERT_RETURN(hei != NULL && cJSON_IsNumber(hei), NULL, "Could not find __cHei while loading tilemap"); cJSON* const grid = cJSON_GetObjectItem(json, "__gridSize"); ASSERT_RETURN(grid != NULL && cJSON_IsNumber(grid), NULL, "Could not find __gridSize while loading tilemap"); // the minimum requirements for a valid tilemap are met // allocate a tilemap and load the tileset Tilemap* self = malloc(sizeof(Tilemap)); self->transform = IdentityTransform; self->set = tileset_load(tileset->valueint); self->map_size = (IVector) { .x = wid->valueint, .y = hei->valueint }; self->map_num = json_array_len(tiles); self->map = malloc(self->map_num * sizeof(TileInstance)); if(self->map == NULL) { tileset_destroy(self->set); free(self); RETURN_ERROR(NULL, "Failed to allocate map memory"); } self->rigidbody = rigidbody_make(Tilemap_as_Transformable(self)); const double px_to_ws = 1.0 / grid->valuedouble; cJSON* tile; TileInstance* writer = self->map; cJSON_ArrayForEach(tile, tiles) { cJSON* t = cJSON_GetObjectItem(tile, "t"); writer->tiledef = tileset_get_tiledef(self->set, t->valueint); writer->transform = IdentityTransform; cJSON* px = cJSON_GetObjectItem(tile, "px"); writer->transform.position = vmulff(json_array_to_vector(px), px_to_ws); writer->parent_map = self; ++writer; } return self; } void tilemap_destroy(Tilemap* self) { free(self->map); rigidbody_destroy(self->rigidbody); free(self); } void tilemap_draw(Tilemap* self, Transform transform) { Transform tiletrans = transform_apply(transform, self->transform); TileInstance* tile; for(int i = 0; i < self->map_num; ++i) { tile = self->map + i; tiletrans = transform_apply(self->transform, tile->transform); // shape_draw(tiledef_get_shape(tile->tiledef), tiletrans); } for(int i = 0; i < self->map_num; ++i) { tile = self->map + i; tiletrans = transform_apply(self->transform, tile->transform); Sprite* sprite = tiledef_get_sprite(tile->tiledef); if(sprite != NULL) { sprite_draw(sprite, tiletrans); } } } size_t tilemap_get_tile_count(Tilemap* self) { return self->map_num; } TileInstance* tilemap_get_tile(Tilemap* self, size_t at) { return &self->map[at]; } Transform* tilemap_get_transform(Tilemap* self ) { return &self->transform; } RigidBody* tile_instance_get_rigidbody(TileInstance* self) { return self->parent_map->rigidbody; } Transform* tile_instance_get_transform(TileInstance* self) { return &self->transform; } Shape* tile_instance_get_shape(TileInstance* self) { return tiledef_get_shape(self->tiledef); } void tile_instance_on_collision(TileInstance* self, Collision collision) {} Vector* tile_instance_get_position(TileInstance* self) { return &self->transform.position; } Vector* tile_instance_get_scale(TileInstance* self) { return &self->transform.scale; } float* tile_instance_get_rotation(TileInstance* self) { return &self->transform.rotation; } void tile_instance_solve_contacts(TileInstance* self, List* contacts) {}