#概要
こちらはRPGに出てくるようなマップを作成する記事です。
何か不備がありましたら指摘していただければ幸いです。
#コード
1秒おきにワールドマップが自動生成されるプログラムです。
Main.cpp
#include "DxLib.h"
//横画面サイズ
#define MAP_X 480
//縦画面サイズ
#define MAP_Y 320
/*チャンク生成*/
void mapMake(int x, int y, int size, int t1, int t2, int t3, int t4, unsigned char map[][18])
{
//再起の終了処理
if (size < 1) return;
//頂点の高さを決める
int mapPlus = ((t1 + t2 + t3 + t4) >> 2) + GetRand(size);
if (mapPlus >= 255) mapPlus = 255;
map[x][y] = mapPlus;
//四角形の2点同士の中点の高さを決定
int s1 = ((t1 + t2) >> 1);
int s2 = ((t1 + t3) >> 1);
int s3 = ((t2 + t4) >> 1);
int s4 = ((t3 + t4) >> 1);
//4つの地点の座標を決める
map[x + size][y] = s3;
map[x - size][y] = s2;
map[x][y + size] = s4;
map[x][y - size] = s1;
//分割サイズを半分にする
size >>= 1;
//4つに分割
mapMake(x - size, y - size, size, t1, s1, s2, map[x][y], map);
mapMake(x + size, y - size, size, s1, t2, map[x][y], s3, map);
mapMake(x - size, y + size, size, s2, map[x][y], t3, s4, map);
mapMake(x + size, y + size, size, map[x][y], s3, s4, t4, map);
}
/*チャンク生成の呼び出し*/
void mapSimple(unsigned char map[][18])
{
//チャンク生成を実行
mapMake(8, 8, 8, map[0][0], map[16][0], map[0][16], map[16][16], map);
}
/*ワールドマップ生成*/
void worldMake(unsigned char map[][18], int SEED, unsigned char WorldMap[][MAP_Y])
{
for (int i = 0; i < MAP_X / 16; i++) {
for (int j = 0; j < MAP_Y / 16; j++) {
//四角形の4点の高さを決定
SRand(SEED + i + j * 10000 + (i&j) * 100);
map[0][0] = GetRand(255);
SRand(SEED + i + 1 + j * 10000 + ((i + 1)&j) * 100);
map[16][0] = GetRand(255);
SRand(SEED + i + (j + 1) * 10000 + (i&(j + 1)) * 100);
map[0][16] = GetRand(255);
SRand(SEED + i + 1 + (j + 1) * 10000 + ((i + 1)&(j + 1)) * 100);
map[16][16] = GetRand(255);
//チャンク生成
mapSimple(map);
for (int i2 = 0; i2 < 16; i2++) {
for (int j2 = 0; j2 < 16; j2++) {
//生成したチャンクをワールドマップにコピペ
WorldMap[i * 16 + i2][j * 16 + j2] = map[i2][j2];
}
}
}
}
for (int i = 0; i < (MAP_X / 16) * 16; i++) {
for (int j = 0; j < (MAP_Y / 16) * 16; j++) {
//ワールドマップの線画
if (WorldMap[i][j] <= 110 && WorldMap[i][j] > 50) {
DrawPixel(i, j, GetColor(WorldMap[i][j], 165, WorldMap[i][j]));
}
else if (WorldMap[i][j] <= 50) {
DrawPixel(i, j, GetColor(WorldMap[i][j], 125, WorldMap[i][j]));
}
else {
DrawPixel(i, j, GetColor((255 - WorldMap[i][j]) / 3, (255 - WorldMap[i][j]) / 3, 240));
}
}
}
//文字列初期化
clsDx();
//SEED値を文字列線画
printfDx("SEED:%d", SEED);
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
//log出力停止・ウィンドウモード変更・初期化・裏画面設定
SetOutApplicationLogValidFlag(FALSE), ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK);
//画面サイズの決定
SetGraphMode(MAP_X, MAP_Y, 32);
//チャンク生成用の配列
unsigned char map[18][18] = { 255 };
//SEED値
int SEED = GetRand(65535);
//ワールドマップ
unsigned char WorldMap[MAP_X][MAP_Y] = { 255 };
//時間
int time = 0;
//ワールドマップを生成する
worldMake(map, SEED, WorldMap);
while (ScreenFlip() == 0 && ProcessMessage() == 0) {
//1秒おきにワールドマップを生成
if (time == 60) {
worldMake(map, GetRand(65535), WorldMap);
time = 0;
}
//ESCキーで終了
if (CheckHitKey(KEY_INPUT_ESCAPE)) break;
//時間を増やす
time++;
}
//DXライブラリの終了処理
DxLib_End();
return 0;
}
RPGに使えそうなマップになりましたね。
こんな感じにアニメーションします。
##ソースコードのライセンス
These codes are licensed under CC0.
ソースコードは自由に使用してください。
#参考
DXライブラリ 関数リファレンスページ
新・C言語 ~ゲームプログラミングの館
フラクタル
フラクタル地形自動生成
中点変位法を使用してマインクラフトのようなランダム地形を Unity で作ってみた