iOSゲームのインテリジェントレベルの自動生成アルゴリズム



私は星空を見て遠い世界について考えるのが好きですが、宇宙の無限という事実は私の頭にほとんど収まりません。 ビッグバン理論によれば、私たちの宇宙は絶えず膨張し、特異な状態から冷却していますが、無限の宇宙は特定のルールに従って絶えず生成され、これらのルールの数は限られていると仮定しましょう。 私たちの宇宙はすでに生成されている、つまり、無限宇宙の各ポイントについて、有限数のルールに従って生成がすでに行われていると仮定できます(生成は無限回行われています)。その結果、無限に生成された宇宙があります。

タスクに戻りましょう。マリオタイプのIPhone / iPadゲームのマップを知的に生成する必要があります。まず、128x128キューブのフィールド内でマップを生成することを検討します。

マップエディターで描画できるのに、なぜゲーム用のマップを生成するのですか? iOSゲーム「Tanks」を開発するとき、サーバーにレベルを保存する機能を持つレベルエディターを作成しました。プレーヤー自身がマップを描画して送信することを期待していました。 しかし、現実はより深刻であることが判明し、プレイヤーは何千枚ものカードで私を満たしました。それは穏やかに言えば、未処理で、未完成で、単にいです。 新しいゲームの開発中、私はレベルを自動的に生成し、可能な限りエディタのレベルに匹敵するようにすることを固く決定しました。

私たちは何を持っています:
-マップは128x128ブロックで構成され、各ブロックのサイズは32x32ピクセルです。
-マップは128x128配列として保存されます。



単純な方法または「ランダム」な方法でのレベル生成


最初に、ランダム化機能を含む単純な式を使用してマップ生成機能を実装することにしました。 式の変数の値を変更することにより、マップを許容可能な状態に調整することを望んでいました。



strong>式は、ゲームマップの次の要素を生成しました。

  1. フロア:マップ全体が条件付きフロアに分割され、フロア間の距離はランド関数によって決定されました。
  2. 開口部:ランダムな幅のランダムな数の通路がフロア間に生成されました。
  3. ノイズ:床にランダムに形成されたブロック。
  4. 部屋:各階に、ランダムな数の長方形の部屋が1つ、2つの出口、または出口なしで形成されました。
  5. トレッドミル:プレイヤーがランニング中に加速できるようにするため、各フロアにランダムな数のランニング用の直線パスが生成され、ランダムな高さの「天井」がランダムにそれらのいくつかの上に描かれました。




「ランダム」メソッドを使用したレベル生成の短所



マップを生成するための式の複雑さを改善することにより、より良い結果を達成することができましたが、私は別の方法で移動することにしました。

要件アルゴリズムは満たす必要があります



パスを使用したレベル生成


カードを生成する方法は? パターンに応じて! また、テンプレート自体には、より小さいテンプレート(サブパターン)が含まれます。

まず、プレイフィールドを8x8の64個の正方形に分割します。これらの正方形のそれぞれについて、テンプレートから値をさらに読み込み、この正方形を「部屋」と呼びます。 したがって、マップは8x8 = 64の部屋で構成されています。

ゲームの本質は、ポイントA(エントリポイント)からポイントB(出口ポイント)に移動し、ある部屋から別の部屋に移動することです。 この場合、入り口は部屋の一番上の行にあり、出口は地図の一番下にあります。

そのため、まず最初に、プレーヤーが移動するルート(パス)を配置する必要があります。 これを行うために、部屋をタイプに分けます:





このパス生成アルゴリズムはチューリングマシンデバイスに似ており、部屋のマトリックス内を移動する制御デバイス(書き込み/読み取りヘッド)があります。 制御装置の可能な状態の数はもちろん正確に設定され、状態は部屋のタイプに対応します。



この段階で、キャラクターの移動経路を形成しました。アルゴリズムの影響を受けないすべての部屋をゼロで埋めます(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の部屋のパターンの例を考えてみましょう。



テンプレートからマップをコンパイルする場合、次のルールを使用します。



パターンマスキング


テンプレートからマップを収集する場合、大きなマップではブロック付きのセクションが繰り返されますが、私たちのタスクは、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ゲームのレベル生成アルゴリズムを部分的に使用しましたが、おそらくより高度なレベル生成を備えたゲームがありますが、それについては知りません。

あなたが知っている良いレ​​ベルの世代を持つ他のゲームをコメントに書いてください。

この記事のすべてのエラーをプライベートメッセージに送信してください。

Source: https://habr.com/ru/post/J255775/


All Articles