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

03 / 08
Sat

Lisp が気になる Ziphil です。

ランダムダンジョン関係の処理が一段落したので、 タイトル画面を作ってみました。 ちなみに、 考えた結果、 ランダムダンジョンの生成アルゴリズムは 4 種類で十分だということになりました。

776A_製作過程A

あれ・・・、 ドット絵・・・?

ドット絵ではないです。 つまりどういうことかというと、 私にはこんなに大きいドット絵は描けないということです。 背景画像は CLOSET 様からお借りしました。

やっぱり青はきれいです。


comment ×0
03 / 07
Fri

RGB 色空間がますます使いにくく感じていく Ziphil です。

Maze 型のダンジョン生成プログラムができました。

775_製作過程A

通路の幅 が 2 マス、 壁の幅が 1 マスになるように作ってあります。 使用したアルゴリズムですが、 よくある 「穴掘り法」 ってやつです。 たぶん。 正直、 穴掘り法の解説を真面目に読んでないので、 本当に私の実装したアルゴリズムが本当に穴掘り法かどうかは分かりませんが。 穴は掘ってますけどね。

そういえば、 プログラムを書きながら、 地味にマップチップを追加してます。 今回のスクリーンショットのマップチップは全部新作ですし、 前の洞窟のチップは壁だけ新作です。 まあ、 プログラムが主だったので、 ちょっと手抜きだったりしなくもないですけど・・・。

にしても、 ドット絵うまくなりたい。


comment ×0
03 / 06
Thu

この欄に書くことが思いつかない Ziphil です。

さて、 これまで Temple 型, Wilderness 型, Cavern 型 の 3 つのランダムダンジョン生成アルゴリズムを作りました。 名前は今適当につけました。

3 種類あれば十分かもしれませんが、 もう 2 種類くらいほしいなー、 と思うわけです。 具体的に言えば、 部屋と通路ではなく迷路のようになっている Maze 型と、 Temple 型 を自然物化させたような空洞と通路で構成される Cave 型です。

Maze 型は有名なアルゴリズムがありますから良いんです、 穴堀り法とか。 問題は Cave 型です。 Temple 型における部屋と通路の生成を、 より自然物っぽく曲線を含ませたものに改良すれば、 それで終わりな気がしますが、 せっかくだし違う方法を採ってみたいです。

穴掘り法っぽい方法で作れそうかなー、 と思うんです。 つまり、 適当な位置から適当に通路を掘っていって、 適当な位置で空洞を作り、 また適当に通路を作る、 みたいな。 このとき、 その場に本当に作れるか調査しならが通路や空洞を作っていけば、 それっぽくなる気がします。

もしくは、 空洞を先に適当に配置して、 適当に通路をつなぐ方法です。 ただ、 この通路をつなぐ処理が、 意外と面倒なんです。 孤立した空洞ができては困りますし、 かえってつなぎすぎも良くありません。

調べてみてもいるんですが、 なかなか良い方法は見つかりませんし。 こう、 エレガントな方法はないんでしょうか。


comment ×0
03 / 05
Wed

ワイエルシュトラス (Weierstrass) のカタカナ表記のブレが気になる Ziphil です。

いろいろあって、 自然物っぽいダンジョンの生成アルゴリズムが完成しました。 先日アルゴリズムの考察を投稿しましたが、 その中のどれとも違う方法で生成してます。 考察とは何だったのか・・・。

アルゴリズムの解説の前に、 完成品を見てもらいましょうか。 こんな感じの洞窟ができます。

773_製作過程A

ぐちゃぐちゃしてますね。 ちょっと荒れすぎな感じもしますが、 これ以上は私の力では無理でした。 全く違うアルゴリズムを考案する必要があるかもしれないですね。

では、 アルゴリズムの解説です。 ちょっと私のコードが煩雑になってしまったので、 今回はコードなしで、 概要だけ説明しますね。

まず、 2 点間を結ぶ通路を作るアルゴリズムを説明します。 この 2 点のうち、 片方を 「スタート地点」 と呼び、 もう片方を 「ゴール地点」 と呼ぶことにします。

