ゲームの時間逆メカニズム


10

ゲームの時間操作メカニズムが一般的にどのように設計されているのか疑問に思っています。私は特にタイムリバースに興味があります(最新のSSXやPrince of Persiaのようなものです)。

ゲームは2Dトップダウンシューティングゲームです。

私が設計/実装しようとしているメカニズムには、次の要件があります。

1)プレイヤーキャラクター以外のエンティティのアクションは完全に確定的です。

  • エンティティが実行するアクションは、レベルの開始以降に進行したフレームおよび/または画面上のプレーヤーの位置に基づいています
  • エンティティは、レベルの設定された時間に生成されます。

2)時間逆転は、リアルタイムで逆転することで機能します。

  • プレーヤーのアクションも逆になり、プレーヤーが実行したものとは逆に再生されます。リバースタイム中はプレイヤーはコントロールできません。
  • リバースに費やす時間に制限はありません。必要に応じて、レベルの最初までリバースできます。

例として:

フレーム0-50:プレイヤーはこの時間内に前方に20ユニット移動します。敵1がフレーム20でスポーンします。フレーム50

これを逆にすると、リアルタイムで再生されます。この間、プレーヤーは20ユニット後方に移動します。敵1はフレーム50で復活します。弾丸はフレーム50で再出現します。フレーム20。

動きを見るだけで、これを実現する方法についていくつかのアイデアがありました。時間を進めたり、逆転させたりするときの動作を変えるインターフェースを持つことを考えました。このようなことをする代わりに:

void update()
{
    movement += new Vector(0,5);
}

私はこのようなことをします:

public interface movement()
{
    public void move(Vector v, Entity e);
}

public class advance() implements movement
{
    public void move(Vector v, Entity e)
    {
            e.location += v;
    }
}


public class reverse() implements movement
{
    public void move(Vector v, Entity e)
    { 
        e.location -= v;
    }
}

public void update()
{
    moveLogic.move(new vector(5,0));
}

ただし、これは最適なパフォーマンスではなく、より高度なアクション(カーブしたパスに沿ったスムーズな移動など)を行うとすぐに複雑になることに気付きました。


1
私はこれまですべてを見ていませんでしたが(YouTubeの不安定なカム、1.5時間)、ジョナサンブローが彼のゲームのブレードでこれを機能させたというアイデアがおそらくあるでしょう。
MichaelHouse

回答:


9

あなたはを見てみたいかもしれませんCommandパターン

基本的に、エンティティが実行するすべての可逆アクションは、コマンドオブジェクトとして実装されます。これらのオブジェクトはすべて、少なくとも2つのメソッドを実装します。Execute()とUndo()に加えて、適切なタイミングのタイムスタンププロパティなど、必要なものをすべて実装します。

エンティティが可逆的なアクションを実行するときは常に、最初に適切なコマンドオブジェクトを作成します。Undoスタックに保存してから、ゲームエンジンにフィードして実行します。時間を逆にしたい場合は、スタックの一番上からアクションをポップし、それらのUndo()メソッドを呼び出します。このメソッドは、Execute()メソッドの反対です。たとえば、ポイントAからポイントBへのジャンプの場合、BからAへのジャンプを実行します。

アクションをポップした後、テキストエディターやペイントプログラムの元に戻す/やり直し機能と同じように、前後に自由に移動したい場合は、アクションをやり直しスタックに保存します。もちろん、アニメーションは、逆方向に再生するための「巻き戻し」モードもサポートしている必要があります。

より多くのゲームデザインの厄介な問題については、すべてのエンティティがそのアクションを独自のスタックに格納できるようにして、それらを互いに独立して元に戻したりやり直したりできるようにします。

コマンドパターンには他の利点もあります。たとえば、スタック上のすべてのオブジェクトをファイルに保存するだけでよいので、リプレイレコーダーを作成するのは非常に簡単です。 1。


2
浮動小数点の精度の問題、可変タイムステップなどのため、ゲーム内のアクションの可逆性は非常に扱いにくいものになる可能性があることに注意してください。ほとんどの場合、状態を再構築するよりもその状態を保存する方がはるかに安全です。
Steven Stadnicki

