Dungeon texturing

This commit is contained in:
Ben
2020-09-02 22:04:42 +01:00
parent 5983601ac5
commit ad419f92e3
10 changed files with 111 additions and 205 deletions

BIN
The Great Machine.exe Normal file

Binary file not shown.

BIN
The Great Machine.zip Normal file

Binary file not shown.

View File

@@ -7,8 +7,8 @@
void Camera::Update(float fTime) void Camera::Update(float fTime)
{ {
if (_Track == nullptr) return; if (_Track == nullptr) return;
Coords.x = _Track->Coords.x; Coords.x = _Track->Coords.x - (ViewPort.x / 2);
Coords.y = _Track->Coords.y; Coords.y = _Track->Coords.y - (ViewPort.y / 2);
} }
void Camera::Input(olc::PixelGameEngine* engine) void Camera::Input(olc::PixelGameEngine* engine)

View File

@@ -0,0 +1,3 @@
#include "Collisions.hpp"

View File

@@ -0,0 +1,6 @@
#ifndef GREATMACHINE_COLLISIONS_H_
#define GREATMACHINE_COLLISIONS_H_
#endif

View File

@@ -1,5 +1,7 @@
#include "Dungeon.hpp" #include "Dungeon.hpp"
#include <algorithm>
#include "Things.hpp" #include "Things.hpp"
#include "Camera.hpp" #include "Camera.hpp"
#include "Logger.hpp" #include "Logger.hpp"
@@ -26,8 +28,10 @@ void Dungeon::Generate()
TileSetDictionary = new TileDictionary(); TileSetDictionary = new TileDictionary();
TileSetDictionary->Register(); TileSetDictionary->Register();
TileSet = new olc::Sprite("res/dungeon_tileset.png");
_Logger.Debug("Texture Loaded: ", TileSet, " ", TileSet->width, " ", TileSet->height); TileSet = new olc::Renderable();
TileSet->Load("res/dungeon_tileset.png");
_Logger.Debug("Texture Loaded: ", TileSet, " ", TileSet->Sprite()->width, " ", TileSet->Sprite()->height);
DungeonWidth = 0; DungeonWidth = 0;
DungeonHeight = 0; DungeonHeight = 0;
@@ -50,7 +54,7 @@ void Dungeon::Generate()
int directionChance = 5; int directionChance = 5;
int roomChance = 5; int roomChance = 5;
int dungeonMinSize = 2000; int dungeonMinSize = 5000;
struct Agent struct Agent
{ {
@@ -59,7 +63,7 @@ void Dungeon::Generate()
}; };
Agent* agent = new Agent(); Agent* agent = new Agent();
agent->x = 20; agent->y = 10; agent->x = 0; agent->y = 0;
agent->direction = rand() % 4; agent->direction = rand() % 4;
_Logger.Debug("Agent ", agent->x, " ", agent->y, " ", agent->direction); _Logger.Debug("Agent ", agent->x, " ", agent->y, " ", agent->direction);
@@ -71,6 +75,8 @@ void Dungeon::Generate()
tiles.push_back({ x, y }); tiles.push_back({ x, y });
}; };
addTile(0, 0);
while (tiles.size() < dungeonMinSize) while (tiles.size() < dungeonMinSize)
{ {
switch (agent->direction) switch (agent->direction)
@@ -82,7 +88,7 @@ void Dungeon::Generate()
} }
addTile(agent->x, agent->y); addTile(agent->x, agent->y);
if (rand() % 100 < directionChance) if (rand() % 200 < directionChance)
{ {
agent->direction = rand() % 4; agent->direction = rand() % 4;
directionChance = 0; directionChance = 0;
@@ -92,7 +98,7 @@ void Dungeon::Generate()
directionChance += 5; directionChance += 5;
} }
if (rand() % 200 < roomChance) if (rand() % 300 < roomChance)
{ {
Room* room = randomRoom(agent->x, agent->y); Room* room = randomRoom(agent->x, agent->y);
for (int x = room->x; x < room->w + room->x; x++) for (int x = room->x; x < room->w + room->x; x++)
@@ -111,13 +117,65 @@ void Dungeon::Generate()
{ {
if (DungeonWidth <= tile.x) DungeonWidth = tile.x; if (DungeonWidth <= tile.x) DungeonWidth = tile.x;
if (DungeonHeight <= tile.y) DungeonHeight = tile.y; 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); ETile::Type tileType = rand() % 100 > 1 ? ETile::Type::Floor : ETile::Type::FloorV1;
auto DoesTileExist = [&](olc::vi2d tile)
{
return std::find(tiles.begin(), tiles.end(), tile) != tiles.end();
};
bool tileBelow = DoesTileExist({ tile.x, tile.y + 1 });
bool tileAbove = DoesTileExist({ tile.x, tile.y - 1 });
bool tileLeft = DoesTileExist({ tile.x - 1, tile.y });
bool tileRight = DoesTileExist({ tile.x + 1, tile.y });
if (!tileAbove)
tileType = ETile::Type::WallU;
if (!tileRight)
tileType = ETile::Type::WallR;
if (!tileBelow)
tileType = ETile::Type::WallD;
if (!tileLeft)
tileType = ETile::Type::WallL;
if (!tileAbove && !tileBelow)
tileType = ETile::Type::PathAcross;
if (!tileRight && !tileLeft)
tileType = ETile::Type::PathUp;
if (!tileAbove && !tileLeft)
tileType = ETile::Type::WallTLCorner;
if (!tileAbove && !tileRight)
tileType = ETile::Type::WallTRCorner;
if (!tileBelow && !tileLeft)
tileType = ETile::Type::WallBLCorner;
if (!tileBelow && !tileRight)
tileType = ETile::Type::WallBRCorner;
if (!tileAbove && !tileBelow && !tileRight)
tileType = ETile::Type::PathRight;
if (!tileAbove && !tileBelow && !tileLeft)
tileType = ETile::Type::PathLeft;
if (!tileRight && !tileLeft && !tileAbove)
tileType = ETile::Type::PathTop;
if (!tileRight && !tileLeft && !tileBelow)
tileType = ETile::Type::PathBottom;
// Is the tile below free? if so, make it 3D
if (!tileBelow)
{
Tile* psuedo3DTile = new Tile({ tile.x, tile.y + 1 },
ETile::Type::ThreeDStandard, ETile::State::Default);
DungeonTiles[psuedo3DTile->Coords] = psuedo3DTile;
}
Tile* t = new Tile(tile, tileType, ETile::State::Default);
DungeonTiles[t->Coords] = t; DungeonTiles[t->Coords] = t;
} }
// Empty rooms // DungeonRenderTarget = new olc::Renderable();
// DungeonRenderTarget->Create(DungeonWidth * 32, DungeonHeight * 32);
} }
void Dungeon::SpawnEntity(Entity* entity) void Dungeon::SpawnEntity(Entity* entity)
@@ -128,13 +186,13 @@ void Dungeon::SpawnEntity(Entity* entity)
void Dungeon::Input(olc::PixelGameEngine* engine, float fTime) void Dungeon::Input(olc::PixelGameEngine* engine, float fTime)
{ {
if (engine->GetKey(olc::W).bHeld) if (engine->GetKey(olc::W).bHeld)
Player->Coords.y += 1 / fTime; Player->Coords.y -= 1000 * fTime;
if (engine->GetKey(olc::A).bHeld) if (engine->GetKey(olc::A).bHeld)
Player->Coords.x += 1 / fTime; Player->Coords.x -= 1000 * fTime;
if (engine->GetKey(olc::S).bHeld) if (engine->GetKey(olc::S).bHeld)
Player->Coords.y -= 1 / fTime; Player->Coords.y += 1000 * fTime;
if (engine->GetKey(olc::D).bHeld) if (engine->GetKey(olc::D).bHeld)
Player->Coords.x -= 1 / fTime; Player->Coords.x += 1000 * fTime;
} }
void Dungeon::Update(float fTime) void Dungeon::Update(float fTime)
@@ -144,21 +202,18 @@ void Dungeon::Update(float fTime)
void Dungeon::Draw(olc::PixelGameEngine* engine) 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<olc::vi2d, Tile*> tile : DungeonTiles) for (std::pair<olc::vi2d, Tile*> tile : DungeonTiles)
{ {
engine->DrawPartialSprite({ (tile.first.x * 16) + ActiveCamera->Coords.x, (tile.first.y * 16) + ActiveCamera->Coords.y }, TileSet, // TODO: Perform culling
TileSetDictionary->Dictionary[tile.second->Type], { 16, 16 }, 1); engine->DrawPartialDecal({ static_cast<float>((tile.first.x * 64) - ActiveCamera->Coords.x), static_cast<float>((tile.first.y * 64) - ActiveCamera->Coords.y) },
{ 64, 64 }, TileSet->Decal(), TileSetDictionary->Dictionary[tile.second->Type], { 16, 16 });
} }
// Draw character
engine->DrawPartialDecal({ static_cast<float>(Player->Coords.x - ActiveCamera->Coords.x), static_cast<float>(Player->Coords.y - ActiveCamera->Coords.y) },
{ 64, 64 }, TileSet->Decal(), { 143, 130 }, { 16, 16 });
} }
Dungeon::~Dungeon() Dungeon::~Dungeon()