マップのそれぞれのマスに、 状態とスコアの 2 つのデータをもたせます。 状態は 「open」 か 「closed」 のどちらかで、 スコアは 5 以下の整数とします。 スコアをもたないマスもあるとします。 初期状態は、 全て closed でスコアなしの状態です。

以下、 参考として図を乗せますが、 open なら明るい色、 closed なら暗い色でマス目を塗ることにしています。 マスの中の数字は、 そのマスのスコアを意味します。 また、 スタート地点を赤の枠で、 ゴール地点を緑の枠で示します。 したがって、 初期状態は以下のようになります。

773_ランダムダンジョン1

スタート地点を、 状態 open, スコア 5 とします。

773_ランダムダンジョン2

マップの中から状態が open であるマスを適当に選び出します。 そのマスの上下左右にあり、 スコアをまだもっていないマスをいくつか選び、 状態を open とします。 全方向を open でも良いですし、 1 個も open にしなくても構いません。 新たに open にしたマスのスコアは、 最初に選んだマスに比べてゴール地点に近づいたなら同じスコア、 遠ざかったなら 2~4 ほど減少させます。 その後、 最初に選んだマスの状態を closed にします。

773_ランダムダンジョン3

上の処理を繰り返します。 なお、 処理の途中でスコアが 0 以下になってしまったマスは、 強制的に状態を closed にします。 ゴール地点にスコアが与えられた時点で、 繰り返しを終了します。

さて、 運が悪いと、 ゴール地点にスコアが与えられる前に、 open のマスがなくなってしまう場合があります。 その場合は、 スコアが与えられているマスのうち、 ゴール地点から最も近いマスの 1 つを open にして、 繰り返しを続行します。

最終的に、 ゴール地点にスコアが与えられると、 マップ全体はこんな感じになります。

773_ランダムダンジョン4

最後に、 スコアが 0 以下のマスとスコアをもっていないマスを壁とし、 スコアが 1 以上のマスを通過可能領域とすれば、 2 点間を結ぶ通路が完成します。

773_ランダムダンジョン5

さて、 後は、 マップ全体に何ヶ所かチェックポイントをとり、 そのチェックポイント同士を結ぶ通路を、 上のアルゴリズムを用いて作成すれば、 ダンジョンの完成です。

さて、 このアルゴリズムのパラメータは、 新たに隣接するマスを open にするときの確率と、 ゴール地点から遠ざかったときに減少させるスコアの量の 2 つです。 この 2 つを適当に調整すれば、 それっぽいダンジョンが作れます。

・・・でもやっぱり、 ちょっと形が荒れすぎですよね。 輪郭を滑らかにできるアルゴリズムをまた考えないといけませんね。


comment ×0
03 / 04
Tue

記事を連投する Ziphil です。

前に作ったランダムダンジョン生成アルゴリズムを微妙に改良しました。 領域の大きさ (幅+高さ) 上位 3 位までの中から適当に選んで、 分割することにしました。 これで、 不自然に大きな部屋が生成されたりすることもなくなり、 きれいな部屋割りのダンジョンができるようになりました。 こんな感じ。

772_製作過程A

それと、 マップの軽量化をしておきました。 どうやら、 オートタイルの処理が重かったみたいです。 マップの描画処理を毎フレーム行うのではなく、 マップ生成時にバッファに全て描画してしまって、 それを毎フレーム画面に表示する形にしました。 これで、 重かったオートタイルの処理を、 マップ生成時 1 回行うだけでよくなりました。 FPS も余裕で 40 をキープしてます。


comment ×0
03 / 03
Mon

Ziphil です。

アルゴリズム考察の続きです。 前回のエントリで、 曲線を使った方法を書きましたが、 もうちょっと具体的にしてみましょう。

