🌏母なる大地を創造する🌏
今回はパーリンノイズ法を用いたバイオーム生成について簡単に解説します。
🌏パーリンノイズとは🌏
**"パーリンノイズ"は地形生成に適した"ノイズアルゴリズム"です。
あの超有名なゲームである"マインクラフト"**でも使われています。
また、マインクラフトのワールドでは バイオームを生成 しており
様々な生物群系 を取り入れています。
🌏前回紹介した生成の応用🌏
[DTL]地形生成(パーリンノイズ法)🌏
で紹介したパーリンノイズ法による地形自動生成を用いてバイオームを作っていきます。
🌏バイオームを作るために必要なモノ🌏
バイオーム生成には
"年平均気温"と"年降水量"に近似した2つの変数が必要です。
🌏バイオーム変数を定義🌏
using shape_t = std::uint_fast8_t;
constexpr std::size_t size_x{ 512 };
constexpr std::size_t size_y{ 512 };
//温度
std::unique_ptr<float[][size_x] > temperature(new(std::nothrow) float[size_y][size_x]);
dtl::shape::PerlinIsland<float>(6.0, 8, -20.0f, 60.0f).draw(temperature, size_x, size_y);
//降水量
std::unique_ptr<std::uint_fast16_t[][size_x] > amount_of_rainfall(new(std::nothrow) std::uint_fast16_t[size_y][size_x]);
dtl::shape::PerlinIsland<std::uint_fast16_t>(6.0, 8, 0, 4500).draw(amount_of_rainfall, size_x, size_y);
//標高
std::unique_ptr<shape_t[][size_x] > elevation(new(std::nothrow) shape_t[size_y][size_x]);
dtl::shape::PerlinIsland<shape_t>(6.0, 8, 200).draw(elevation, size_x, size_y);
//バイオーム
std::unique_ptr<shape_t[][size_x] > biome(new(std::nothrow) shape_t[size_y][size_x]);
"年平均気温"と"年降水量"に近似した2つの変数を作成しました。
処理がしやすいように単純にしています。
この2つの変数を用いてバイオーム分けしていきます。
ここで、標高といったまた別の変数が定義されていますが
これは 陸地と海を区別するため に用います。
🌏バイオームを生成🌏
for (std::size_t row{}; row < size_y; ++row)
for (std::size_t col{}; col < size_x; ++col) {
//海
if (elevation[row][col] < 90) biome[row][col] = 0;
//ツンドラ
else if (temperature[row][col] < -5.0f) biome[row][col] = 1;
//砂漠
else if (amount_of_rainfall[row][col] < 500) biome[row][col] = 2;
else if (amount_of_rainfall[row][col] < 1500) {
//ステップ
if (temperature[row][col] < 20.0f) biome[row][col] = 3;
//サバンナ
else biome[row][col] = 4;
}
//針葉樹林
else if (temperature[row][col] < 3.0f) biome[row][col] = 5;
//夏緑樹林
else if (temperature[row][col] < 12.0f) biome[row][col] = 6;
//照葉樹林
else if (temperature[row][col] < 20.0f) biome[row][col] = 7;
//雨緑樹林
else if (amount_of_rainfall[row][col] < 2500) biome[row][col] = 8;
//亜熱帯多雨林
else if (temperature[row][col] < 24.0f) biome[row][col] = 9;
//熱帯多雨林
else biome[row][col] = 10;
}
図の数値通りにバイオーム分けするプログラムを書きます。
"年平均気温"と"年降水量"と"標高"を用いて作成したバイオーム。
海と陸地を分けている。
🌏バイオーム画像の保存🌏
dtl::storage::FilePNG<shape_t>("file_sample_biome.png", 3).write(biome, size_x, size_y, [](const shape_t value, unsigned char* const color) {
switch (value) {
//海
case 0:
color[0] = 41;color[1] = 40;color[2] = 159;
break;
//ツンドラ
case 1:
color[0] = 218;color[1] = 217;color[2] = 225;
break;
//砂漠
case 2:
color[0] = 223;color[1] = 203;color[2] = 140;
break;
//ステップ
case 3:
color[0] = 188;color[1] = 205;color[2] = 146;
break;
//サバンナ
case 4:
color[0] = 164;color[1] = 143;color[2] = 50;
break;
//針葉樹林
case 5:
color[0] = 97;color[1] = 154;color[2] = 96;
break;
//夏緑樹林
case 6:
color[0] = 101;color[1] = 163;color[2] = 56;
break;
//照葉樹林
case 7:
color[0] = 9;color[1] = 100;color[2] = 5;
break;
//雨緑樹林
case 8:
//亜熱帯多雨林
case 9:
//熱帯多雨林
case 10:
color[0] = 43;color[1] = 84;color[2] = 41;
break;
}
});
return 0;
}
生成したバイオームの画像をPNG形式で保存します。
これで出力は完了です。
🌏完成🌏
無事に実装できました。
🌏実装ライブラリ(ソースコード)🌏
今回解説した地形自動生成は**"Dungeon Template Library"に"PerlinIsland"**として実装されています。
ぜひ、活用してみてください!
🌏ソースコードのライセンス🌏
These codes are licensed under CC0.
この記事のソースコードはCC0ライセンスとします。
ぜひ、自由に改変して遊んでみてください。
"いいね"をつけてくださると大変励みになります。
最後までお読みいただきありがとうございました!