diff --git a/CMakeLists.txt b/CMakeLists.txt index 57336dc..2785f03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,11 +14,14 @@ add_executable(PixelDefense game/utils/building_types.h + game/buildings.c + game/buildings.h game/components.h game/entrypoint.c game/main.c game/map_init.c game/map_init.h + game/map_layers.h ) diff --git a/game/buildings.c b/game/buildings.c new file mode 100644 index 0000000..da9db75 --- /dev/null +++ b/game/buildings.c @@ -0,0 +1,106 @@ +#include "buildings.h" + +#include "components.h" +#include "game_state.h" +#include "map_layers.h" + +bool canPlaceBuilding(BzTileMap *map, BuildingType type, BzTile tileX, BzTile tileY) { + i32 sizeX, sizeY; + getBuildingSize(type, &sizeX, &sizeY); + if (sizeX == 0 || sizeY == 0) return false; + + // Ensure that it is within the map + if (tileX < 0 || tileX + sizeX > map->width || + tileY < 0 || tileY + sizeY > map->height) + return false; + + Rectangle buildArea = {tileX * map->tileWidth, tileY * map->tileHeight, + sizeX * map->tileWidth, sizeY * map->tileHeight}; + + // Need to check neighbour tiles + tileX -= 1; + tileY -= 1; + sizeX += 2; + sizeY += 2; + + BzTileLayer *buildLayer = bzTileMapGetLayer(map, LAYER_BUILDINGS); + BzTileset *tileset = bzTileLayerGetTileset(map, buildLayer); + + for (i32 y = tileY; y < tileY + sizeY; y++) { + for (i32 x = tileX; x < tileX + sizeX; x++) { + if (x != tileX && x != tileX + sizeX - 1 && + y != tileY && y != tileY + sizeY - 1) { + // Without padding + BzTile tile = bzTileLayerGetTile(buildLayer, x, y); + tile = bzTilesetGetTile(tileset, tile); + tile = getTileBuilding(tile); + if (tile == BUILDINGS_ROAD) + return false; + } + BzTileCollider collider = bzTileMapGetCollider(map, x, y); + f32 posX = x * map->tileWidth; + f32 posY = y * map->tileHeight; + for (int i = 0; i < BZ_MAP_COLLIDER_DEPTH; i++) { + BzTileShape shape = collider.shapes[i]; + shape.x += posX; + shape.y += posY; + switch (shape.type) { + case BZ_TILE_SHAPE_NONE: + case BZ_TILE_SHAPE_POINT: + break; + case BZ_TILE_SHAPE_RECT: { + Rectangle shapeRec = {shape.x, shape.y, shape.sizeX, shape.sizeY}; + if (CheckCollisionRecs(buildArea, shapeRec)) + return false; + break; + } + case BZ_TILE_SHAPE_ELLIPSE: { + Vector2 pos = {shape.x, shape.y}; + f32 radius = (shape.sizeX + shape.sizeY) * 0.5f; + if (CheckCollisionCircleRec(pos, radius, buildArea)) + return false; + break; + } + } + } + } + } + + return true; +} + +ecs_entity_t placeBuilding(BzTileMap *map, BuildingType type, BzTile tileX, BzTile tileY) { + i32 sizeX, sizeY; + getBuildingSize(type, &sizeX, &sizeY); + ECS_COMPONENT(ECS, TilePosition); + ECS_COMPONENT(ECS, TileSize); + ECS_COMPONENT(ECS, Owner); + + BzTileLayer *buildingLayer = bzTileMapGetLayer(map, LAYER_BUILDINGS); + BzTileset *buildingTileset = bzTileLayerGetTileset(map, buildingLayer); + BzTile buildingTile = getBuildingTile(type); + BZ_ASSERT(buildingTile != -1); + + // Create entity + ecs_entity_t e = ecs_new_id(ECS); + + ecs_set(ECS, e, TilePosition, {.x=tileX, .y=tileY}); + ecs_set(ECS, e, TileSize, {.sizeX=sizeX, .sizeY=sizeY}); + ecs_set(ECS, e, Owner, {.playerID=BUILDINGS_PLAYER_RED}); + + for (i32 y = tileY; y < tileY + sizeY; y++) { + for (i32 x = tileX; x < tileX + sizeX; x++) { + BzTile layerTile = buildingTile + buildingTileset->startID; + bzTileLayerSetTile(buildingLayer, layerTile, x, y, 1, 1); + buildingTile++; + + GAME->entityMap[y * buildingLayer->width + x] = e; + + bzTileMapUpdateCollider(map, x, y); + } + buildingTile += buildingTileset->width - sizeX; + } + + return e; + +} diff --git a/game/buildings.h b/game/buildings.h new file mode 100644 index 0000000..0eff8ac --- /dev/null +++ b/game/buildings.h @@ -0,0 +1,12 @@ +#ifndef PIXELDEFENSE_BUILDINGS_H +#define PIXELDEFENSE_BUILDINGS_H + +#include +#include + +#include "utils/building_types.h" + +bool canPlaceBuilding(BzTileMap *map, BuildingType type, i32 tileX, i32 tileY); +ecs_entity_t placeBuilding(BzTileMap *map, BuildingType type, i32 tileX, i32 tileY); + +#endif //PIXELDEFENSE_BUILDINGS_H diff --git a/game/main.c b/game/main.c index 108d04b..ec250e3 100644 --- a/game/main.c +++ b/game/main.c @@ -1,9 +1,12 @@ +#include + #include "utils/building_types.h" #include "components.h" #include "game_state.h" #include "map_init.h" +#include "map_layers.h" +#include "buildings.h" -#include Game *GAME = NULL; @@ -34,99 +37,6 @@ bool bzMain(BzAppDesc *appDesc, int argc, const char **argv) { return true; } -bool canBuildOn(BzTileMap *map, i32 tileX, i32 tileY, i32 sizeX, i32 sizeY) { - // Ensure that it is within the map - if (tileX < 0 || tileX + sizeX > map->width || - tileY < 0 || tileY + sizeY > map->height) - return false; - - Rectangle buildArea = {tileX * map->tileWidth, tileY * map->tileHeight, - sizeX * map->tileWidth, sizeY * map->tileHeight}; - - // Need to check neighbour tiles - tileX -= 1; - tileY -= 1; - sizeX += 2; - sizeY += 2; - - BzTileLayer *buildLayer = bzTileMapGetLayer(map, LAYER_BUILDINGS); - BzTileset *tileset = bzTileLayerGetTileset(map, buildLayer); - - for (i32 y = tileY; y < tileY + sizeY; y++) { - for (i32 x = tileX; x < tileX + sizeX; x++) { - if (x != tileX && x != tileX + sizeX - 1 && - y != tileY && y != tileY + sizeY - 1) { - // Without padding - BzTile tile = bzTileLayerGetTile(buildLayer, x, y); - tile = bzTilesetGetTile(tileset, tile); - tile = getTileBuilding(tile); - if (tile == BUILDINGS_ROAD) - return false; - } - BzTileCollider collider = bzTileMapGetCollider(map, x, y); - f32 posX = x * map->tileWidth; - f32 posY = y * map->tileHeight; - for (int i = 0; i < BZ_MAP_COLLIDER_DEPTH; i++) { - BzTileShape shape = collider.shapes[i]; - shape.x += posX; - shape.y += posY; - switch (shape.type) { - case BZ_TILE_SHAPE_NONE: - case BZ_TILE_SHAPE_POINT: - break; - case BZ_TILE_SHAPE_RECT: { - Rectangle shapeRec = {shape.x, shape.y, shape.sizeX, shape.sizeY}; - if (CheckCollisionRecs(buildArea, shapeRec)) - return false; - break; - } - case BZ_TILE_SHAPE_ELLIPSE: { - Vector2 pos = {shape.x, shape.y}; - f32 radius = (shape.sizeX + shape.sizeY) * 0.5f; - if (CheckCollisionCircleRec(pos, radius, buildArea)) - return false; - break; - } - } - } - } - } - - return true; -} - -void placeBuilding(BzTileMap *map, BuildingType type, i32 posX, i32 posY, i32 sizeX, i32 sizeY) { - ECS_COMPONENT(ECS, TilePosition); - ECS_COMPONENT(ECS, TileSize); - ECS_COMPONENT(ECS, Owner); - - BzTileLayer *buildingLayer = bzTileMapGetLayer(map, LAYER_BUILDINGS); - BzTileset *buildingTileset = bzTileLayerGetTileset(map, buildingLayer); - BzTile buildingTile = getBuildingTile(type); - BZ_ASSERT(buildingTile != -1); - - // Create entity - ecs_entity_t e = ecs_new_id(ECS); - ecs_set(ECS, e, TilePosition, {.x=posX, .y=posY}); - ecs_set(ECS, e, TileSize, {.sizeX=sizeX, .sizeY=sizeY}); - ecs_set(ECS, e, Owner, {.playerID=BUILDINGS_PLAYER_RED}); - - for (i32 y = posY; y < posY + sizeY; y++) { - for (i32 x = posX; x < posX + sizeX; x++) { - BzTile layerTile = buildingTile + buildingTileset->startID; - bzTileLayerSetTile(buildingLayer, layerTile, x, y, 1, 1); - buildingTile++; - - GAME->entityMap[y * buildingLayer->width + x] = e; - - bzTileMapUpdateCollider(map, x, y); - } - buildingTile += buildingTileset->width - sizeX; - } - - -} - bool init(Game *game) { int screenWidth = 1280; int screenHeight = 720; @@ -213,7 +123,7 @@ void update(float dt, Game *game) { BzTile sizeX = 0, sizeY = 0; getBuildingSize(game->selectedBuilding, &sizeX, &sizeY); - bool canPlace = canBuildOn(&game->map, tileX, tileY, sizeX, sizeY); + bool canPlace = canPlaceBuilding(&game->map, game->selectedBuilding, tileX, tileY); /* Color placeColor = canPlace ? (Color) {0, 255, 0, 200} : @@ -223,7 +133,7 @@ void update(float dt, Game *game) { */ if (canPlace && IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { - placeBuilding(&game->map, game->selectedBuilding, tileX, tileY, sizeX, sizeY); + placeBuilding(&game->map, game->selectedBuilding, tileX, tileY); } } @@ -236,14 +146,7 @@ void render(float dt, Game *game) { bzTileMapDraw(&game->map); bzTileMapDrawColliders(&game->map); - - - - EndMode2D(); - - - } void imguiRender(float dt, Game *game) { diff --git a/game/map_init.c b/game/map_init.c index 50525eb..710da32 100644 --- a/game/map_init.c +++ b/game/map_init.c @@ -1,10 +1,10 @@ #include "map_init.h" -#include "components.h" -#include "game_state.h" - #include +#include "components.h" +#include "game_state.h" +#include "map_layers.h" bool initGameObjectsLayer(BzTileMap *map, BzTileObjectGroup *objectGroup) { for (i32 i = 0; i < objectGroup->objectCount; i++) { diff --git a/game/map_init.h b/game/map_init.h index ae88d2b..e9c7e69 100644 --- a/game/map_init.h +++ b/game/map_init.h @@ -3,21 +3,6 @@ #include -typedef enum Layers { - LAYER_TERRAIN = 0, - LAYER_FOLIAGE, - LAYER_TREES, - LAYER_TREES2, - LAYER_BUILDINGS, - LAYER_BUILDING_OWNER, -} Layers; - -typedef enum ObjectGroup { - OBJECTS_GAME = 0, - OBJECTS_ENTITIES, -} ObjectGroup; - - bool initGameObjectsLayer(BzTileMap *map, BzTileObjectGroup *objectGroup); bool initEntityObjectsLayer(BzTileMap *map, BzTileObjectGroup *objectGroup); diff --git a/game/map_layers.h b/game/map_layers.h new file mode 100644 index 0000000..1a6e8d6 --- /dev/null +++ b/game/map_layers.h @@ -0,0 +1,18 @@ +#ifndef PIXELDEFENSE_ENUMS_H +#define PIXELDEFENSE_ENUMS_H + +typedef enum Layers { + LAYER_TERRAIN = 0, + LAYER_FOLIAGE, + LAYER_TREES, + LAYER_TREES2, + LAYER_BUILDINGS, + LAYER_BUILDING_OWNER, +} Layers; + +typedef enum ObjectGroup { + OBJECTS_GAME = 0, + OBJECTS_ENTITIES, +} ObjectGroup; + +#endif //PIXELDEFENSE_ENUMS_H