時間旅行をゲームに実装する方法は?


10

ゲームにタイムトラベルを実装する方法を考えていました。超複雑なものは何もありません。Braidのように時間を逆転するだけで、ユーザーは時間を30秒ずつ巻き戻したり早送りしたりできます。

ウェブを何度も検索しましたが、結果は通常、「3時です」のような時間やタイマーなどを使用して参照されていました。

私が考え得る唯一のことは、2つの配列を使用することでした。1つはプレーヤーのx位置用、もう1つはプレーヤーのy位置用であり、それらの配列を繰り返し処理して、巻き戻し/早送りしながらその位置にキャラクターを配置しました。それでうまくいきますか?それが機能する場合、配列はどのくらいの大きさでなければならず、プレーヤーのxとyをどのくらいの頻度で格納する必要がありますか?それが機能しない場合、他に何を試すことができますか?

前もって感謝します!


11
ニュースを読みませんか(ust.hk/eng/news/press_20110719-893.html)?彼らは、タイムトラベルが不可能であることを示しました。したがって、コーディングすることは不可能です。

タイムトラベルの可能な意味論を考える必要があります。その後で初めて、実装について考え始めることができます。
パウロEbermann


2
いくつかのベクトル数学を自分で学んでください。2つの個別の配列を提案している場合、それらを使用したことがないことを示しています。私はそれらがどれだけ物事を単純化できるかという理由で、ゲームプログラマーが知ることが不可欠であると考えています。
doppelgreener

5
import universal.back2future.FluxCapacitor;
11

回答:


6

配列のアイデアは、Braidでの実装方法とほぼ同じです。キャラクターに作用するのが重力、キーボード/ジョイパッド入力、およびその他のキャラクターのみである場合、ほとんどの場合、各キャラクターの重要なすべてを知るために各ステップでの位置と速度を保存するだけです。文字ごとに毎秒10のスナップショットを保存する場合、1つの文字の履歴の1分間はまだ50K未満です-ほとんどのシステムで簡単に管理でき、それよりも効率的な方法を見つけることができます。


これは正しい道です。たとえば、アクティブコマンドの保存:タイムスタンプ付きのキープレス。システムが確定的である場合、他のほとんどの動作を推定できます。巻き戻しシステムには10 fpsトラッカーで十分ですが、実際のコマンドが保持されている限り、オブジェクトの状態または状態の変化が実際に保持される限り、許容範囲がさらに狭くなる可能性があります。
カーミントン、2011

4

コマンドパターンについて読んでください。これは、元に戻すアクション(および後で再実行するアクション)を提供します。これは、船の位置だけでなく、プレイヤーが実行するすべてのアクションを処理します。

しかし、私はあなたのアレイのアイデアも同様に健全だと思います。


おそらくない素晴らしいアイデア-であることに加え、より多くのメモリ集約型(あなたがその位置にエンティティの速度を追加するたびに、あなたがその「アクション」として保存する必要があります)、それはかなり必要としますが、フローティング使用している場合以来、固定小数点演算を-あなたの位置/速度のポイント、(x+v)-vに等しくないかもしれませんx
BlueRaja-ダニープフルフフト

1
@BlueRaja-そのアプローチがメモリを大量に消費する場所がわからない。100 FPSで最後の10秒間を保存する場合、コマンドの1000 n-tupelを保存する必要があります。nは最大で5程度です。または、さらに良いことに、これらの各フレームに絶対位置のみを保存し、巻き戻しの場合は、そのパスに沿ってキャラクターを逆方向にアニメーション化するだけです。これにより、浮動小数点の問題が発生する可能性もなくなり、開始した場所に正確に戻ります。
ハックワース2011

3

2つの個別の配列を使用するのではなく、プレーヤーの位置を説明する1つのクラス(おそらく、JavaにはおそらくPointクラスがあります...私は最近C#の人です)を使用し、1つの配列を使用して過去の位置を保持する必要があります。

「リングバッファ」を設定する必要があります。つまり、配列の最後に到達すると、配列の最初に戻り、最も古いエントリを上書きします。過去にさかのぼると、その逆になります(最初に到達したら、最後まで丸で囲みます)。

30秒分の過去のデータを保持する場合、スペースを事前に割り当てて固定サイズの配列を使用するには、フレームレートを知っている必要があります。10フレーム/秒で30秒を掛けてゲームをレンダリングすると、300要素になります。


2

GDCVaultのサイトで、Braidの作成者であるJon Blowによる講演「The Implementation of Rewind in Braid in3.95」が開催されています。私はこれがあなたが望む情報を持っているに違いない;)

編集:おそらくJavaにはないでしょうが、アイデアは保持されるべきです。


彼らが文字起こしも販売するのか、それとも音声のみを販売するのか知っていますか?
o0 '。

サイトのクイック検索では何も見つかりませんでした。多分あなたはいくつかの転写ソフトウェアを使用できますか?
NoobsArePeople2 2011

1

エリックJが言ったように、リングバッファーにポイントオブジェクトのコレクションとしてプレーヤーの過去の位置を保存することは、合理的に聞こえます。

ただし、バッファを実装するためにキューを使用することをお勧めします。配列よりも更新の方がはるかに安く、事前にフレームレートを知っておく必要はありません。

update():
   time_queue.push(player.positions)
   if current_time() - start_time > n:
       queue.pop()