View File

@@ -38,7 +38,9 @@ public:
std::unordered_map<olc::vf2d, FixedItem*> FixedItems; std::unordered_map<olc::vf2d, FixedItem*> FixedItems;
TileDictionary* TileSetDictionary; TileDictionary* TileSetDictionary;
olc::Sprite* TileSet; olc::Renderable* TileSet;
// olc::Renderable* DungeonRenderTarget;
~Dungeon(); ~Dungeon();

View File

@@ -91,13 +91,21 @@ namespace EEntity
} }
} }
// AABB
class HitBox
{
public:
int x, y, w, h;
};
class Entity class Entity
{ {
public: public:
olc::vi2d Coords; olc::vi2d Coords;
EEntity::Type Type; EEntity::Type Type;
HitBox* AABBHitBox;
olc::vf2d SpriteTextureMask; olc::vf2d SpriteTextureMask;
olc::Sprite* SpriteMap; olc::Renderable* SpriteMap;
}; };
class Item : public Entity class Item : public Entity
@@ -141,7 +149,7 @@ public:
ETile::State State; ETile::State State;
//olc::vf2d SpriteTextureMask; //olc::vf2d SpriteTextureMask;
//olc::Sprite* SpriteMap; //olc::Renderable* SpriteMap;
virtual void Update(float fTime); virtual void Update(float fTime);
}; };

View File

@@ -1,168 +0,0 @@
#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<olc::vi2d> 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<olc::vi2d, Tile*> 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<olc::vi2d, Tile*> tile : DungeonTiles)
delete tile.second;
}

View File

@@ -48,11 +48,11 @@ public:
// _Logger.Debug(m_TimeAccumilator); // _Logger.Debug(m_TimeAccumilator);
//if (m_TimeAccumilator < 4.0f) if (m_TimeAccumilator < 4.0f)
//{ {
// DisplayTitle(fTime); DisplayTitle(fTime);
// return true; return true;
//} }
_Dungeon->Input(this, fTime); _Dungeon->Input(this, fTime);
@@ -78,7 +78,7 @@ int main()
_Logger.InitializeLoggingThread(); _Logger.InitializeLoggingThread();
Game _Game; Game _Game;
_Game.Construct(1280, 720, 1, 1, false, true); _Game.Construct(1280, 720, 1, 1, false, false);
_Logger.Info("Game Constructed"); _Logger.Info("Game Constructed");
if (!_Game.Start()) if (!_Game.Start())