Bonjour à tous,
Dans le cadre d’un développement de jeu vidéo, je cherche à faire une tile map 2D aléatoire sur des grandes dimensions. J’ai partitionné ma map en différents chunks de tuiles. Du coup j’arrive à charger/générer des chunks assez rapidement et je les stockes de nouveau sur le disque dur une fois qu’ils sont trop loin de mon joueur pour en garder qu’une quantité limité en mémoire (pour l’instant 25)
Cependant le soucis vient dès que je souhaite faire des biomes. Pour cela, je détermine des centres avec un positionnement pseudo-aléatoire par rapport à une grille. Je défini un espacement par défaut entre chaque centre auquel je viens ajouter un offset aléatoire. Ces centres contiennent aussi de la donnée concernant différents paramètres (par soucis de simplicité, seulement le type de biome pour le moment)
Lorsque je génère par la suite un chunk, pour chaque tuile composant ce chunk je récupère les centres à priori les plus proches via leur positionnement de base dans le maillage et ensuite je détermine dans cet ensemble restreint le centre de biome le plus proche et j’associe à la tuile les infos de ce centre
Pour éviter de garder une grille énorme en mémoire, je pensais à la stocker dans un fichier sur le DD. Je cherche cependant une solution à la fois "facile" à utiliser et la plus rapide et efficace en mémoire (cette solution n’existe peut-être pas). Pour l’instant j’ai trouvé les deux extrêmes : créer un fichier par centre de biome ou mettre tous les biomes dans un seul fichier. Le problème que je vois avec le premier c’est juste le nombre énorme de fichier qui va se créer. Cependant, ça sera très simple à utiliser par la suite. J’aurais juste besoin de récupérer le fichier correspondant aux quelques centres de biomes dont j’ai pour le moment besoin. La deuxième me semble pas idéale non plus. Elle est probablement la plus compacte mais me semble compliqué à être utilisé car trouver un centre dans le fichier impliquerait de la parcourir entièrement (au pire du cas)
Du coup, je viens vers vous pour d’autres idées d’implémentation possible permettant soit le stockage sur DD de manière simple et optimisé ou une manière de garder ça en mémoire sans faire ramer mon jeu comme pas possible.
Vous trouverez le code de génération ci-dessous :
// CHUNK_SIZE = 16
// MAP_SIZE = 500
// MIN_DISTANCE_VORONOI_CENTER = 10
// TILE_SIZE = 32px, pour l'affichage, du coup une tile peut-être considéré comme une unité
// voronoiCenters = std::map<int,std::map<int,std::unique_ptr<BiomeCenter>>
// génération des centres
// biomeDistribution(rd) = jet aléatoire entre 1 et 4 pour un type de biome
int nbTiles = CHUNK_SIZE * MAP_SIZE;
int nbTilesOffset = (nbTiles % MIN_DISTANCE_VORONOI_CENTER) / 2;
int limit = nbTiles / (2 * MIN_DISTANCE_VORONOI_CENTER) + nbTilesOffset;
for (int i = -limit; i < limit; i++) {
for (int j = -limit; j < limit; j++) {
double xoffset = distribution(rd);
double yoffset = distribution(rd);
voronoiCenters[i][j] = std::make_unique<BiomeCenter>(
(i)*MIN_DISTANCE_VORONOI_CENTER + nbTilesOffset + xoffset,
(j)*MIN_DISTANCE_VORONOI_CENTER + nbTilesOffset + yoffset,
biomeDistribution(rd));
}
}
// Génération d'un chunk
for (int i = 0; i < CHUNK_SIZE; i++) {
for (int j = 0; j < CHUNK_SIZE; j++) {
double centerX = pos.x + TILE_SIZE * i;
double centerY = pos.y + TILE_SIZE * j;
centerX += TILE_SIZE / 2;
centerY += TILE_SIZE / 2;
std::vector<BiomeCenter*> centers =
parent->getNearestPoints(centerX / TILE_SIZE, centerY / TILE_SIZE);
BiomeCenter* nearest = centers[0];
double minDist = dist(nearest->x * TILE_SIZE, nearest->y * TILE_SIZE, centerX, centerY);
for (auto& c : centers) {
double distance = dist(c->x * TILE_SIZE, c->y * TILE_SIZE, centerX, centerY);
if (distance < minDist) {
nearest = c;
minDist = distance;
}
}
tiles.push_back(std::make_unique<Tile>(
glm::vec2(pos.x + TILE_SIZE * i, pos.y + TILE_SIZE * j), nearest->type));
}
}
// getNearestPoint() :
int x = indexI / MIN_DISTANCE_VORONOI_CENTER; // coords du centre situé le plus proche en haut à gauche de la tuile
int y = indexJ / MIN_DISTANCE_VORONOI_CENTER;
std::vector<BiomeCenter*> nearestPoints;
for (int i = -1; i < 3; i++) {
for (int j = -1; j < 3; j++) {
if (voronoiCenters.find(x + i) != voronoiCenters.end() &&
voronoiCenters.at(x + i).find(y + j) != voronoiCenters.at(x + i).end()) {
nearestPoints.push_back(voronoiCenters.at(i + x).at(y + j).get());
}
}
}
return nearestPoints;
//BiomeCenter
struct BiomeCenter {
double x;
double y;
int type;
BiomeCenter(double mX, double mY, int mType) : x(mX), y(mY), type(mType) {}
BiomeCenter() : x(0), y(0), type(0) {}
friend std::istream& operator>>(std::istream& in, BiomeCenter& c) {
in >> c.x;
in >> c.y;
in >> c.type;
return in;
}
friend std::ostream& operator<<(std::ostream& out, BiomeCenter& c) {
out << c.x << " ";
out << c.y << " ";
out << c.type << " ";
return out;
}
};
Merci d’avance pour votre aide, ça fait 1 semaine non stop que je me casse la tête sur ce problème