スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ランダムダンジョン生成プログラム

現在ローグライクゲームを作っているのですが、
ランダムなダンジョンを生成する処理は完成してます。

で、もしかしたら参考になるかもしれないので、公開してみます。
(需要はあるのだろうか?)

【ダンジョンの作り方】
-----------------------------------------------------------
①2次元配列のマップを、いくつかの領域に分ける
②領域ごとに、部屋を作る
③部屋から道を伸ばし、つなげる
④余分な道を消す

-----------------------------------------------------------
自分がやっている方法は以上です。

作り方

【補足】
ここからは補足です。
まず①領域分割について。
【1】下記の様な構造体を用意します。
---------------------------------------------------
typedef struct{
  int pt_x;  //左上の頂点座標
  int pt_y;  //左上の頂点座標
  int width;  //横幅
  int height;  //縦幅
}Range;

---------------------------------------------------

【2】構造体の配列を3つ用意します。
-----------------------------------------------------
Range range[30];     //分割対象の領域を入れる
Range temp_range[30];  //一時記憶用
Range room[30];      //部屋の情報を記憶する

-----------------------------------------------------
(添え字オーバーにならないように、多めに配列を用意しています。
        動的確保しても良いのですが、今回は単純な対応策をとってみました。)


【3】range[0]に初期状態の領域情報を入れ、分割して行く。
※初期状態は、30×30の二次元配列であれば、このようになります。
-------------
range[0].pt_x = 0;
range[0].pt_y = 0;
range[0].width = 30;
range[0].height = 30;

-------------
あと、下記の変数も必要です。
int RANGE_COUNT = 1;
int TEMP_RANGE_COUNT = 0;

分割の流れ
【大まかな流れ図。クリックで拡大】
分割は、縦か横に、2分していくという規則にしてます。
2等分だと、出来上がるダンジョンのレパートリーが減ってしまう)

※部屋を作る方法は割愛。

そしてもう一つ。③道を作る方法について。
「どうしたら確実に部屋が繋がるの?」と感じるかもしれませんが、コレは簡単です。

下記の画像を見ても分かるように、分割した場合、出来た部屋が境界線をはさむ形になります。
したがって、境界線に向かって道を作れば必ず部屋は繋がります。
繋がる

※余分な道を削除する方法も割愛。

---------------------------------------------------------------------
【このプログラムの長所】
ダンジョン生成の規則上、主人公が二次元配列外に出る可能性が無い。
(if(player.pt_x + 1 < WIDTH)という様な判定式は無くせる)

【このプログラムの短所】
全ての部屋が、かならずどこかの部屋に繋がってしまう。
(行き止まりのあるダンジョン、一本道のダンジョンは作れない)
---------------------------------------------------------------------

需要があるのかは分かりませんが、プログラムの方も知りたいという方がいれば、
気軽にコメント下さい(`・ω・´)

(アップローダーなどを利用して、公開しようかなと思います)

【追記】
アップした記事へ飛ぶ
スポンサーサイト

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

コメント

No title

単純に2分していくだけなら。再帰表現もありですね。
一つの大部屋をどんどん細かく分割していく、2分木みたいな感じで。
typedef struct{
  Range* rangeA = null;
  Range* rangeB = null;
  int pt_x;  //左上の頂点座標
  int pt_y;  //左上の頂点座標
  int width;  //横幅
  int height;  //縦幅
}Range;

function void makeDungeon(Range* range, int number) {
  if(number <= 0) { return; }
  {
    int w = rand()%width;
    range->rangeA = new Range(pt_x, pt_y, w, height);
    range->rangeB = new Range(pt_x+w, pt_y, width-w, height);
  }
  makeDungeon(range->rangeA ,number-1);
  makeDungeon(range->rangeB ,number-1);
}
文法とかは、てきとーです。ぜんぜんC言語使えないです(笑)
私だったらたぶん、こうやって作ってます。

> 【このプログラムの短所】
> 全ての部屋が、かならずどこかの部屋に繋がってしまう。
短所でなく、こういうアルゴリズムであって、バラエティーに富んだダンジョンを生成するならアルゴリズムを切り替えていくしかないと思いました。

No title

おぉ再帰を使えば、結構短く出来そうですね 参考になりますe-454
(自分はぷよぷよの様な、同じ色が何個繋がっているか?再帰を使わずに無理やり実現させよう として、酷いことになった経験があります)

そうですね
部屋生成クラスを派生させて、
部屋生成アルゴリズムNo.1~No.6みたいなものを作り、
適宜 その中から一つアルゴリズムを選ぶという様にすれば応用が利きそうですv-290
道を作った後に部屋を作るといった方法もあるみたいですし、
色々と挑戦してみようと思いますv-411

No title

できればソースが見てみたいです

No title

分かりましたv-290
自分自身、まだまだプログラミングが上手い訳ではないので
参考になるかは分からないのですが、UPしてみようと思います。
(就職活動があるので、UP出来るのは今日か明日の深夜 になると思います(_ _) )

No title

自分はC#で風来のシレン(?)みたいなんを作りました。
マッピングのアルゴリズムはほとんど同じですが、再帰でもないしいらない道も削除できてませんw
ですがC#だとJAVAに比べGUIが豊富だったりと、はるかに楽にできましたし、アイテムなどほとんどない状態ですので、プログラム自体としては800行程度になりましたね。

No title

おぉそうなのですかv-291
C#は自分は使ったこと無いですが、800行はかなり短いですねe-451

自分は、
----------------------------------------------
●ストック可能な消費アイテム(弓矢15本など)
●装備品の装備
●一気に2歩動ける敵の登場
●属性攻撃でダメージ2倍
----------------------------------------------
こんな感じで、いろんな機能を実装して行ったところ、
ソースコードが目も当てられない状態になってしまいました。
(それでも、なんとか動いてくれた)

もう一度 ローグライクゲームを作ってみようかなとか思ってますv-290
で、今度はマップを立体にしようかなーと考えてたりします。
(橋の下をくぐる、などが出来る)

是非とも

プログラムを教えて頂きたい

No title

http://blog-imgs-30.fc2.com/r/u/d/rudora7/RandumMap.txt

コメントありがとうございます!v-411
結構前に作ったので、ログを漁って見つけました。

上記がランダムダンジョン生成プログラムになりますv-290

No title

unityのテスト生成プログラム
http://fukaken.rosx.net/
コメントの投稿
管理者にだけ表示を許可する



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。