まずは、 マップ全体を形作る閉曲線はどうやって描くか? 初期地点を決めて適当に曲げながら線分を描いていく方法を考えましたが、 これでは閉曲線になる保障がありません。 そこで、 最初から閉曲線を作っておいて、 それを曲げていく手法を採ってみようと思います。

  • マップ全体より少し小さめの長方形を作り、 その頂点に時計回りに 0, 1, 2, 3 のデータ値をもったノードを置く。
  • 数値が隣り合っている 2 つのノードを選び、 その中点から少しずれた位置に新たなノードを作成する。このノードは、 選んだ 2 つのノードのデータ値の相加平均のデータ値をもつ。
  • 上の処理を適当な回数繰り返す。

適当な線分描画アルゴリズム (ブレゼンハムのアルゴリズム) を使って、 隣り合うデータ値をもつノード間の線分を描画し、 通過領域とすれば、 洞窟ダンジョンの輪郭が決まります。 このとき、 輪郭の内部の座標を記憶しておきましょうか。

次は、 この閉曲線内に適当に道を作ります。

  • 通過領域から適当に 1 点選び、 内部に向かって適当な長さの線分を引き、 通過領域に変える。
  • 線分の先の点から、 前回引いた線分とのなす角が 60° 未満になるように、 新たな線分を引き、 通過領域に変える。
  • 上の線分を引く処理を、 通過領域に衝突するまで続ける。
  • 最初の処理から順に同じ処理を適当な回数繰り返す。

これで、 輪郭がいくつかの領域に分けられるはずです。 後は、 部屋になる部分を決めます。

  • 輪郭の内部の通過不能領域である点を適当に選ぶ。
  • その点を含む領域を、 部屋として通過可能領域とする。
  • 以上の処理を適当な回数繰り返す。

これで部屋の完成し、 空洞つきの洞窟ダンジョンのマップが完成する・・・と思います。

このアルゴリズムの欠点ですが、 空洞の中央から通路が伸びるということがないことでしょうか。 まあ、 後から通路を追加すれば良いだけの話ですが。 詳しいことは、 実際にコードを書いて動かしてみないことには分かりませんね。 実装はまだ今度やろうと思います。


comment ×0
03 / 03
Mon

Ziphil です。

昨日はランダムダンジョンを自動生成するコードを書いたわけですが、 やっぱりあれを洞窟のダンジョンに使うには不自然。 ということで、 自然物のダンジョンをそれっぽく生成する方法を考えてみます。

昨日のアルゴリズムの何が不自然かと言うと、 一番は部屋の形でしょう。 長方形ですから、 自然物らしくありません。 そこで、 長方形の部屋の角や辺を少し削って、 部屋に丸みを帯びさせるというのが最も簡単です。

根本からアルゴリズムを見直してみましょう。 こんな生成方法が思いつきます。

  • 適当な位置を中心とし、 楕円状の通過領域を作る。
  • 適当な方向に移動し、 同じように楕円状の通過領域を作る。
  • 上の移動を何度か繰り返す。

楕円状の通過領域の形を毎回微妙に変えてやれば、 それっぽい洞窟の通路ができそうです。 まあ、 これだけでは一本道なので、 分岐を作ったりの処理も入れなければなりませんが。

こんな方法も思いつきました。

  • マップ全体に閉曲線の通過領域を描く。
  • 通過領域の適当な 2 点を結ぶ、 適当な曲線の通過領域を描く。
  • 上の曲線の描画を何回か繰り返す。
  • 閉曲線になっている部分をいくつか選び、 その内部を全て通過領域として部屋を作る。

直線要素がなくなるので自然物らしくはなりますが、 閉曲線を描くアルゴリズムが難しそうですね。

さて、 左上にミニマップそ表示するプログラムを追加したので、 昨日のアルゴリズムで生成したランダムダンジョンのサンプルを上げておきましょうか。 サイズは 80×80 です。

771_製作過程A

ちなみに、 変に細長い部屋が作られないように、 領域が縦長なら横に分割し、 領域が横長なら縦に分割するように、 昨日のプログラムを改良してあります。 また、 領域の最小の長さを、 5 から 10 に変更してあります。

上の画像ではよく分かりませんが、 実は FPS が設定値の 40 を下回っています。 やっぱり描画が遅いみたいで、 これは昔 StarRuby のときにやっていた軽量化処理を施さないといけないのでしょうか。


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