レベルで定義されたオブジェクトの永続状態を実装するにはどうすればよいですか?


17

私は再接続可能な一連の相互接続されたレベルで構成される2Dメトロイドバニアを開発しています。

各レベルは、さまざまなスプライトクラスのさまざまなオブジェクト(たとえば、敵、ピックアップ、レバーなど)が生成される場所を指定したTiled TMXファイルで表されます。新しいゲームを開始するとき、保存したゲームをロードするとき、またはレベルを変更するとき、ゲームループは適切なTMXファイルを実行し、そのレベルのすべてのオブジェクトを生成します。

レベルの変更は次の方法で処理します。Playerオブジェクトがオブジェクトと交差するPortal場合、change_map()新しいマップ(交差したポータルに関連付けられたマップ)をロードし、プレーヤーを新しいマップ上の適切な位置に配置するメソッドが呼び出されます。

一部のオブジェクトには、レベルの変更とゲームの保存と終了を通じて永続的になりたい状態があります。たとえば、プレーヤーがドアのロックを解除し、ドアの状態属性が「開く」に設定されている場合、プレーヤーが戻ったときにドアが開くようにします。左または右に設定できるレバー、およびその他のさまざまなオブジェクトに似たものが必要です。さらに、プレイヤーがエリアを再訪したときに、プレイヤーが再スポーンしたくないアイテムを収集することがあります。

したがって、私の質問は、この種の永続性どのように処理できますか?

私はPythonで働いていますが、あなたはそれから抽象化できると思います。

回答:


27

この問題を考え直さないと最良の結果が得られると思うので、単純なキー値保存システムを他の保存データと共に保存するゲームに実装し、前の状態にアクセスする必要があるときにオンデマンドでロードするだけです。

フローは次のようになります。

  1. ファイルからの負荷レベル
  2. タイル/オブジェクトを配置する前に、「永続的」プロパティがあるかどうかを確認します。
    1. はいの場合:プロパティに一致するキーの保存されたキーと値のペアを確認し、適切な値を取得します。
    2. いいえの場合:通常どおりにオブジェクトを配置します
  3. プレーヤーがレベルを終了すると、「永続的な」プロパティを持つすべてのオブジェクトを介してゲームループが保存され、キーと値のペアとして保存されます。

以下は、単純な2Dゲームに使用するものに基づいた擬似コードの例です。

def load_map(map):
    for y in range(0, height):
        for x in range(0, width):
            tile = map[x, y]

            for property in tile.properties:
                if is_persistent(property.name):
                    // Name prefixed with "persistent" means that it's persistent
                    // so we load the value from out persistent storage
                    property.value = persistent_values[property.name]

def save_map(map):
    ... everything in load_map ...
    if (property.name.matches("persistent_*")):
        // Name prefixed with "persistent" means that it's persistent
        // so we save the value to persistent storage
        persistent_values[property.name] = property.value

def is_persistent(name):
    return name.matches("persistent_*") and persistent_values.contains(name)

次に、このプロパティを使用して状態を確認するだけです。

def draw():
    if properties["persistent_is_pressed"].value:
        draw_sprite(button_pressed)
    else:
        draw_sprite(button_unpressed)

def on_pressed():
    properties["persistent_is_pressed"].value = not properties["persistent_is_pressed"].value

Tiledのようなタイルマップエディターを使用している場合、次のようなプロパティの追加は非常に簡単です。

プロパティを追加する

願わくば、これが永続状態を可能な限り簡単に実装する方法についてのアイデアを与えてくれることを願っています!


これは非常に役立ちますが、自分の状況にそれをどのように適用するかを正確に確認するのに苦労しています。私はそれについてもう少し考えます。
GoldenGremlin

値の保存を機能させるにはどうすればよいかわからないと思います。保存するとき、TMXデータのタイルを反復処理しません。むしろ、all_spritesグループのスプライトオブジェクトを反復処理します。マップを読み込むとき、スプライトオブジェクトをインスタンス化するときにTMXオブジェクトのTMXプロパティをパラメーターとして使用しますが、その後、これらのプロパティに触れないため、スプライトオブジェクトの変更を追跡しません。
GoldenGremlin

1
@dietestusおそらく、スプライトオブジェクトにproperties変更するフィールドを与えるだけで、タイルpropertiesを変更するプロパティの指標としてのみ使用する必要があります(ただし、すべてのデータはスプライトに保存されます)。あなたがスプライトからタイルを変更することができますので、あなたも自分のスプライトにタイルを渡すことができます:)私が、私はいくつかのより多くの擬似コードをモックアップすることができます何を意味するのかはっきりしていない場合
Charanor

3
@dietestus永続エンティティ(ドア、レバー)と対話するとすぐに、新しい状態をキー値マップに保存します。保存時にマップを反復処理する必要はありません。マップ内のすべてを既に持っています。
君ダーブ

1
@dietestusはい、そうです:)キーはプロパティ名であり、値は(まあ...値)である単純な辞書です。同じタイルに複数のオブジェクトを配置しても、一意のキーがあれば何も変わりません。
チャラノール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.