これはまだフレームレートの変化や実際に時間移動を行う場合に何が起こるかを考慮していないので、各エントリにタイムスタンプを保存し、代わりにそれを確認することをお勧めします。

update():
    time_queue.push({
        'pos': player.positions,
        'time': current_time()
    })
    first_entry = queue.peek()
    while current_time() - first_entry['time'] > n:
       queue.pop()
       first_entry = queue.peek()

お役に立てれば!


1

Mementoと呼ばれるデザインパターンがあります。それはブレードのようなゲームの出発点だと思います

mementoパターンは、オブジェクトを以前の状態に戻す機能を提供するソフトウェアデザインパターンです(ロールバックを介して元に戻す)。

記念品パターンは、2つのオブジェクト(オリジネーターと管理人)によって使用されます。オリジネーターは、内部状態を持つオブジェクトです。世話人はオリジネーターに何かをしようとしていますが、変更を元に戻せるようにしたいと考えています。世話人は最初に発信者に記念品オブジェクトを要求します。次に、実行しようとした操作(または操作のシーケンス)を実行します。操作前の状態にロールバックするために、それはmementoオブジェクトをオリジネーターに返します。記念品オブジェクト自体は不透明なオブジェクトです(管理人が変更できない、または変更すべきではないオブジェクト)。このパターンを使用する場合、発信者が他のオブジェクトまたはリソースを変更する可能性がある場合は注意が必要です。メモリメントパターンは単一のオブジェクトで動作します。

http://en.wikipedia.org/wiki/Memento_pattern

ここの特別情報:http ://dofactory.com/Patterns/PatternMemento.aspx


2
これがどのように役立つかはわかりません。OPはBraidのようなスムーズなものを要求する一方で、「インスタントロールバック」のように見えます。多分私は何かを読み間違えましたか?
o0 '。

これは、単一のロールバックを意味するパターンではなく、たとえばアクションの「タイムライン」を作成できます。ここでは、このパターンの使用状況についてのブラジルのブログ記事です:abrindoojogo.com.br/padroes-de-projeto-memento :ここではFlashで作られた例ですabrindoojogo.com.br/files/fasteroids.swf移動:矢印は| シュート:スペース| 巻き戻しアクション:バックスペース
Marcelo Assis

1

時間操作を伴うXBox360用にリリースされたゲームがありました。平凡だったので、現時点ではタイトルを思い出せません。とにかく、開発者とのインタビューで、彼らは時間操作の管理方法を概説しました。

Xフレームごとに(Xの値が小さいほど、きめ細かい操作が可能になります)、その時点でゲームワールドの「スナップショット」を取り、それをゲーム内時間に関連付けます。

ゲームを通常通り、時間をかけてプレイしながら、リアクションのすべての入力は、将来のある時点で設定されるスナップショットに寄与します。

その後、ゲームワールドは現在のスナップショットと将来のスナップショットXフレームの間で反復します。

次に、時間を逆にしたい場合は、時間の方向を逆方向に設定するだけで、現在と過去のスナップショットXフレームの間で繰り返されます(将来のスナップショットを作成する機能は無効になります)。


スナップショットの細分性についての要点として+1。
Omar Kooheji

0

単にゲームの仮想時間を別の空間のような次元として扱うことができます。したがって、外部からのタイムトラベルは、ゲームの仮想宇宙における単純なn + 1次元の動きです。

ユーザー入力がない場合に宇宙の振る舞いを決定する何らかのユーザーインタラクションとある種の物理システムを想定すると、記録する必要があるのはユーザーインタラクションの影響(たとえば、n + 1次元の速度/加速度ベクトルの変化)だけです。 、あなたの物理学は時間可逆であるはずです。

このようにして、任意の時間座標でゲームユニバースの状態を計算するために必要なメモリが大幅に少なくなります。


私は別のコメントで述べたように、ビデオゲームにおける物理学は通常ない浮動小数点数を使用した場合、ので、時間の可逆的(x+v)-vに等しいではないかもしれませんx
ダニーPflughoeft - BlueRaja

0

エンティティに速度、回転、x、yの位置があるとします。これらは、加速の場合、基本的な運動状態、値、あなたがそれを呼ぶものは何でもです。次の2つの方法でデータを保存できます
。1.回転、xおよびy位置を
保存2.回転、x速度およびy速度を保存

速度が固定されている場合は、回転のみを保存するか、両方の軸の速度を1つだけ保存することもできます。

エンティティに静的なローテーションがない限り、ゲームではローテーションを保存する必要があります。

つまり、複数の値にオブジェクトのリストを使用する必要があります。たとえば、1秒に20回更新メソッドを呼び出し、fpsに依存しない優れたタイマーシステムがある場合、20 * 30のオブジェクトの配列を作成して、過去30秒間に必要な動きの値を保存できます。 。単純な配列を使用することはお勧めしません。更新の呼び出しごとに、すべての要素を1インデックス左に移動する必要があるためです。

これに基づいて、リストまたは戻るものを何でも実行できます。本当に「リアルな」効果を得たい場合は、すべての移動オブジェクトにこの手法を使用してください。しかし、これはゲームデザインに関連しています。

オブジェクトを破棄する場合は、オブジェクトをプールして、きちんとした友人のガベージ氏にストレスを与えないようにしてください;)

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