プラットフォーマーゲームループでの操作の正しい順序


7

ロックマンエンジンで問題が発生しました。ゲームループの構造により、修正が非常に困難になっています。Rush Jet、または落下するプラットフォームでは、ロックマンは落下してもプラットフォームに接続されたままでいる必要があります。現在、私ができる最善の方法(彼を引き寄せる魔法の力場のような回避策に頼ることなく)は、プラットフォームが最初に落ち始めたときに彼が1フレーム落ちるようにすることです。しかし、これでも、衝突チェック中に落下プラットフォームが彼を引き下げる必要があります。この追加のステップがなければ、プラットフォームが下降するとき、彼は常に「揺らぎ」ます。

ゲームループ内のイベントの順序がこれを実現しています。こんなふうになります:

  1. ロックマンとラッシュジェットがしばらく水平に飛んでいます。
  2. 思考フェーズ:プレーヤーが押し下げる-プラットフォームは速度を下向きに設定することを決定します。
  3. アクションフェーズ:プラットフォームが下に移動します。プレーヤーはこれを認識していません。
  4. 反応フェーズ:2つは衝突していないため、「拘束力」チェックは行われません。
  5. 次のフレームでは、ロックマンが落ちます。1フレーム後、重力が追いつき、再びプラットフォームに着地し、y速度を0にリセットします。

ループの基本的な順序がわかります。

  1. 前のフレームからの衝突やその他の変数を分析して、状態遷移やその他の調整を決定する思考フェーズ。
  2. アクションフェーズ-全員が速度に従って移動します。
  3. 反応フェーズ-衝突チェック、位置を調整して修正します。これは、プラットフォームの移動などのエフェクトも処理します。プレーヤーをある程度押します。彼の速度の変更は、アクションフェーズの次のフレームで適用されます。

私はこれらの手順と他のさまざまな変更を並べ替えてみましたが、すべてのバグがあり、すべてが全体をさらに悪化させています。これらのことを正しくするためにエンジンに大幅な変更を加える必要がある場合は、時間を無駄にする前に、「適切な」方法が何かを知りたいと思います。

私が考えられる解決策の1つは、前のフレームでプラットフォームに触れていた人を見て、その人を引き寄せて実際に一緒に移動するという動きのステップになることを知っています。しかし、それは複雑すぎるようで、そのようなコンポーネント間で到達します。私のエンジンコードは、元のゲームよりもずっと複雑に感じられ、何か間違っていることを示唆しています。

それで、イベントの適切なシーケンスはありますか?プラットフォームに沿って物事を移動することについてここで別の質問がありますが、それは私の問題の原因となるイベントの問題の順序には対応していません。また、クラシックロックマンのゲームのやり方を実際に知っている人がいれば、それは大きな助けになります。

https://github.com/Tesserex/C--MegaMan-Engine/tree/master/Mega%20Manで、必要なだけ私のコードを見つけてください。CollisionComponentとMovementComponentが最も便利です。


1
私は完全には理解していませんが、ロックマンとプラットフォームが一緒に動くので、おそらくそれらの動きを結びつけることは恐ろしいことではないでしょう。(それらが1つのエンティティのように一緒に移動する場合、なぜそれらを1つのエンティティになるようにプログラムするか、少なくとも何らかの方法でそれらをバインドしませんか?)
Michael Coleman

「プラットフォームの後で転倒する」という問題を解決する方法は、プレイヤーが2フレーム以上床に触れない限り、転倒状態に移行しないことでした。プレーヤーが落ちる。しかし、アニメーションは変化しないので、プレーヤーは気づきません。これは、坂道をかなりよく歩くことも処理します。
Blecki

@Blecki-私にとってそれはうまくいくかもしれないし、うまくいかないかもしれません-私のシステムはカスタマイズ可能ですので、かなり一般的な変更になります。とにかく、「正しい」ゲームループの順序を知っている人がいれば、私はまだ興味があります。
Tesserex、2011

回答:


2

この回答がこの質問のタイトルに適合しないことはわかっていますが、問題を解決できると思います。

