私は星空を見て遠い世界について考えるのが好きですが、宇宙の無限という事実は私の頭にほとんど収まりません。 ビッグバン理論によれば、私たちの宇宙は絶えず膨張し、特異な状態から冷却していますが、無限の宇宙は特定のルールに従って絶えず生成され、これらのルールの数は限られていると仮定しましょう。 私たちの宇宙はすでに生成されている、つまり、無限宇宙の各ポイントについて、有限数のルールに従って生成がすでに行われていると仮定できます(生成は無限回行われています)。その結果、無限に生成された宇宙があります。
タスクに戻りましょう。マリオタイプのIPhone / iPadゲームのマップを知的に生成する必要があります。まず、128x128キューブのフィールド内でマップを生成することを検討します。
マップエディターで描画できるのに、なぜゲーム用のマップを生成するのですか? iOSゲーム「Tanks」を開発するとき、サーバーにレベルを保存する機能を持つレベルエディターを作成しました。プレーヤー自身がマップを描画して送信することを期待していました。 しかし、現実はより深刻であることが判明し、プレイヤーは何千枚ものカードで私を満たしました。それは穏やかに言えば、未処理で、未完成で、単にいです。 新しいゲームの開発中、私はレベルを自動的に生成し、可能な限りエディタのレベルに匹敵するようにすることを固く決定しました。
私たちは何を持っています:
-マップは128x128ブロックで構成され、各ブロックのサイズは32x32ピクセルです。
-マップは128x128配列として保存されます。
- 0-空のブロック。
- 1-土地、キャラクターはこのブロックに沿ってミックスし、爆発させることができます。
- 2-石-爆破できないブロック。
- 3-宝石の入った箱。
- 4-スパイク、プレイヤーが死ぬときに落ちる;
単純な方法または「ランダム」な方法でのレベル生成
最初に、ランダム化機能を含む単純な式を使用してマップ生成機能を実装することにしました。 式の変数の値を変更することにより、マップを許容可能な状態に調整することを望んでいました。
strong>式は、ゲームマップの次の要素を生成しました。
- フロア:マップ全体が条件付きフロアに分割され、フロア間の距離はランド関数によって決定されました。
- 開口部:ランダムな幅のランダムな数の通路がフロア間に生成されました。
- ノイズ:床にランダムに形成されたブロック。
- 部屋:各階に、ランダムな数の長方形の部屋が1つ、2つの出口、または出口なしで形成されました。
- トレッドミル:プレイヤーがランニング中に加速できるようにするため、各フロアにランダムな数のランニング用の直線パスが生成され、ランダムな高さの「天井」がランダムにそれらのいくつかの上に描かれました。
「ランダム」メソッドを使用したレベル生成の短所
- 多くの場合、フロア間の開口部が上下に重なっているため、レベルはあまりにも速く通過しました。
- レベルは単調すぎるように見えました。
- 地図は見た目があまりにも見苦しかった。
マップを生成するための式の複雑さを改善することにより、より良い結果を達成することができましたが、私は別の方法で移動することにしました。
要件アルゴリズムは満たす必要があります
- このゲームでは、メインキャラクターはポイントAからポイントBに到達する必要があります。
- レベルを上げるとき、プレイヤーは行き止まりで立ち往生したりつまずいたりしてはいけません。
- ジェットパックで飛行するにはスペースが必要です。
パスを使用したレベル生成
カードを生成する方法は? パターンに応じて! また、テンプレート自体には、より小さいテンプレート(サブパターン)が含まれます。
まず、プレイフィールドを8x8の64個の正方形に分割します。これらの正方形のそれぞれについて、テンプレートから値をさらに読み込み、この正方形を「部屋」と呼びます。 したがって、マップは8x8 = 64の部屋で構成されています。
ゲームの本質は、ポイントA(エントリポイント)からポイントB(出口ポイント)に移動し、ある部屋から別の部屋に移動することです。 この場合、入り口は部屋の一番上の行にあり、出口は地図の一番下にあります。
そのため、まず最初に、プレーヤーが移動するルート(パス)を配置する必要があります。 これを行うために、部屋をタイプに分けます:
- 0:メインルートのパス上にない部屋。
- 1:左右へのアクセスが保証されている部屋。
- 2:左、右、下へのアクセスが保証されている部屋。
- 3:左、右、上へのアクセスが保証されている部屋。
このパス生成アルゴリズムはチューリングマシンデバイスに似ており、部屋のマトリックス内を移動する制御デバイス(書き込み/読み取りヘッド)があります。 制御装置の可能な状態の数はもちろん正確に設定され、状態は部屋のタイプに対応します。
- まず、上の行に最初の部屋を置きます。部屋のタイプは1または2にできますが、最初にタイプを1に設定します。
- 次に、移動する方向を決定する必要があります。これは、1または5の場合は1〜5の数字をランダムに取得し、2または3の場合は左に移動し、5の場合は右に移動します。最初の部屋のタイプを1から2に変更しながら下に移動します(開始部屋の下に出口があります)。
- 移動中に、画面の境界が左または右に「静止」する場合、方向を反対に変更します。 下に移動するたびに、現在の部屋のタイプを1から2に書き換える必要があることに注意してください(この部屋には下からの出口があるため)。
- 次の部屋に移動した後、移動した部屋を確認します。 タイプ2の部屋からの場合-私たちの部屋は再びタイプ2(次の出口を下に)またはタイプ3(上、左および右からの出口)を持つことができます。 タイプ2と3の部屋には左側と右側に出口があるため、アルゴリズムを何度も繰り返すことができます。
- すでに最下行にあり、アルゴリズムがさらに下に移動するように提案している場合は、部屋から退出してアルゴリズムを完了します。
この段階で、キャラクターの移動経路を形成しました。アルゴリズムの影響を受けないすべての部屋をゼロで埋めます(0は出口がない可能性のある部屋です)。
アルゴリズムパラメーター
他の特性を持つパスを生成するために、たとえば、どのようにアルゴリズムに影響を与えることができますか?
アルゴリズムの最初の段落で1から7の乱数を選択した場合、数値が1から3に落ちるとき、左に移動し、4から6の数に右に移動し、7が落ちるとき、生成中に各階にさらに部屋ができます「1」と入力すると、パスがわかりにくくなります。 同様に、1から3までの乱数は、パスの曲がりを少なくします。
地図表示
これらのスクリーンショットでは、パスをよりよく表示するために、タイプ「0」の見栄えの悪い部屋を舗装しました。
パターン
各部屋は16x16の正方形で、合計で4種類の部屋があります。部屋の種類ごとに、テンプレートは個別の.plistファイルにあります。
room0.plist
room1.plist
room2.plist
room3.plist
まず、ルームタイプの制限を定義します。タイプ1のルームには下部と上部からの出口がありません。つまり、テンプレートに関係なく、タイプ1のルームの上下の出口はすぐに「閉じる」ことができます。 タイプ2の部屋の場合、下から出口を「閉じ」、タイプ3の部屋の場合-上から出口を閉じます。
タイプ1の各部屋ごとに、プログラムはroom1.plistファイルからテンプレートを選択し、
また、このテンプレートの場合、50%のケースで左から右にミラー反射が行われます。
タイプ1の部屋のパターンの例を考えてみましょう。
テンプレートからマップをコンパイルする場合、次のルールを使用します。
- 0-空のブロック。
- 1-土地、キャラクターはこのブロックに沿ってミックスし、爆発させることができます。
- 2-石-爆破できないブロック。
- 3-宝石の入った箱。
- 4-スパイク、プレイヤーが死ぬときに落ちる;
- 7-「サブパターン」-高さ3、幅5のブロック
- 8-75%の確率で土地がここにあります。 25%-空の可能性。
- 9-50%の確率で土地ができます。
パターンマスキング
テンプレートからマップを収集する場合、大きなマップではブロック付きのセクションが繰り返されますが、私たちのタスクは、1つのテンプレートのフレームワーク内で互いに異なるマップを作成することです。
これを行うには、テンプレートを水平にミラーリングすることに加えて、テンプレートに数字の8と9を入力します。これらの数字は、それぞれ75%と50%の確率で1つ(地球ブロック)に置き換えられます。 GZCH(読み書きヘッド)が番号7でつまずくと、テンプレートのこのセクションは「サブパターン」に置き換えられ、テンプレートと同様のルールに従って読み取られます。
サブパターン
サブパターンは、2つの同一のパターンを互いに異なるものにするためにも導入されています。 テンプレートに数字7があります-アルゴリズムが数字7に出くわした場合、boxTemplate.plistファイルからの「サブパターン」でテンプレートを埋めます
サブパターンの例:
00100
01110
00100
11111
01110
00100
00100
11111
00100
サブパターンについても、ケースの50%で、左から右にミラー反射を行います。
グラフィカルなマップエディタの作成を避けようとしましたが、テンプレートのレンダリングにはまだ実装する必要がありました。 ゲームに追加するテンプレートとサブパターンが多いほど、カードはより多様になります。
「サブパターン」を使用した結果
これらの4つのスクリーンショットでは、同じテンプレートが表示されます。これは、数字7.8.9により、毎回異なって見えます。
ビデオでは、レベル生成が実際にどのように見えるかを見ることができます。
見込み
- テンプレートの数はレベルの品質に直接影響するため、新しいテンプレートを追加するとゲームプレイが大幅に向上します。
- より多様なカードの場合、「サブパターン」で「サブパターン」を作成できます。
- ワールドのスケールとエントリポイントと出口ポイントを変更することで、キャラクターのパス上にブロックを動的に形成し、横断エリアをキャッシュすることで、無限のマップを生成できます。
このトピックに興味があれば、私に知らせてください、私はより詳細にトピックを開きます。
この記事を編集するために、Spelunkyゲームのレベル生成アルゴリズムを部分的に使用しましたが、おそらくより高度なレベル生成を備えたゲームがありますが、それについては知りません。
あなたが知っている良いレベルの世代を持つ他のゲームをコメントに書いてください。
この記事のすべてのエラーをプライベートメッセージに送信してください。