Moved generation parameters to yaml.
This commit is contained in:
parent
9c4feb7636
commit
831975cf10
4 changed files with 40 additions and 17 deletions
15
res/yaml/generation.yaml
Normal file
15
res/yaml/generation.yaml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Whenever tiles are generated, rectangles of this side length are created.
|
||||||
|
generate_area_size: 4
|
||||||
|
|
||||||
|
# Distance in pixels to which areas should be generated.
|
||||||
|
generate_area_range: 1200.0
|
||||||
|
|
||||||
|
# Deciding factor in how big individual rooms will be. Higher value means bigger rooms.
|
||||||
|
room_size_value: 10.0
|
||||||
|
|
||||||
|
# Deciding factor in how long connections between rooms may be and how many there may be.
|
||||||
|
# Higher value means more and/or longer paths.
|
||||||
|
room_connection_value: 5.0
|
||||||
|
|
||||||
|
# The chance that an enemy is placed in a certain tile, must be in [0, 1]. Higher value means more enemies.
|
||||||
|
enemy_generation_chance: 0.075
|
|
@ -22,7 +22,7 @@
|
||||||
Game::Game(tgui::Window& window) :
|
Game::Game(tgui::Window& window) :
|
||||||
mWindow(window),
|
mWindow(window),
|
||||||
mWorldView(Vector2f(0, 0), mWindow.getView().getSize()),
|
mWorldView(Vector2f(0, 0), mWindow.getView().getSize()),
|
||||||
mGenerator(mWorld, mPathfinder) {
|
mGenerator(mWorld, mPathfinder, Yaml("generation.yaml")) {
|
||||||
mWindow.setFramerateLimit(FPS_GOAL);
|
mWindow.setFramerateLimit(FPS_GOAL);
|
||||||
mWindow.setKeyRepeatEnabled(false);
|
mWindow.setKeyRepeatEnabled(false);
|
||||||
srand(time(nullptr));
|
srand(time(nullptr));
|
||||||
|
|
|
@ -19,11 +19,17 @@
|
||||||
#include "../Pathfinder.h"
|
#include "../Pathfinder.h"
|
||||||
#include "../World.h"
|
#include "../World.h"
|
||||||
#include "../sprites/Enemy.h"
|
#include "../sprites/Enemy.h"
|
||||||
|
#include "../util/Yaml.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates new random seed.
|
* Generates new random seed.
|
||||||
*/
|
*/
|
||||||
Generator::Generator(World& world, Pathfinder& pathfinder) :
|
Generator::Generator(World& world, Pathfinder& pathfinder, const Yaml& config) :
|
||||||
|
mAreaSize(config.get("generate_area_size", 1)),
|
||||||
|
mMaxRange((config.get("generate_area_range", 1.0f) / mAreaSize) / Tile::TILE_SIZE.x),
|
||||||
|
mRoomSizeValue(config.get("room_size_value", 1.0f)),
|
||||||
|
mRoomConnectionValue(config.get("room_connection_value", 1.0f)),
|
||||||
|
mEnemyGenerationChance(config.get("enemy_generation_chance", 0.0f) * 2 - 1),
|
||||||
mWorld(world),
|
mWorld(world),
|
||||||
mPathfinder(pathfinder) {
|
mPathfinder(pathfinder) {
|
||||||
}
|
}
|
||||||
|
@ -40,7 +46,7 @@ Generator::generateCurrentAreaIfNeeded(const Vector2f& playerPosition,
|
||||||
|
|
||||||
Vector2i start((int) floor(playerPosition.x / Tile::TILE_SIZE.x),
|
Vector2i start((int) floor(playerPosition.x / Tile::TILE_SIZE.x),
|
||||||
(int) floor(playerPosition.y / Tile::TILE_SIZE.y));
|
(int) floor(playerPosition.y / Tile::TILE_SIZE.y));
|
||||||
start /= GENERATE_AREA_SIZE;
|
start /= mAreaSize;
|
||||||
auto makePair = [&start](const Vector2i& point) {
|
auto makePair = [&start](const Vector2i& point) {
|
||||||
return std::make_pair(point, thor::length(Vector2f(point - start)));
|
return std::make_pair(point, thor::length(Vector2f(point - start)));
|
||||||
};
|
};
|
||||||
|
@ -51,11 +57,11 @@ Generator::generateCurrentAreaIfNeeded(const Vector2f& playerPosition,
|
||||||
float distance = open[current];
|
float distance = open[current];
|
||||||
open.erase(current);
|
open.erase(current);
|
||||||
closed.insert(current);
|
closed.insert(current);
|
||||||
if (!mGenerated[current.x][current.y] && distance <= GENERATE_AREA_RANGE) {
|
if (!mGenerated[current.x][current.y] && distance <= mMaxRange) {
|
||||||
mGenerated[current.x][current.y] = true;
|
mGenerated[current.x][current.y] = true;
|
||||||
sf::IntRect area(current * GENERATE_AREA_SIZE -
|
sf::IntRect area(current * mAreaSize -
|
||||||
Vector2i(GENERATE_AREA_SIZE, GENERATE_AREA_SIZE) / 2,
|
Vector2i(mAreaSize, mAreaSize) / 2,
|
||||||
Vector2i(GENERATE_AREA_SIZE, GENERATE_AREA_SIZE));
|
Vector2i(mAreaSize, mAreaSize));
|
||||||
generateTiles(area);
|
generateTiles(area);
|
||||||
for (const auto& spawn : getEnemySpawns(area)) {
|
for (const auto& spawn : getEnemySpawns(area)) {
|
||||||
float distance = thor::length(spawn - playerPosition);
|
float distance = thor::length(spawn - playerPosition);
|
||||||
|
@ -64,7 +70,7 @@ Generator::generateCurrentAreaIfNeeded(const Vector2f& playerPosition,
|
||||||
mWorld, mPathfinder, spawn, playerItems)));
|
mWorld, mPathfinder, spawn, playerItems)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mGenerated[current.x][current.y] && distance <= GENERATE_AREA_RANGE) {
|
if (mGenerated[current.x][current.y] && distance <= mMaxRange) {
|
||||||
if (closed.find(Vector2i(current.x + 1, current.y)) == closed.end())
|
if (closed.find(Vector2i(current.x + 1, current.y)) == closed.end())
|
||||||
open.insert(makePair(Vector2i(current.x + 1, current.y)));
|
open.insert(makePair(Vector2i(current.x + 1, current.y)));
|
||||||
if (closed.find(Vector2i(current.x, current.y + 1)) == closed.end())
|
if (closed.find(Vector2i(current.x, current.y + 1)) == closed.end())
|
||||||
|
@ -158,7 +164,7 @@ Generator::connectRooms(const Vector2i& start) {
|
||||||
destinations.insert(current);
|
destinations.insert(current);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (distance.at(current) < ROOM_CONNECTION_VALUE) {
|
if (distance.at(current) < mRoomConnectionValue) {
|
||||||
process(Vector2i(current.x + 1, current.y), current);
|
process(Vector2i(current.x + 1, current.y), current);
|
||||||
process(Vector2i(current.x, current.y + 1), current);
|
process(Vector2i(current.x, current.y + 1), current);
|
||||||
process(Vector2i(current.x - 1, current.y), current);
|
process(Vector2i(current.x - 1, current.y), current);
|
||||||
|
@ -167,7 +173,7 @@ Generator::connectRooms(const Vector2i& start) {
|
||||||
}
|
}
|
||||||
|
|
||||||
float totalValue = 0.0f;
|
float totalValue = 0.0f;
|
||||||
while (totalValue < ROOM_CONNECTION_VALUE && !destinations.empty()) {
|
while (totalValue < mRoomConnectionValue && !destinations.empty()) {
|
||||||
std::vector<Vector2i> path;
|
std::vector<Vector2i> path;
|
||||||
float pathValue = 0;
|
float pathValue = 0;
|
||||||
Vector2i current = *destinations.begin();
|
Vector2i current = *destinations.begin();
|
||||||
|
@ -214,7 +220,7 @@ Generator::generateTiles(const sf::IntRect& area) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Vector2i> selected = createMinimalSpanningTree(start, ROOM_SIZE_VALUE);
|
std::vector<Vector2i> selected = createMinimalSpanningTree(start, mRoomSizeValue);
|
||||||
|
|
||||||
// For rooms, take minimum bounding box of spanning tree.
|
// For rooms, take minimum bounding box of spanning tree.
|
||||||
|
|
||||||
|
@ -261,7 +267,7 @@ Generator::getEnemySpawns(const sf::IntRect& area) {
|
||||||
for (int x = area.left; x < area.left + area.width; x++) {
|
for (int x = area.left; x < area.left + area.width; x++) {
|
||||||
for (int y = area.top; y < area.top + area.height; y++) {
|
for (int y = area.top; y < area.top + area.height; y++) {
|
||||||
float noise = mCharacterNoise.getNoise(x, y);
|
float noise = mCharacterNoise.getNoise(x, y);
|
||||||
if (noise <= -0.85f) {
|
if (noise <= mEnemyGenerationChance) {
|
||||||
Vector2i tilePosition = findClosestFloor(Vector2i(x, y));
|
Vector2i tilePosition = findClosestFloor(Vector2i(x, y));
|
||||||
spawns.push_back(Vector2f(tilePosition.x * Tile::TILE_SIZE.x,
|
spawns.push_back(Vector2f(tilePosition.x * Tile::TILE_SIZE.x,
|
||||||
tilePosition.y * Tile::TILE_SIZE.y));
|
tilePosition.y * Tile::TILE_SIZE.y));
|
||||||
|
|
|
@ -17,13 +17,14 @@
|
||||||
|
|
||||||
class World;
|
class World;
|
||||||
class Pathfinder;
|
class Pathfinder;
|
||||||
|
class Yaml;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Procedurally generates tiles, chooses player and enemy spawn positions.
|
* Procedurally generates tiles, chooses player and enemy spawn positions.
|
||||||
*/
|
*/
|
||||||
class Generator : public sf::Drawable {
|
class Generator : public sf::Drawable {
|
||||||
public:
|
public:
|
||||||
explicit Generator(World& world, Pathfinder& pathfinder);
|
explicit Generator(World& world, Pathfinder& pathfinder, const Yaml& config);
|
||||||
void generateCurrentAreaIfNeeded(const Vector2f& position,
|
void generateCurrentAreaIfNeeded(const Vector2f& position,
|
||||||
const Character::EquippedItems& playerItems);
|
const Character::EquippedItems& playerItems);
|
||||||
Vector2f getPlayerSpawn() const;
|
Vector2f getPlayerSpawn() const;
|
||||||
|
@ -42,10 +43,11 @@ private:
|
||||||
void draw(sf::RenderTarget& target, sf::RenderStates states) const;
|
void draw(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr int GENERATE_AREA_SIZE = 4;
|
const int mAreaSize;
|
||||||
static constexpr float GENERATE_AREA_RANGE = 4.0f;
|
const float mMaxRange;
|
||||||
static constexpr float ROOM_SIZE_VALUE = 10.0f;
|
const float mRoomSizeValue;
|
||||||
static constexpr float ROOM_CONNECTION_VALUE = 5.0f;
|
const float mRoomConnectionValue;
|
||||||
|
const float mEnemyGenerationChance;
|
||||||
|
|
||||||
World& mWorld;
|
World& mWorld;
|
||||||
Pathfinder& mPathfinder;
|
Pathfinder& mPathfinder;
|
||||||
|
|
Reference in a new issue