@StevenStadnicki多分、それは間違いなく可能です。私の頭の上のC&Cジェネラルズはこのようにしています。それは、最長でも数百kBの重さで、最大8人までのプレーヤーで数時間のリプレイがあり、すべてのRTSゲームがマルチプレーヤーであるとは限りませんが、ほとんどの場合、何百もの潜在的な状態で完全なゲーム状態を送信することはできません。フレームごとのユニットの場合、エンジンに更新を行わせる必要があります。ええ、それは間違いなく実行可能です。
ハックワース、

3
順方向に一貫して再現可能な操作(たとえば、x_0 = 0から開始して各ステップにデルタv_nを追加することにより、フレームn、x_nでの位置を見つける)は、必ずしも逆方向に再現できるわけではないため、リプレイは巻き戻しとは非常に異なります。 ; (x + v_n)-v_nは、浮動小数点演算で一貫してxと等しくありません。そして、「それを回避する」と言うのは簡単ですが、あなたは多くの外部ライブラリを使用できないことを含めて、潜在的に完全なオーバーホールについて話しています。
Steven Stadnicki

1
一部のゲームではあなたのアプローチは実現可能かもしれませんが、AFAIKがメカニックとして時間反転を使用するほとんどのゲームは、関連する状態フレームごとに保存されるOriginalDaemonのMementoアプローチに近いものを使用しています。
Steven Stadnicki

2
ステップを再計算して巻き戻しますが、数秒ごとにキーフレームを保存しますか?浮動小数点エラーは、ほんの数秒で大きな違いを生む可能性は低いです(もちろん、複雑さに依存します)。ビデオ圧縮でも機能することが示されています:P
Tharwen

1

Mementoパターンを見てみましょう。その主な目的は、オブジェクトの状態をロールバックして元に戻す/やり直し操作を実装することですが、特定の種類のゲームではそれで十分です。

リアルタイムループのゲームの場合、操作の各フレームを状態変化と見なして保存できます。これは簡単な実装方法です。代替手段は、オブジェクトの状態が変更されたときにトラップすることです。たとえば、剛体に作用する力が変化したときを検出します。プロパティを使用して変数を取得および設定する場合、これも比較的単純な実装である可能性があります。困難なのは、状態をロールバックするタイミングを特定することです。これは、すべてのオブジェクトに対して同じ時間ではないためです(システムの開始からのフレームカウントとしてのロールバック時間)。


0

特定のケースでは、モーションを巻き戻してロールバックを処理することで問題なく動作するはずです。AIユニットで任意の形式のパスファインディングを使用している場合は、ユニットが重複しないように、ロールバック後に必ず再計算してください。

問題は、動き自体の処理方法です。適切な物理エンジン(2Dトップダウンシューターは非常にシンプルなもので問題ありません)は、過去のステップ情報(位置、正味の力など)を追跡し、強固な基盤。次に、最大のロールバックとロールバック手順の細分性を決定すると、必要な結果が得られます。


0

これは面白いアイデアですが。私はそれに反対するでしょう。

操作は常にゲームの状態に同じ影響を与えるため、ゲームを順方向に再生すると問題なく動作します。これは、逆の操作によって元の状態が得られることを意味するものではありません。たとえば、任意のプログラミング言語で次の式を評価します(最適化をオフにします)。

(1.1 + 3 - 3) == 1.1

少なくともCおよびC ++では、falseを返します。差は小さいかもしれませんが、10秒の10分の60fpsでどれだけのエラーが蓄積できるか想像してみてください。プレーヤーが何かを逃しただけで、ゲームが逆方向に再生されている間にヒットする場合があります。

0.5秒ごとにキーフレームを保存することをお勧めします。これはあまりメモリを消費しません。次に、キーフレーム間を補間するか、さらに良いことに、2つのキーフレーム間の時間をシミュレートしてから、逆方向に再生できます。

ゲームがそれほど複雑でない場合は、ゲーム状態のキーフレームを1秒間に30回保存して、逆方向に再生します。2Dの位置にそれぞれ15個のオブジェクトがある場合、圧縮せずにMBになるまでに1.5分程度かかります。コンピュータにはギガバイトのメモリがあります。

したがって、複雑にしないでください。ゲームを逆方向に再生するのは簡単ではなく、多くのエラーが発生します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.