Proper layer rendering
This commit is contained in:
@@ -24,7 +24,6 @@ set(BreezeSources
|
|||||||
|
|
||||||
breeze/utils/tokenizer.c
|
breeze/utils/tokenizer.c
|
||||||
|
|
||||||
breeze/world/layer.c
|
|
||||||
breeze/world/map.c
|
breeze/world/map.c
|
||||||
breeze/world/tileset.c
|
breeze/world/tileset.c
|
||||||
)
|
)
|
||||||
@@ -37,7 +36,6 @@ set(BreezeHeaders
|
|||||||
|
|
||||||
breeze/utils/tokenizer.h
|
breeze/utils/tokenizer.h
|
||||||
|
|
||||||
breeze/world/layer.h
|
|
||||||
breeze/world/map.h
|
breeze/world/map.h
|
||||||
breeze/world/tileset.h
|
breeze/world/tileset.h
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include "breeze/utils/tokenizer.h"
|
#include "breeze/utils/tokenizer.h"
|
||||||
|
|
||||||
#include "breeze/world/layer.h"
|
|
||||||
#include "breeze/world/map.h"
|
#include "breeze/world/map.h"
|
||||||
#include "breeze/world/tileset.h"
|
#include "breeze/world/tileset.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
#include "layer.h"
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#ifndef BREEZE_LAYER_H
|
|
||||||
#define BREEZE_LAYER_H
|
|
||||||
|
|
||||||
#endif //BREEZE_LAYER_H
|
|
||||||
@@ -1 +1,144 @@
|
|||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
|
#include "../core/memory.h"
|
||||||
|
#include "../math/vec2i.h"
|
||||||
|
|
||||||
|
#include <cute_tiled.h>
|
||||||
|
|
||||||
|
BzTileMap BZ_TILEMAP_INVALID = {.isValid = false};
|
||||||
|
|
||||||
|
BzTileMap bzTileMapCreate(const BzTileMapDesc *desc) {
|
||||||
|
BzTileMap map = {};
|
||||||
|
i32 tilesetCount = desc->tilesetCount;
|
||||||
|
if (tilesetCount == 0) {
|
||||||
|
// Auto detect tileset count.
|
||||||
|
for (i32 i = 0; i < BZ_MAX_MAP_TILESETS; i++) {
|
||||||
|
if (!desc->tilesets[i].isValid)
|
||||||
|
break;
|
||||||
|
tilesetCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
map.tilesetCount = tilesetCount;
|
||||||
|
for (i32 i = 0; i < map.tilesetCount; i++) {
|
||||||
|
map.tilesets[i] = desc->tilesets[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
cute_tiled_map_t *cuteMap = cute_tiled_load_map_from_file(desc->path, NULL);
|
||||||
|
|
||||||
|
map.backgroundColor = GetColor(cuteMap->backgroundcolor);
|
||||||
|
|
||||||
|
map.width = cuteMap->width;
|
||||||
|
map.height = cuteMap->height;
|
||||||
|
map.tileWidth = cuteMap->tilewidth;
|
||||||
|
map.tileHeight = cuteMap->tileheight;
|
||||||
|
|
||||||
|
cute_tiled_layer_t *cuteLayer = cuteMap->layers;
|
||||||
|
while (cuteLayer) {
|
||||||
|
BZ_ASSERT(map.layerCount < BZ_MAX_MAP_LAYERS);
|
||||||
|
|
||||||
|
BzTileLayer *layer = map.layers + map.layerCount;
|
||||||
|
layer->id = cuteLayer->id;
|
||||||
|
|
||||||
|
layer->dataCount = cuteLayer->data_count;
|
||||||
|
layer->data = NULL;
|
||||||
|
if (layer->dataCount > 0) {
|
||||||
|
layer->data = bzAlloc(layer->dataCount * sizeof(*layer->data));
|
||||||
|
layer->minData = layer->maxData = (i16) cuteLayer->data[0];
|
||||||
|
for (i32 i = 0; i < layer->dataCount; i++) {
|
||||||
|
layer->data[i] = (i16) cuteLayer->data[i];
|
||||||
|
if (layer->data[i] < layer->minData)
|
||||||
|
layer->minData = layer->data[i];
|
||||||
|
else if (layer->data[i] > layer->maxData)
|
||||||
|
layer->maxData = layer->data[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
layer->width = cuteLayer->width;
|
||||||
|
layer->height = cuteLayer->height;
|
||||||
|
|
||||||
|
layer->offsetX = cuteLayer->offsetx;
|
||||||
|
layer->offsetY = cuteLayer->offsety;
|
||||||
|
layer->opacity = cuteLayer->opacity;
|
||||||
|
|
||||||
|
map.layerCount++;
|
||||||
|
cuteLayer = cuteLayer->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
cute_tiled_tileset_t *cuteTileset = cuteMap->tilesets;
|
||||||
|
tilesetCount = 0;
|
||||||
|
while ((cuteTileset = cuteTileset->next)) tilesetCount++;
|
||||||
|
BZ_ASSERT(tilesetCount == map.tilesetCount);
|
||||||
|
|
||||||
|
cuteTileset = cuteMap->tilesets;
|
||||||
|
for (i32 i = 0; i < map.tilesetCount; i++) {
|
||||||
|
BzTileset *tileset = map.tilesets + i;
|
||||||
|
tileset->startID = cuteTileset->firstgid;
|
||||||
|
cuteTileset = cuteTileset->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign tilesets to layers
|
||||||
|
for (i32 i = 0; i < map.layerCount; i++) {
|
||||||
|
BzTileLayer *layer = map.layers + i;
|
||||||
|
layer->tilesetIdx = -1;
|
||||||
|
for (i32 j = map.tilesetCount - 1; j >= 0; j--) {
|
||||||
|
BzTileset *tileset = map.tilesets + j;
|
||||||
|
|
||||||
|
if (tileset->startID >= layer->minData &&
|
||||||
|
tileset->startID <= layer->maxData) {
|
||||||
|
layer->tilesetIdx = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cute_tiled_free_map(cuteMap);
|
||||||
|
|
||||||
|
map.isValid = true;
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawLayer(BzTileLayer *layer, BzTileset *tileset) {
|
||||||
|
if (!tileset) return;
|
||||||
|
if (layer->minData == layer->maxData) return;
|
||||||
|
Vector2 drawPos = {layer->offsetX, layer->offsetY};
|
||||||
|
|
||||||
|
for (i32 y = 0; y < layer->height; y++) {
|
||||||
|
for (i32 x = 0; x < layer->width; x++) {
|
||||||
|
i16 tile = bzTileLayerGetTile(layer, x, y);
|
||||||
|
if (tile - tileset->startID != -1) {
|
||||||
|
Rectangle rec = bzTilesetGetTileRegion(tileset, tile);
|
||||||
|
DrawTextureRec(tileset->tiles, rec, drawPos, WHITE);
|
||||||
|
}
|
||||||
|
drawPos.x += (float) tileset->tileWidth;
|
||||||
|
}
|
||||||
|
drawPos.x = layer->offsetX;
|
||||||
|
drawPos.y += (float) tileset->tileHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void bzTileMapDraw(BzTileMap *map) {
|
||||||
|
for (i32 i = 0; i < map->layerCount; i++) {
|
||||||
|
BzTileLayer *layer = map->layers + i;
|
||||||
|
BzTileset *tileset = NULL;
|
||||||
|
if (layer->tilesetIdx != -1) {
|
||||||
|
tileset = map->tilesets + layer->tilesetIdx;
|
||||||
|
}
|
||||||
|
drawLayer(map->layers + i, tileset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int16_t bzTileLayerGetTile(BzTileLayer *layer, i32 x, i32 y) {
|
||||||
|
return layer->data[layer->width * y + x];
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,62 @@
|
|||||||
#ifndef BREEZE_MAP_H
|
#ifndef BREEZE_MAP_H
|
||||||
#define BREEZE_MAP_H
|
#define BREEZE_MAP_H
|
||||||
|
|
||||||
|
#include "tileset.h"
|
||||||
|
|
||||||
|
#define BZ_MAX_MAP_LAYERS 16
|
||||||
|
#define BZ_MAX_MAP_TILESETS 8
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct BzTileLayer {
|
||||||
|
i32 id;
|
||||||
|
|
||||||
|
int16_t *data;
|
||||||
|
i32 dataCount;
|
||||||
|
i16 minData;
|
||||||
|
i16 maxData;
|
||||||
|
|
||||||
|
i32 width;
|
||||||
|
i32 height;
|
||||||
|
|
||||||
|
f32 offsetX;
|
||||||
|
f32 offsetY;
|
||||||
|
f32 opacity;
|
||||||
|
|
||||||
|
i32 tilesetIdx;
|
||||||
|
} BzTileLayer;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct BzTileMapDesc {
|
||||||
|
const char *path;
|
||||||
|
BzTileset tilesets[BZ_MAX_MAP_TILESETS];
|
||||||
|
i32 tilesetCount;
|
||||||
|
} BzTileMapDesc;
|
||||||
|
|
||||||
|
typedef struct BzTileMap {
|
||||||
|
Color backgroundColor;
|
||||||
|
|
||||||
|
i32 width;
|
||||||
|
i32 height;
|
||||||
|
i32 tileWidth;
|
||||||
|
i32 tileHeight;
|
||||||
|
|
||||||
|
BzTileLayer layers[BZ_MAX_MAP_LAYERS];
|
||||||
|
i32 layerCount;
|
||||||
|
|
||||||
|
BzTileset tilesets[BZ_MAX_MAP_TILESETS];
|
||||||
|
i32 tilesetCount;
|
||||||
|
|
||||||
|
bool isValid;
|
||||||
|
} BzTileMap;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //BREEZE_MAP_H
|
#endif //BREEZE_MAP_H
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef BREEZE_TILESET_H
|
#ifndef BREEZE_TILESET_H
|
||||||
#define BREEZE_TILESET_H
|
#define BREEZE_TILESET_H
|
||||||
|
|
||||||
|
#include "../defines.h"
|
||||||
|
|
||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
|
|
||||||
typedef struct BzTilesetDesc {
|
typedef struct BzTilesetDesc {
|
||||||
@@ -10,13 +12,13 @@ typedef struct BzTilesetDesc {
|
|||||||
|
|
||||||
typedef struct BzTileset {
|
typedef struct BzTileset {
|
||||||
Texture2D tiles;
|
Texture2D tiles;
|
||||||
int startID;
|
i32 startID;
|
||||||
int tileWidth;
|
i32 tileWidth;
|
||||||
int tileHeight;
|
i32 tileHeight;
|
||||||
int width;
|
i32 width;
|
||||||
int height;
|
i32 height;
|
||||||
int offsetX;
|
i32 offsetX;
|
||||||
int offsetY;
|
i32 offsetY;
|
||||||
bool isValid;
|
bool isValid;
|
||||||
} BzTileset;
|
} BzTileset;
|
||||||
|
|
||||||
|
|||||||
82
game/main.c
82
game/main.c
@@ -1,54 +1,21 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <flecs.h>
|
#include <flecs.h>
|
||||||
|
|
||||||
#include <cute_tiled.h>
|
|
||||||
|
|
||||||
#define BZ_ENTRYPOINT
|
#define BZ_ENTRYPOINT
|
||||||
#include <breeze.h>
|
#include <breeze.h>
|
||||||
|
|
||||||
|
|
||||||
static void drawTile(Texture2D texture, int tid, int tileSetWidth, int size, Vector2 pos) {
|
|
||||||
Rectangle rec = {(tid % tileSetWidth) * size, (tid / tileSetWidth) * size, size, size};
|
|
||||||
|
|
||||||
DrawTextureRec(texture, rec, pos, WHITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawLayer(cute_tiled_layer_t *layer, BzTileset *tileset) {
|
|
||||||
Vector2 pos = {layer->offsetx, layer->offsety};
|
|
||||||
|
|
||||||
for (int y = 0; y < layer->height; y++) {
|
|
||||||
for (int x = 0; x < layer->width; x++) {
|
|
||||||
int tile = layer->data[y * layer->width + x];
|
|
||||||
if (tile - tileset->startID != -1) {
|
|
||||||
Rectangle rec = bzTilesetGetTileRegion(tileset, tile);
|
|
||||||
DrawTextureRec(tileset->tiles, rec, pos, WHITE);
|
|
||||||
}
|
|
||||||
pos.x += tileset->tileWidth;
|
|
||||||
}
|
|
||||||
pos.x = layer->offsetx;
|
|
||||||
pos.y += tileset->tileHeight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct Game {
|
typedef struct Game {
|
||||||
cute_tiled_map_t *map;
|
|
||||||
Camera2D camera;
|
Camera2D camera;
|
||||||
BzTileset terrainTileset;
|
BzTileset terrainTileset;
|
||||||
BzTileset buildingsTileset;
|
BzTileset buildingsTileset;
|
||||||
cute_tiled_layer_t *terrain;
|
BzTileMap map;
|
||||||
cute_tiled_layer_t *trees;
|
|
||||||
cute_tiled_layer_t *trees2;
|
|
||||||
cute_tiled_layer_t *buildings;
|
|
||||||
} Game;
|
} Game;
|
||||||
|
|
||||||
static Game GAME = {};
|
static Game GAME = {};
|
||||||
|
|
||||||
bool init(Game *game) {
|
bool init(Game *game) {
|
||||||
game->map = cute_tiled_load_map_from_file("assets/maps/test.tmj", NULL);
|
|
||||||
cute_tiled_tileset_t *terrainSource = cute_tiled_load_external_tileset("assets/terrain.tsj", NULL);
|
|
||||||
|
|
||||||
cute_tiled_tileset_t *buildingsSource = cute_tiled_load_external_tileset("assets/buildings.tsj", NULL);
|
|
||||||
|
|
||||||
game->terrainTileset = bzTilesetCreate( &(BzTilesetDesc) {
|
game->terrainTileset = bzTilesetCreate( &(BzTilesetDesc) {
|
||||||
.path="assets/terrain.tsj",
|
.path="assets/terrain.tsj",
|
||||||
.texturePath="assets/terrain.png"
|
.texturePath="assets/terrain.png"
|
||||||
@@ -58,42 +25,12 @@ bool init(Game *game) {
|
|||||||
.texturePath="assets/buildings.png"
|
.texturePath="assets/buildings.png"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
game->map = bzTileMapCreate(&(BzTileMapDesc) {
|
||||||
|
.path="assets/maps/test.tmj",
|
||||||
|
.tilesets[0]=game->terrainTileset,
|
||||||
|
.tilesets[1]=game->buildingsTileset
|
||||||
|
});
|
||||||
|
|
||||||
cute_tiled_tileset_t *tileset = game->map->tilesets;
|
|
||||||
game->terrainTileset.startID = tileset->firstgid;
|
|
||||||
tileset = tileset->next;
|
|
||||||
game->buildingsTileset.startID = tileset->firstgid;
|
|
||||||
|
|
||||||
cute_tiled_free_external_tileset(terrainSource);
|
|
||||||
cute_tiled_free_external_tileset(buildingsSource);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
game->terrain = NULL;
|
|
||||||
game->trees = NULL;
|
|
||||||
game->trees2 = NULL;
|
|
||||||
game->buildings = NULL;
|
|
||||||
// loop over the map's layers
|
|
||||||
cute_tiled_layer_t* layer = game->map->layers;
|
|
||||||
while (layer)
|
|
||||||
{
|
|
||||||
int* data = layer->data;
|
|
||||||
int data_count = layer->data_count;
|
|
||||||
|
|
||||||
if (strcmp("Terrain", layer->name.ptr) == 0) {
|
|
||||||
game->terrain = layer;
|
|
||||||
} else if (strcmp("Foliage", layer->name.ptr) == 0) {
|
|
||||||
|
|
||||||
} else if (strcmp("Trees", layer->name.ptr) == 0) {
|
|
||||||
game->trees = layer;
|
|
||||||
} else if (strcmp("TreesS", layer->name.ptr) == 0) {
|
|
||||||
game->trees2 = layer;
|
|
||||||
} else if (strcmp("Buildings", layer->name.ptr) == 0) {
|
|
||||||
game->buildings = layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
layer = layer->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
int screenWidth = 1280;
|
int screenWidth = 1280;
|
||||||
int screenHeight = 720;
|
int screenHeight = 720;
|
||||||
@@ -108,7 +45,7 @@ bool init(Game *game) {
|
|||||||
void deinit(Game *game) {
|
void deinit(Game *game) {
|
||||||
bzTilesetDestroy(&game->terrainTileset);
|
bzTilesetDestroy(&game->terrainTileset);
|
||||||
bzTilesetDestroy(&game->buildingsTileset);
|
bzTilesetDestroy(&game->buildingsTileset);
|
||||||
cute_tiled_free_map(game->map);
|
bzTileMapDestroy(&game->map);
|
||||||
}
|
}
|
||||||
void render(float dt, Game *game) {
|
void render(float dt, Game *game) {
|
||||||
Camera2D *camera = &game->camera;
|
Camera2D *camera = &game->camera;
|
||||||
@@ -126,10 +63,7 @@ void render(float dt, Game *game) {
|
|||||||
BeginMode2D(*camera);
|
BeginMode2D(*camera);
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
drawLayer(game->terrain, &game->terrainTileset);
|
bzTileMapDraw(&game->map);
|
||||||
drawLayer(game->trees, &game->terrainTileset);
|
|
||||||
drawLayer(game->trees2, &game->terrainTileset);
|
|
||||||
drawLayer(game->buildings, &game->buildingsTileset);
|
|
||||||
|
|
||||||
EndMode2D();
|
EndMode2D();
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|||||||
Reference in New Issue
Block a user