UPD: Refactor Forest Tile Generation to seperate method
This commit is contained in:
parent
f6beaf48ea
commit
5213987719
@ -73,6 +73,12 @@ add_executable(Dicewars_Siedler src/main.cpp
|
|||||||
src/engine/renderer/shaders/TerrainShader.h
|
src/engine/renderer/shaders/TerrainShader.h
|
||||||
src/engine/renderer/model/AssetManager.cpp
|
src/engine/renderer/model/AssetManager.cpp
|
||||||
src/engine/renderer/model/AssetManager.h
|
src/engine/renderer/model/AssetManager.h
|
||||||
|
src/game/hexWorld/tileGenerator/HexTileGeneratorStrategy.cpp
|
||||||
|
src/game/hexWorld/tileGenerator/HexTileGeneratorStrategy.h
|
||||||
|
src/game/hexWorld/tileGenerator/ForestTileGenerator.cpp
|
||||||
|
src/game/hexWorld/tileGenerator/ForestTileGenerator.h
|
||||||
|
src/engine/toolbox/Random.cpp
|
||||||
|
src/engine/toolbox/Random.h
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(Dicewars_Siedler PRIVATE
|
target_include_directories(Dicewars_Siedler PRIVATE
|
||||||
|
|||||||
5
src/engine/toolbox/Random.cpp
Normal file
5
src/engine/toolbox/Random.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 08.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Random.h"
|
||||||
38
src/engine/toolbox/Random.h
Normal file
38
src/engine/toolbox/Random.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 08.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef RANDOM_H
|
||||||
|
#define RANDOM_H
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
|
||||||
|
class Random {
|
||||||
|
public:
|
||||||
|
Random() : gen(std::random_device{}()) {};
|
||||||
|
|
||||||
|
// Float zwischen min und max
|
||||||
|
float randomFloat(float min, float max) {
|
||||||
|
std::uniform_real_distribution<float> dist(min, max);
|
||||||
|
return dist(gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Int zwischen min und max (inklusive)
|
||||||
|
int randomInt(int min, int max) {
|
||||||
|
std::uniform_int_distribution<int> dist(min, max);
|
||||||
|
return dist(gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool mit Wahrscheinlichkeit p
|
||||||
|
bool randomBool(float probability = 0.5f) {
|
||||||
|
std::bernoulli_distribution dist(probability);
|
||||||
|
return dist(gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mt19937 gen;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //RANDOM_H
|
||||||
@ -10,27 +10,20 @@
|
|||||||
#include "HexTile.h"
|
#include "HexTile.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
#include "../../engine/renderer/model/AssetManager.h"
|
#include "../../engine/renderer/model/AssetManager.h"
|
||||||
|
#include "../../engine/toolbox/Random.h"
|
||||||
|
#include "tileGenerator/ForestTileGenerator.h"
|
||||||
|
|
||||||
class MapGenerator {
|
class MapGenerator {
|
||||||
public:
|
public:
|
||||||
static void generateHexMap(Map& map, int width, int height, float hexRadius, std::vector<std::shared_ptr<Entity>>& mapEntities) {
|
static void generateHexMap(Map& map, int width, int height, float hexRadius, std::vector<std::shared_ptr<Entity>>& mapEntities) {
|
||||||
// Zufallsgenerator initialisieren (einmal)
|
// Zufallsgenerator initialisieren (einmal)
|
||||||
std::random_device rd; // Zufälliger Seed
|
Random random;
|
||||||
std::mt19937 gen(rd()); // Mersenne Twister Generator
|
|
||||||
|
|
||||||
// Verteilung definieren: hier z.B. 0 bis 9
|
|
||||||
std::uniform_real_distribution<float> dis(0.0f, 1.0f);
|
|
||||||
map.tiles.clear();
|
map.tiles.clear();
|
||||||
|
|
||||||
float xOffset = hexRadius * std::sqrt(3.0f);
|
float xOffset = hexRadius * std::sqrt(3.0f);
|
||||||
float zOffset = hexRadius * 1.5f;
|
float zOffset = hexRadius * 1.5f;
|
||||||
|
|
||||||
std::shared_ptr<TexturedModel> treeModel = AssetManager::getModel("lowPolyTree");
|
|
||||||
std::shared_ptr<TexturedModel> treeModel2 = AssetManager::getModel("lowPolyTree2");
|
|
||||||
std::vector<std::shared_ptr<TexturedModel>> treeModels = {treeModel, treeModel2};
|
|
||||||
|
|
||||||
std::uniform_int_distribution<int> treeModelDistribution(0, treeModels.size() - 1);
|
|
||||||
|
|
||||||
for (int r = 0; r < height; ++r) {
|
for (int r = 0; r < height; ++r) {
|
||||||
for (int q = 0; q < width; ++q) {
|
for (int q = 0; q < width; ++q) {
|
||||||
HexTile tile;
|
HexTile tile;
|
||||||
@ -43,53 +36,20 @@ public:
|
|||||||
tile.worldPos = glm::vec3(x, 0.0f, z);
|
tile.worldPos = glm::vec3(x, 0.0f, z);
|
||||||
tile.radius = hexRadius;
|
tile.radius = hexRadius;
|
||||||
|
|
||||||
float randomValue = dis(gen);
|
float randomValue = random.randomFloat(0.0f, 1.0f);
|
||||||
if (randomValue < 0.5f) {
|
if (randomValue < 0.5f) {
|
||||||
tile.resourceType = RessourceType::WOOD;
|
tile.resourceType = RessourceType::WOOD;
|
||||||
|
ForestTileGenerator forestTileGenerator;
|
||||||
int treeCount = 3 + (int) (dis(gen) * 3);
|
const std::vector<std::shared_ptr<Entity>> forestEntities = forestTileGenerator.generateHexTile(random, tile.worldPos, mapEntities);
|
||||||
std::uniform_real_distribution<float> offsetDis(-hexRadius * 0.5f, hexRadius * 0.5f);
|
tile.entitiesOnTile = forestEntities;
|
||||||
|
|
||||||
float minDistance = 3.0f; // Minimaler Abstand zwischen Bäumen
|
|
||||||
|
|
||||||
for (int i = 0; i < treeCount; ++i) {
|
|
||||||
glm::vec3 treePos;
|
|
||||||
bool validPos = false;
|
|
||||||
|
|
||||||
// versuche zufällige Position, bis Abstand stimmt oder max Versuche erreicht
|
|
||||||
int attempts = 0;
|
|
||||||
const int maxAttempts = 10;
|
|
||||||
|
|
||||||
while (!validPos && attempts < maxAttempts) {
|
|
||||||
treePos = tile.worldPos;
|
|
||||||
treePos.x += offsetDis(gen);
|
|
||||||
treePos.z += offsetDis(gen);
|
|
||||||
|
|
||||||
validPos = true;
|
|
||||||
for (const auto& otherTree : tile.entitiesOnTile) {
|
|
||||||
if (glm::distance(treePos, otherTree->getPosition()) < minDistance) {
|
|
||||||
validPos = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
attempts++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!validPos) continue; // zu viele Versuche, überspringen
|
|
||||||
|
|
||||||
int treeModelIndex = treeModelDistribution(gen);
|
|
||||||
auto treeEntity = std::make_shared<Entity>(treeModels[treeModelIndex], treePos, 0, 0, 0, 1.f);
|
|
||||||
mapEntities.push_back(treeEntity);
|
|
||||||
tile.entitiesOnTile.push_back(treeEntity);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map.tiles.push_back(tile);
|
map.tiles.push_back(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
48
src/game/hexWorld/tileGenerator/ForestTileGenerator.cpp
Normal file
48
src/game/hexWorld/tileGenerator/ForestTileGenerator.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 08.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "ForestTileGenerator.h"
|
||||||
|
|
||||||
|
#include "../../../engine/renderer/model/AssetManager.h"
|
||||||
|
#include "glm/detail/func_geometric.inl"
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Entity>> ForestTileGenerator::generateHexTile(Random& random, glm::vec3 tilePos, std::vector<std::shared_ptr<Entity>> &mapEntities) const {
|
||||||
|
int treeCount = random.randomInt(minTreeCount, maxTreeCount);
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Entity>> entitiesOnTile;
|
||||||
|
std::shared_ptr<TexturedModel> treeModel = AssetManager::getModel("lowPolyTree");
|
||||||
|
std::shared_ptr<TexturedModel> treeModel2 = AssetManager::getModel("lowPolyTree2");
|
||||||
|
std::vector<std::shared_ptr<TexturedModel>> treeModels = {treeModel, treeModel2};
|
||||||
|
for (int i = 0; i < treeCount; ++i) {
|
||||||
|
glm::vec3 treePos;
|
||||||
|
bool validPos = false;
|
||||||
|
|
||||||
|
// versuche zufällige Position, bis Abstand stimmt oder max Versuche erreicht
|
||||||
|
int attempts = 0;
|
||||||
|
|
||||||
|
while (!validPos && attempts < maxAttempts) {
|
||||||
|
treePos = tilePos;
|
||||||
|
treePos.x += random.randomFloat(-hexRadius * 0.5f, hexRadius * 0.5f);
|
||||||
|
treePos.z += random.randomFloat(-hexRadius * 0.5f, hexRadius * 0.5f);
|
||||||
|
|
||||||
|
validPos = true;
|
||||||
|
for (const auto& otherTree : entitiesOnTile) {
|
||||||
|
if (glm::distance(treePos, otherTree->getPosition()) < minDistance) {
|
||||||
|
validPos = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
attempts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!validPos) continue; // zu viele Versuche, überspringen
|
||||||
|
|
||||||
|
int treeModelIndex = random.randomInt(0, static_cast<int>(treeModels.size()-1));
|
||||||
|
auto treeEntity = std::make_shared<Entity>(treeModels[treeModelIndex], treePos, 0, 0, 0, 1.f);
|
||||||
|
mapEntities.push_back(treeEntity);
|
||||||
|
entitiesOnTile.push_back(treeEntity);
|
||||||
|
}
|
||||||
|
return entitiesOnTile;
|
||||||
|
}
|
||||||
24
src/game/hexWorld/tileGenerator/ForestTileGenerator.h
Normal file
24
src/game/hexWorld/tileGenerator/ForestTileGenerator.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 08.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef FORESTTILEGENERATOR_H
|
||||||
|
#define FORESTTILEGENERATOR_H
|
||||||
|
#include "HexTileGeneratorStrategy.h"
|
||||||
|
|
||||||
|
|
||||||
|
class ForestTileGenerator : public HexTileGeneratorStrategy {
|
||||||
|
public:
|
||||||
|
std::vector<std::shared_ptr<Entity>> generateHexTile(Random& random, glm::vec3 tilePos, std::vector<std::shared_ptr<Entity>>& mapEntities) const override;
|
||||||
|
private:
|
||||||
|
const int minTreeCount = 3;
|
||||||
|
const int maxTreeCount = 5;
|
||||||
|
const float minDistance = 3.0f;
|
||||||
|
const int maxAttempts = 10;
|
||||||
|
|
||||||
|
const float hexRadius = 10.f;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //FORESTTILEGENERATOR_H
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 08.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "HexTileGeneratorStrategy.h"
|
||||||
23
src/game/hexWorld/tileGenerator/HexTileGeneratorStrategy.h
Normal file
23
src/game/hexWorld/tileGenerator/HexTileGeneratorStrategy.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// Created by sebastian on 08.02.26.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HEXTILEGENERATORSTRATEGY_H
|
||||||
|
#define HEXTILEGENERATORSTRATEGY_H
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "../../../engine/layer/entities/Entity.h"
|
||||||
|
#include "../../../engine/toolbox/Random.h"
|
||||||
|
|
||||||
|
|
||||||
|
class HexTileGeneratorStrategy {
|
||||||
|
public:
|
||||||
|
virtual ~HexTileGeneratorStrategy() = default;
|
||||||
|
|
||||||
|
virtual std::vector<std::shared_ptr<Entity>> generateHexTile(Random& random, glm::vec3 tilePos, std::vector<std::shared_ptr<Entity>>& mapEntities) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //HEXTILEGENERATORSTRATEGY_H
|
||||||
Loading…
Reference in New Issue
Block a user