私はあなたのコードベースを見ました、そしてあなたはゲームエンティティを構成するための集合的なコンポーネントデザインを持っています。ラッシュジェットには独自のゲームエンティティとコンポーネントのリストがあると思います(「ラッシュジェット」はこの移動プラットフォームと呼ばれるものです。そうです、メガマンゲームについては何も知りません)。その場合は、ラッシュジェットをプレーヤーのゲームエンティティに渡し、何らかのブリッジを設定する必要があります(使用するのに最適な用語ではありません)。

この「ブリッジ」では、ラッシュジェットがキーボードから入力を取得しないようにします。代わりに、プレーヤーは入力を受け取り、メッセージシステム(エンティティのゲームコンポーネント用のコンポーネント)で、ラッシュジェットに関連付けられた別のゲームコンポーネントを使用して、移動メッセージも傍受することができます。したがって、プレイヤーとプラットフォームの両方が一緒に移動します。ラッシュジェットがなくなると、ラッシュジェットとプレーヤーの間の架け橋として機能するゲームコンポーネントは、廃棄されて削除されます。

これはもっともらしい選択肢だと思います。動きはゲームループ内で発生し、衝突チェックが発生して、ラッシュジェットとプレーヤーが境界内にあることを確認します。また、ラッシュジェットがこのようにプレーヤーに依存していることはまったく問題ないと思います。これは最も崇高なソリューションではありませんが、おそらく機能します。

PS:私はあなたのコードベースが好きです。コードは最高ではありませんが、それは素晴らしいです。


ありがとう。それは斬新なアプローチだと思います。ゲームエンティティは外部で定義されており、それらの間の何らかの特別な接続なしで動作させたい最大の理由は、他の落下するプラットフォームが動作するために同じ特別な処理を必要としないようにするためです。しかし、おそらく私はこのタイプのアプローチを使用して、そのようなプラットフォームをより簡単に作成することができます。
Tesserex、2011

プラットフォームとプレーヤーをバインドする唯一のものは、エンティティコンポーネントです。したがって、他のプラットフォームを作成し、このエンティティコンポーネントをプレーヤーにアタッチしないでください。プラットフォームを拡張機能に対して開いたままにしておくと、作業が簡単になります。
マイケルコールマン、

これまでのところ、私がそれを機能させる1つの方法として、ヒットボックスを使用して2つの間の通信を行いました。したがって、現時点では、少なくとも他の小さなオブジェクトを作成しない単純な解決策はないようです。
Tesserex、2011

ええ、でもその小さなオブジェクトは本当に問題なのでしょうか?1つのフレームで1回だけ割り当てられます。私の意見では非常に少量です。
Michael Coleman、

そう、それはうまくいきます。そのようなプラットフォームを作成するたびに、それを覚えておかなければなりません。
Tesserex、2011

0

わかりましたので、最も基本的な形式では、ゲームループは次のようになります。

while game is running
    act upon user input
    update all game objects
    re-draw everything to the screen

あなたの場合、何が起こるべきですか:

  1. ループが始まります。
  2. 発生したキーの押下に基づいて、すべてのオブジェクトを更新します。プラットフォームが下に移動します。
  3. 次に、それらの速度に基づいてすべてのオブジェクトを更新します。そのステップ内では、完全な距離を移動しないように衝突チェックを行うか、壁にぶつかって(通過する)ときに速度をゼロに変更して、適切な場所に配置します。
  4. すべてを画面に描画します。ユーザーはエラー状態を見たことがないので、すべてが問題なく見えます。今までジッタはありません。

そして、それが私が書くほとんどのゲームがそれを機能させる方法です。

更新:優れたゲームループを作成する方法についてさらに情報が必要な場合は、この優れたガイドよりさらに詳しく調べてください


その記事は、ハードウェアの速度でゲームのループ時間を正しくする方法について完全に書かれているようです。しかし、あなたの提案は私の注文が正しいことを示唆しているようです。あなたがそれを持っている方法私は問題がまだ存在すると思います。ふたりを結び付ける魔法のようなものをしなければならないと思います。
Tesserex、2011

@Tesserex:わかりません。プレーヤーが重力チェックを行う前にプラットフォームの位置を変更した場合、次のステップが発生する前に、プラットフォームが下に移動してプラットフォームに接続することはありませんか?あなたのコードを見ていないと、操作の順序に問題があるように見えるので、私の投稿です。
ロバートマサイオリ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.