diff --git a/The Great Machine/Camera.cpp b/The Great Machine/Camera.cpp index 33b791c..31dbb7b 100644 --- a/The Great Machine/Camera.cpp +++ b/The Great Machine/Camera.cpp @@ -2,6 +2,8 @@ #include "Things.hpp" +#include "Logger.hpp" + void Camera::Update(float fTime) { if (_Track == nullptr) return; diff --git a/The Great Machine/Camera.hpp b/The Great Machine/Camera.hpp index 9538c76..ffb3e89 100644 --- a/The Great Machine/Camera.hpp +++ b/The Great Machine/Camera.hpp @@ -8,7 +8,7 @@ class Entity; class Camera { public: - olc::vf2d Coords; + olc::vi2d Coords; olc::vi2d ViewPort; void Update(float fTime); diff --git a/The Great Machine/Dungeon.cpp b/The Great Machine/Dungeon.cpp index 6f5d217..5f0748f 100644 --- a/The Great Machine/Dungeon.cpp +++ b/The Great Machine/Dungeon.cpp @@ -5,41 +5,118 @@ #include "Logger.hpp" Dungeon::Dungeon() + : _Logger(Logger::getInstance()) { ActiveCamera = new Camera(); - ActiveCamera->Coords = { 0.0f, 0.0f }; + ActiveCamera->Coords = { 0, 0 }; ActiveCamera->ViewPort = { 1280, 720 }; + + Player = new Playable(); + + Player->Coords = { 0, 0 }; + Player->Type = EEntity::Type::Player; + + ActiveCamera->TrackEntity(Player); + ActiveCamera->Update(0.0f); } void Dungeon::Generate() { + srand(time(NULL)); + TileSetDictionary = new TileDictionary(); TileSetDictionary->Register(); TileSet = new olc::Sprite("res/dungeon_tileset.png"); - Logger::getInstance().Debug("Texture Loaded: ", TileSet, " ", TileSet->width, " ", TileSet->height); + _Logger.Debug("Texture Loaded: ", TileSet, " ", TileSet->width, " ", TileSet->height); - auto index = [](int x, int y, int depth) -> int { return x + depth * y; }; + DungeonWidth = 0; + DungeonHeight = 0; // Generate a dungeon // Loosely follows the algorithm in section 3.3 "Agent Based Growing" // http://pcgbook.com/wp-content/uploads/chapter03.pdf - + struct Room { int x, y, w, h; }; auto randomRoom = [](int x, int y) - { return new Room{ x, y, (rand() % 15) + 5, (rand() % 15) + 5 }; }; + { return new Room{ x, y, (rand() % 7) + 3, (rand() % 7) + 3 }; }; - std::vector rooms; - std::map tiles; + std::vector tiles; // Starting at 0,0 - olc::vi2d agentPos; + int directionChance = 5; + int roomChance = 5; + int dungeonMinSize = 2000; + struct Agent + { + // 0 up 1 right 2 down 3 left + int x, y, direction; + }; + Agent* agent = new Agent(); + agent->x = 20; agent->y = 10; + agent->direction = rand() % 4; + + _Logger.Debug("Agent ", agent->x, " ", agent->y, " ", agent->direction); + + auto addTile = [&](int x, int y) { + for (auto i : tiles) + if (i.x == x && i.y == y) + return; + tiles.push_back({ x, y }); + }; + + while (tiles.size() < dungeonMinSize) + { + switch (agent->direction) + { + case 0: agent->y -= 1; break; + case 1: agent->x += 1; break; + case 2: agent->y += 1; break; + case 3: agent->x -= 1; break; + } + addTile(agent->x, agent->y); + + if (rand() % 100 < directionChance) + { + agent->direction = rand() % 4; + directionChance = 0; + } + else + { + directionChance += 5; + } + + if (rand() % 200 < roomChance) + { + Room* room = randomRoom(agent->x, agent->y); + for (int x = room->x; x < room->w + room->x; x++) + for (int y = room->y; y < room->h + room->y; y++) + addTile(x, y); + delete room; + roomChance = 0; + } + else + { + roomChance += 5; + } + } + + for (auto& tile : tiles) + { + if (DungeonWidth <= tile.x) DungeonWidth = tile.x; + if (DungeonHeight <= tile.y) DungeonHeight = tile.y; + Tile* t = new Tile(tile, ETile::Type::OneByOne, ETile::State::Default); + _Logger.Debug(t->Coords.x, " ", t->Coords.y); + DungeonTiles[t->Coords] = t; + } + + // Empty rooms } @@ -48,19 +125,25 @@ void Dungeon::SpawnEntity(Entity* entity) Entities[entity->Coords] = entity; } -void Dungeon::Input(olc::PixelGameEngine* engine) +void Dungeon::Input(olc::PixelGameEngine* engine, float fTime) { - // engine->GetKey(olc::W); + if (engine->GetKey(olc::W).bHeld) + Player->Coords.y += 1 / fTime; + if (engine->GetKey(olc::A).bHeld) + Player->Coords.x += 1 / fTime; + if (engine->GetKey(olc::S).bHeld) + Player->Coords.y -= 1 / fTime; + if (engine->GetKey(olc::D).bHeld) + Player->Coords.x -= 1 / fTime; } void Dungeon::Update(float fTime) { - + ActiveCamera->Update(fTime); } void Dungeon::Draw(olc::PixelGameEngine* engine) { - // find tile in map auto DrawFrom = [&](int tile) { // mod w for x int div y - JavidX9 @@ -71,20 +154,15 @@ void Dungeon::Draw(olc::PixelGameEngine* engine) auto index = [](int x, int y, int depth) -> int { return x + depth * y; }; - for (int x = 0; x < DungeonWidth; x++) - for (int y = 0; y < DungeonHeight; y++) + for (std::pair tile : DungeonTiles) { - static Logger& _Logger = Logger::getInstance(); - // _Logger.Debug(x, " ", y); - Tile* tile = DungeonTiles[index(x, y, DungeonWidth)]; - - engine->DrawPartialSprite({ x * 32, y * 32 }, TileSet, - TileSetDictionary->Dictionary[tile->Type], { 16, 16 }, 2); + engine->DrawPartialSprite({ (tile.first.x * 16) + ActiveCamera->Coords.x, (tile.first.y * 16) + ActiveCamera->Coords.y }, TileSet, + TileSetDictionary->Dictionary[tile.second->Type], { 16, 16 }, 1); } } Dungeon::~Dungeon() { - for (int i = 0; i < DungeonTiles.size(); i++) - delete DungeonTiles[i]; + for (std::pair tile : DungeonTiles) + delete tile.second; } diff --git a/The Great Machine/Dungeon.hpp b/The Great Machine/Dungeon.hpp index f2c40e9..8df7235 100644 --- a/The Great Machine/Dungeon.hpp +++ b/The Great Machine/Dungeon.hpp @@ -5,6 +5,8 @@ #include "olcPixelGameEngine.hpp" +#include "Logger.hpp" + class Camera; class Tile; @@ -22,7 +24,7 @@ public: void Generate(); void SpawnEntity(Entity* entity); - void Input(olc::PixelGameEngine* engine); + void Input(olc::PixelGameEngine* engine, float fTime); void Update(float fTime); void Draw(olc::PixelGameEngine* engine); @@ -31,7 +33,7 @@ public: int DungeonWidth; int DungeonHeight; - std::vector DungeonTiles; + std::unordered_map DungeonTiles; std::unordered_map Entities; // key here could be room? std::unordered_map FixedItems; @@ -39,6 +41,9 @@ public: olc::Sprite* TileSet; ~Dungeon(); + +private: + Logger& _Logger; }; #endif diff --git a/The Great Machine/enc_temp_folder/12cc409aa7dc26e42313716aeaf49a5/Dungeon.cpp b/The Great Machine/enc_temp_folder/12cc409aa7dc26e42313716aeaf49a5/Dungeon.cpp new file mode 100644 index 0000000..5f0748f --- /dev/null +++ b/The Great Machine/enc_temp_folder/12cc409aa7dc26e42313716aeaf49a5/Dungeon.cpp @@ -0,0 +1,168 @@ +#include "Dungeon.hpp" + +#include "Things.hpp" +#include "Camera.hpp" +#include "Logger.hpp" + +Dungeon::Dungeon() + : _Logger(Logger::getInstance()) +{ + ActiveCamera = new Camera(); + ActiveCamera->Coords = { 0, 0 }; + ActiveCamera->ViewPort = { 1280, 720 }; + + Player = new Playable(); + + Player->Coords = { 0, 0 }; + Player->Type = EEntity::Type::Player; + + ActiveCamera->TrackEntity(Player); + ActiveCamera->Update(0.0f); +} + +void Dungeon::Generate() +{ + srand(time(NULL)); + + TileSetDictionary = new TileDictionary(); + TileSetDictionary->Register(); + TileSet = new olc::Sprite("res/dungeon_tileset.png"); + _Logger.Debug("Texture Loaded: ", TileSet, " ", TileSet->width, " ", TileSet->height); + + DungeonWidth = 0; + DungeonHeight = 0; + + // Generate a dungeon + // Loosely follows the algorithm in section 3.3 "Agent Based Growing" + // http://pcgbook.com/wp-content/uploads/chapter03.pdf + + struct Room + { + int x, y, w, h; + }; + + auto randomRoom = [](int x, int y) + { return new Room{ x, y, (rand() % 7) + 3, (rand() % 7) + 3 }; }; + + std::vector tiles; + + // Starting at 0,0 + + int directionChance = 5; + int roomChance = 5; + int dungeonMinSize = 2000; + + struct Agent + { + // 0 up 1 right 2 down 3 left + int x, y, direction; + }; + + Agent* agent = new Agent(); + agent->x = 20; agent->y = 10; + agent->direction = rand() % 4; + + _Logger.Debug("Agent ", agent->x, " ", agent->y, " ", agent->direction); + + auto addTile = [&](int x, int y) { + for (auto i : tiles) + if (i.x == x && i.y == y) + return; + tiles.push_back({ x, y }); + }; + + while (tiles.size() < dungeonMinSize) + { + switch (agent->direction) + { + case 0: agent->y -= 1; break; + case 1: agent->x += 1; break; + case 2: agent->y += 1; break; + case 3: agent->x -= 1; break; + } + addTile(agent->x, agent->y); + + if (rand() % 100 < directionChance) + { + agent->direction = rand() % 4; + directionChance = 0; + } + else + { + directionChance += 5; + } + + if (rand() % 200 < roomChance) + { + Room* room = randomRoom(agent->x, agent->y); + for (int x = room->x; x < room->w + room->x; x++) + for (int y = room->y; y < room->h + room->y; y++) + addTile(x, y); + delete room; + roomChance = 0; + } + else + { + roomChance += 5; + } + } + + for (auto& tile : tiles) + { + if (DungeonWidth <= tile.x) DungeonWidth = tile.x; + if (DungeonHeight <= tile.y) DungeonHeight = tile.y; + Tile* t = new Tile(tile, ETile::Type::OneByOne, ETile::State::Default); + _Logger.Debug(t->Coords.x, " ", t->Coords.y); + DungeonTiles[t->Coords] = t; + } + + // Empty rooms + +} + +void Dungeon::SpawnEntity(Entity* entity) +{ + Entities[entity->Coords] = entity; +} + +void Dungeon::Input(olc::PixelGameEngine* engine, float fTime) +{ + if (engine->GetKey(olc::W).bHeld) + Player->Coords.y += 1 / fTime; + if (engine->GetKey(olc::A).bHeld) + Player->Coords.x += 1 / fTime; + if (engine->GetKey(olc::S).bHeld) + Player->Coords.y -= 1 / fTime; + if (engine->GetKey(olc::D).bHeld) + Player->Coords.x -= 1 / fTime; +} + +void Dungeon::Update(float fTime) +{ + ActiveCamera->Update(fTime); +} + +void Dungeon::Draw(olc::PixelGameEngine* engine) +{ + // find tile in map + auto DrawFrom = [&](int tile) { + // mod w for x int div y - JavidX9 + int w = tile % (TileSet->width / 16); + int h = tile / (TileSet->width / 16); + return olc::vi2d(w * 16, h * 16); + }; + + auto index = [](int x, int y, int depth) -> int { return x + depth * y; }; + + for (std::pair tile : DungeonTiles) + { + engine->DrawPartialSprite({ (tile.first.x * 16) + ActiveCamera->Coords.x, (tile.first.y * 16) + ActiveCamera->Coords.y }, TileSet, + TileSetDictionary->Dictionary[tile.second->Type], { 16, 16 }, 1); + } +} + +Dungeon::~Dungeon() +{ + for (std::pair tile : DungeonTiles) + delete tile.second; +} diff --git a/The Great Machine/main.cpp b/The Great Machine/main.cpp index 5c6501a..ea989b8 100644 --- a/The Great Machine/main.cpp +++ b/The Great Machine/main.cpp @@ -54,7 +54,9 @@ public: // return true; //} - _Dungeon->Input(this); + _Dungeon->Input(this, fTime); + + _Dungeon->Update(fTime); _Dungeon->Draw(this);