feat: get_biome method for Chunk

Signed-off-by: szdytom <szdytom@qq.com>
This commit is contained in:
方而静 2025-08-01 22:51:41 +08:00
parent 5af0239ab1
commit 416eabd31f
Signed by: szTom
GPG Key ID: 072D999D60C6473C
7 changed files with 83 additions and 56 deletions

View File

@ -6,6 +6,7 @@ set(ISTD_TILEMAP_SRC
src/tilemap.cpp
src/noise.cpp
src/biome.cpp
src/chunk.cpp
)
# Create the tilemap library

View File

@ -5,7 +5,7 @@
The tilemap library provides a flexible system for generating and managing tile-based terrain with biome support. The library consists of several main components:
- **TileMap**: The main map container holding chunks of tiles
- **Chunk**: 64x64 tile containers with biome information
- **Chunk**: 64x64 tile containers with biome information
- **Tile**: Individual map tiles with base and surface types
- **TerrainGenerator**: Procedural terrain generation system
- **Biome System**: Climate-based terrain variation
@ -20,11 +20,11 @@ The main container for the entire map, organized as an n×n grid of chunks.
class TileMap {
public:
explicit TileMap(std::uint8_t size);
std::uint8_t get_size() const;
Chunk& get_chunk(std::uint8_t chunk_x, std::uint8_t chunk_y);
const Chunk& get_chunk(std::uint8_t chunk_x, std::uint8_t chunk_y) const;
Tile& get_tile(const TilePos& pos);
const Tile& get_tile(const TilePos& pos) const;
void set_tile(const TilePos& pos, const Tile& tile);
@ -41,11 +41,15 @@ Each chunk contains 64×64 tiles and sub-chunk biome information.
```cpp
struct Chunk {
static constexpr uint8_t size = 64; // Tiles per side
static constexpr uint8_t subchunk_size = /* certain value */; // Tiles per sub-chunk side
static constexpr uint8_t subchunk_size = 4; // Tiles per sub-chunk side
static constexpr uint8_t subchunk_count = size / subchunk_size; // Sub-chunks per side
Tile tiles[size][size]; // 64x64 tile grid
BiomeType biome[subchunk_count][subchunk_count];
BiomeType biome[subchunk_count][subchunk_count]; // Sub-chunk biomes
// Get biome for a specific sub-chunk position
BiomeType& get_biome(const SubChunkPos& pos);
const BiomeType& get_biome(const SubChunkPos& pos) const;
};
```
@ -62,7 +66,7 @@ struct Tile {
**Base Tile Types:**
- `Land`: Standard ground terrain
- `Mountain`: Rocky elevated terrain
- `Mountain`: Rocky elevated terrain
- `Sand`: Desert/beach terrain
- `Water`: Water bodies
- `Ice`: Frozen terrain
@ -79,12 +83,29 @@ Position structure for locating tiles within the map.
```cpp
struct TilePos {
uint8_t chunk_x; // Chunk X coordinate
uint8_t chunk_y; // Chunk Y coordinate
uint8_t chunk_y; // Chunk Y coordinate
uint8_t local_x; // Tile X within chunk (0-63)
uint8_t local_y; // Tile Y within chunk (0-63)
};
```
### SubChunkPos
Position within a chunk's sub-chunk grid.
```cpp
struct SubChunkPos {
std::uint8_t sub_x;
std::uint8_t sub_y;
constexpr SubChunkPos(std::uint8_t x, std::uint8_t y);
};
std::pair<std::uint8_t, std::uint8_t> subchunk_to_tile_start(
const SubChunkPos& pos
);
```
## Terrain Generation
### GenerationConfig
@ -94,17 +115,17 @@ Configuration parameters for terrain generation.
```cpp
struct GenerationConfig {
std::uint64_t seed = 0; // Seed for random generation
// Temperature noise parameters
double temperature_scale = 0.005; // Scale for temperature noise
int temperature_octaves = 3; // Number of octaves for temperature noise
double temperature_persistence = 0.4; // Persistence for temperature noise
// Humidity noise parameters
double humidity_scale = 0.005; // Scale for humidity noise
int humidity_octaves = 3; // Number of octaves for humidity noise
double humidity_persistence = 0.4; // Persistence for humidity noise
// Base terrain noise parameters
double base_scale = 0.08; // Scale for base terrain noise
int base_octaves = 3; // Number of octaves for base terrain noise
@ -118,7 +139,7 @@ struct GenerationConfig {
- `temperature_scale`: Controls the scale/frequency of temperature variation across the map
- `temperature_octaves`: Number of noise octaves for temperature (more octaves = more detail)
- `temperature_persistence`: How much each octave contributes to temperature noise (0.0-1.0)
- `humidity_scale`: Controls the scale/frequency of humidity variation across the map
- `humidity_scale`: Controls the scale/frequency of humidity variation across the map
- `humidity_octaves`: Number of noise octaves for humidity
- `humidity_persistence`: How much each octave contributes to humidity noise (0.0-1.0)
- `base_scale`: Controls the scale/frequency of base terrain height variation
@ -176,7 +197,7 @@ public:
**Key Features:**
- **Calibration**: Samples noise distribution to build CDF
- **Uniform Mapping**: Maps raw Perlin values to uniform [0,1] distribution
- **Uniform Mapping**: Maps raw Perlin values to uniform [0,1] distribution
- **Balanced Output**: Ensures even distribution across all value ranges
- **Automatic Use**: TerrainGenerator uses this internally for balanced terrain
@ -189,7 +210,7 @@ Available biome types based on temperature and humidity.
```cpp
enum class BiomeType : std::uint8_t {
SnowyPeeks, // Cold & Dry
SnowyPlains, // Cold & Moderate
SnowyPlains, // Cold & Moderate
FrozenOcean, // Cold & Wet
Plains, // Temperate & Dry
Forest, // Temperate & Moderate
@ -208,7 +229,7 @@ Properties that control terrain generation for each biome.
struct BiomeProperties {
std::string_view name; // Biome name
double water_ratio; // Water generation ratio
double ice_ratio; // Ice generation ratio
double ice_ratio; // Ice generation ratio
double sand_ratio; // Sand generation ratio
double land_ratio; // Land generation ratio
int base_octaves = 3; // Noise octaves
@ -223,21 +244,6 @@ const BiomeProperties& get_biome_properties(BiomeType biome);
BiomeType determine_biome(double temperature, double humidity);
```
### SubChunkPos
Position within a chunk's sub-chunk grid.
```cpp
struct SubChunkPos {
std::uint8_t sub_x;
std::uint8_t sub_y;
};
constexpr std::pair<std::uint8_t, std::uint8_t> subchunk_to_tile_start(
const SubChunkPos& pos
);
```
## Usage Examples
### Basic Map Generation
@ -258,7 +264,7 @@ config.temperature_scale = 0.005;
config.temperature_octaves = 3;
config.temperature_persistence = 0.4;
// Humidity noise settings
// Humidity noise settings
config.humidity_scale = 0.005;
config.humidity_octaves = 3;
config.humidity_persistence = 0.4;
@ -295,10 +301,18 @@ const auto& tile2 = chunk.tiles[32][32];
### Working with Biomes
```cpp
// Get biome for a sub-chunk
// Method 1: Direct array access (traditional way)
const auto& chunk = tilemap.get_chunk(0, 0);
istd::BiomeType biome = chunk.biome[1][1]; // Sub-chunk (1,1)
// Method 2: Using SubChunkPos and get_biome method (recommended)
istd::SubChunkPos pos(1, 1); // Sub-chunk (1,1)
istd::BiomeType biome2 = chunk.get_biome(pos);
// Modify biome using the new method
auto& mutable_chunk = tilemap.get_chunk(0, 0);
mutable_chunk.get_biome(pos) = istd::BiomeType::Forest;
// Get biome properties
const auto& props = istd::get_biome_properties(biome);
std::cout << "Biome: " << props.name << std::endl;

View File

@ -41,10 +41,6 @@ struct BiomeProperties {
double ice_ratio;
double sand_ratio;
double land_ratio;
// Noise parameters for base terrain
int base_octaves = 3;
double base_persistence = 0.5;
};
// Get biome properties for terrain generation
@ -53,18 +49,6 @@ const BiomeProperties &get_biome_properties(BiomeType biome);
// Determine biome type based on temperature and humidity
BiomeType determine_biome(double temperature, double humidity);
struct SubChunkPos {
std::uint8_t sub_x;
std::uint8_t sub_y;
constexpr SubChunkPos(std::uint8_t x, std::uint8_t y): sub_x(x), sub_y(y) {}
};
// Get the starting tile coordinates for a sub-chunk
std::pair<std::uint8_t, std::uint8_t> subchunk_to_tile_start(
const SubChunkPos &pos
);
} // namespace istd
#endif

View File

@ -8,6 +8,14 @@ namespace istd {
// Forward declaration
enum class BiomeType : std::uint8_t;
// Position within a chunk's sub-chunk grid
struct SubChunkPos {
std::uint8_t sub_x;
std::uint8_t sub_y;
constexpr SubChunkPos(std::uint8_t x, std::uint8_t y): sub_x(x), sub_y(y) {}
};
// Represents the position of a tile in the map, using chunk and local
// coordinates
struct TilePos {
@ -32,8 +40,23 @@ struct Chunk {
// array of biomes for sub-chunks
BiomeType biome[subchunk_count][subchunk_count];
// Get biome for a specific sub-chunk position
BiomeType &get_biome(const SubChunkPos &pos) {
return biome[pos.sub_x][pos.sub_y];
}
// Get biome for a specific sub-chunk position (const version)
const BiomeType &get_biome(const SubChunkPos &pos) const {
return biome[pos.sub_x][pos.sub_y];
}
};
// Get the starting tile coordinates for a sub-chunk
std::pair<std::uint8_t, std::uint8_t> subchunk_to_tile_start(
const SubChunkPos &pos
);
} // namespace istd
#endif

View File

@ -119,11 +119,4 @@ BiomeType determine_biome(double temperature, double humidity) {
return static_cast<BiomeType>(index);
}
std::pair<std::uint8_t, std::uint8_t> subchunk_to_tile_start(
const SubChunkPos &pos
) {
// Convert sub-chunk position to tile start coordinates
return {pos.sub_x * Chunk::subchunk_size, pos.sub_y * Chunk::subchunk_size};
}
} // namespace istd

12
tilemap/src/chunk.cpp Normal file
View File

@ -0,0 +1,12 @@
#include "chunk.h"
namespace istd {
std::pair<std::uint8_t, std::uint8_t> subchunk_to_tile_start(
const SubChunkPos &pos
) {
// Convert sub-chunk position to tile start coordinates
return {pos.sub_x * Chunk::subchunk_size, pos.sub_y * Chunk::subchunk_size};
}
} // namespace istd

View File

@ -74,7 +74,7 @@ void TerrainGenerator::generate_chunk(
for (std::uint8_t sub_x = 0; sub_x < Chunk::subchunk_count; ++sub_x) {
for (std::uint8_t sub_y = 0; sub_y < Chunk::subchunk_count; ++sub_y) {
SubChunkPos sub_pos(sub_x, sub_y);
BiomeType biome = chunk.biome[sub_x][sub_y];
BiomeType biome = chunk.get_biome(sub_pos);
generate_subchunk(tilemap, chunk_x, chunk_y, sub_pos, biome);
}
}