-
-
Notifications
You must be signed in to change notification settings - Fork 87
RPG World Map Cliff
Kasugaccho edited this page Aug 22, 2020
·
3 revisions
高さ情報を反映した(崖が追加された)RPGのワールドマップを画像出力するプログラムです。
#include <DTL.hpp>
#include <DTL/ImageWrite.hpp>
#include <cstddef>
#include <cstdint>
#include <new>
#include <memory>
int main() {
using shape_t = std::uint_fast16_t;
constexpr std::size_t size_x{ 512 };
constexpr std::size_t size_y{ 512 };
//温度
std::unique_ptr<shape_t[][size_x] > temperature(new(std::nothrow) shape_t[size_y][size_x]);
dtl::shape::PerlinIsland<shape_t>(12.0, 6, 240, 100).draw(temperature, size_x, size_y);
//降水量
std::unique_ptr<shape_t[][size_x] > amount_of_rainfall(new(std::nothrow) shape_t[size_y][size_x]);
dtl::shape::PerlinIsland<shape_t>(12.0, 6, 225).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::PerlinSolitaryIsland<shape_t>(0.3, 0.4, 7.0, 6, 155).draw(elevation, size_x, size_y);
std::unique_ptr<shape_t[][size_x] > land(new(std::nothrow) shape_t[size_y][size_x]);
//バイオーム
std::unique_ptr<shape_t[][size_x] > biome(new(std::nothrow) shape_t[size_y][size_x]);
//崖
std::unique_ptr<shape_t[][size_x] > elevation2(new(std::nothrow) shape_t[size_y][size_x]);
enum : std::size_t {
field_sea, //海
field_lake, //湖
field_mountain, //山
field_desert, //砂漠
field_forest, //森林
field_rock, //岩山
field_hill, //丘
field_savannah, //サバンナ
field_grass, //草原
field_cliff, //崖
field, //通常の地面
field_num
};
//バイオームの分類分け
for (std::size_t row{}; row < size_y; ++row)
for (std::size_t col{}; col < size_x; ++col) {
temperature[row][col] -= elevation[row][col] / 2;
land[row][col] = 1;
if (elevation[row][col] < 110) {
biome[row][col] = field_sea;
land[row][col] = 0;
}
else if (temperature[row][col] < 45) biome[row][col] = field_rock;
else if (amount_of_rainfall[row][col] < 25) biome[row][col] = field_savannah;
else if (amount_of_rainfall[row][col] < 75) {
if (temperature[row][col] < 120) biome[row][col] = field_desert;
else biome[row][col] = field_desert;
}
else if (temperature[row][col] < 69) biome[row][col] = field_grass;
else if (temperature[row][col] < 96) biome[row][col] = field;
else if (temperature[row][col] < 120) biome[row][col] = field_forest;
else if (amount_of_rainfall[row][col] < 125) biome[row][col] = field_mountain;
else if (temperature[row][col] < 132) biome[row][col] = field_mountain;
else biome[row][col] = field_mountain;
if (elevation[row][col] < 110) {
elevation2[row][col] = 0;
}
else {
if (elevation[row][col] < 110 + 5) elevation2[row][col] = 0;
else elevation2[row][col] = (elevation[row][col] - 110 + 15) / 12;
}
}
dtl::retouch::Bucket<shape_t>(1, 0, 0).draw(land, size_x, size_y);
for (std::size_t row{}; row < size_y; ++row)
for (std::size_t col{}; col < size_x; ++col) {
if (elevation[row][col] < 110 && land[row][col] == 0) biome[row][col] = field_lake;
}
for (std::size_t col{}; col < size_x; ++col) {
//for (std::size_t row{ size_y - 1 };; --row) {
for (std::size_t row{}; row < size_y; ++row) {
//崖の場合
if (elevation2[row][col] >= 1) {
const auto ev = elevation2[row][col];
const bool is_over{ (ev > row) };
if(!is_over) biome[row - ev][col] = biome[row][col] + field_num * elevation2[row][col];
for (std::size_t row2{ row }, row_min{ (((ev - 1) >= row) ? 0 : (row - (ev - 1))) };; --row2) {
biome[row2][col] = field_cliff;
if (row2 <= row_min) break;
}
}
}
}
dtl::storage::FilePNG<shape_t>("file_sample_rpg_world_map_cliff.png", 3).write(biome, size_x, size_y, [](const shape_t value, unsigned char* const color) {
const double height = 1.0 / (value / (field_num * 8.0) + 1.0);
const auto value2 = value % field_num;
switch (value2) {
case field_sea:
color[0] = 33;
color[1] = 97;
color[2] = 124;
break;
case field_lake:
color[0] = 88;
color[1] = 124;
color[2] = 139;
break;
case field_mountain:
color[0] = 101;
color[1] = 100;
color[2] = 60;
break;
case field_desert:
color[0] = 217;
color[1] = 195;
color[2] = 143;
break;
case field_forest:
color[0] = 110;
color[1] = 149;
color[2] = 59;
break;
case field_rock:
color[0] = 120;
color[1] = 125;
color[2] = 108;
break;
case field_hill:
color[0] = 145;
color[1] = 177;
color[2] = 113;
break;
case field_savannah:
color[0] = 144;
color[1] = 140;
color[2] = 73;
break;
case field_grass:
color[0] = 90;
color[1] = 128;
color[2] = 63;
break;
case field_cliff:
color[0] = 111*2/3;
color[1] = 102*2/3;
color[2] = 68*2/3;
break;
case field:
color[0] = 139;
color[1] = 181;
color[2] = 59;
break;
}
color[0] = static_cast<unsigned char>(color[0] * height);
color[1] = static_cast<unsigned char>(color[1] * height);
color[2] = static_cast<unsigned char>(color[2] * height);
});
return 0;
}出力画像(512×512px)

ドット絵(40×40px, 1マス)のワールドマップ(8000×8000px, 200マス)のサンプル画像です。
![]()
Copyright (c) 2018-2021 As Project.
Distributed under the Boost Software License, Version 1.0.(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)