プラットフォーマーで動くプラットフォームの物理をどのように扱うのですか?


8

したがって、インターネットで数時間検索した後も、2Dプラットフォームゲームで移動するプラットフォームを処理する方法について、満足のいく答えが見つかりません。そこで、垂直方向と水平方向に動く2つの異なるプラットフォームを操作する単純なプロトタイプを作成することにしました。何が機能しておらず、どのように修正するのかを分析して確認するための助けが欲しいです。以下の.flaファイルと.asファイルを、再生可能な.swfへのリンクと共に提出しました。

目標は、ヒーローがプラットフォームの上に立って、一緒に押したり、ジャンプしたり、下にジャンプしたりできる固体のオブジェクトであるかのようにプラットフォームと相互作用することです。

私のプロトタイプの問題はこれらです:

  • 水平に動くプラットフォーム上に立って、移動せずに(キーに触れずに)、ヒーローはプラットフォームに沿って移動しますが、少し遅れてヒーローが少し後退します。

  • 水平方向に動くプラットフォームの上に立ってジャンプすると、空中のプラットフォームに沿って動きます(一部のゲームはこのようにすることを好みますが、自然に感じられず、ここでは望まれません)。これは、ヒーローがプラットフォームからX軸の速度を保持していることが原因である可能性があります。

  • 垂直方向に移動するプラットフォームの底部にジャンプするとき、プラットフォームが下に移動しているときに、プラットフォームの中に少し沈みます。主人公は一瞬衝突がなかったかのように貫通します。

  • 垂直方向に移動するプラットフォームにジャンプすると、Y軸の速度が保持されるため、プラットフォームから降りると、より高速で落下します。保持された速度の速度で、+重力が追加されます(これは主に、プレイヤーが空中で凍結せずにプラットフォームに着地したときに、Y軸の速度を0にリセットする方法を理解できないためです)。

私は初心者のプログラマーなので、これを行うためのより良い方法があると確信しています。それらをすべて聞いてみたいと思います。タイルベースのゲームに移動プラットフォームを実装できるコードやその他の方法を改善する方法についてのアイデアは大歓迎です。結局、私は2Dプラットフォーマーで動くプラットフォームを処理するための確かな方法を見つけようとしています。

再生可能なSWF:http : //dl.dropbox.com/u/28271061/PlatformerhowtoFLA.html(矢印キーで移動、Xキーでジャンプ、Zキーで実行)

ソースコードASファイル:http ://dl.dropbox.com/u/28271061/Platformerhowto.as

SourcefileFLA:http : //dl.dropbox.com/u/28271061/PlatformerhowtoFLA.fla

オンラインでパスティーを通してコードを読みたいだけなら:http : //pastie.org/2266764



私はそのスレッドを読みましたが、ノードをまったく使用していないため、問題を解決できなかったように感じます。私が構築しているゲームはタイルベースですが、移動プラットフォームは上記のように実装されます(自由移動)。ノードを使用するには、エンジン全体を書き換える必要があります。これは、すでに長い間費やしてきました。私は誰かがコードを見て、提案されているものと同様のソリューションを提供するか、コードの改善を見つけることを望んでいたと思います。
キッド

あなたはなりますが、それはあなたがそれらを使用する唯一の場所だ場合でも、移動プラットフォームにそのソリューションを実装したら、ノードを使用すること。それはあなたの滑り問題を解決します。
doppelgreener

2
"(一部のゲームはこのようにすることを好みますが、それは自然に感じられず、ここでは望まれません)グーグル慣性と運動量...
Riki

1
@Felheart、実際の物理的な世界ではなく、ゲームプレイの面で自然。スーパーマリオブラザーズや古典的なプラットフォーマーをプレイすると、動くプラットフォームでジャンプしている間、勢いが維持されないことに気付くでしょう。立っている感触や、動くプラットフォームとの相互作用を妨げます。
キッド

回答:


17

問題を個別の問題に分けましょう...

コード品質に関する一言

現在、コードにはプラットフォームがあり、プレーヤーの速度と世界の重力定数さえも直接制御しています。それはハックであり、オブジェクト指向であるべきときに手続き型です。このゲームを拡張し始めると、物事は醜く速くなります。

コードをリファクタリングする必要があります。プレーヤークラス、プラットフォームクラス、フロアクラスを実装します。懸念事項を分離します。プレーヤーにキーボードコントロールを解釈させ、実行方法とジャンプ方法を制御させ、プラットフォームに必要に応じて(必要に応じて、プレーヤーの既に決定されている速度に独自の速度を追加することによって)運動量を変更させます。

プレーヤーに、床タイプのオブジェクトに関して(プラットフォームと床の両方にBodyType = BodyTypes.Floor、または何かがある)かどうかを判断させ、オブジェクトに関してそれがどこにあるか、それがどのように反応するか、落下するか地面に。

これは、あなたが挙げたすべてのものとはまったく別の問題なので、別のトピックに値するかもしれません。ただし、ある時点でそれを行う必要があります。

プラットフォームを離れるときの水平/垂直慣性

垂直および水平速度の問題を解決するには、次の2つの点に注意してください。

  • 水平速度について:コードは、プレーヤーが地面(Pastieライン200)またはプラットフォームに当たったときにのみ水平速度を0に設定します。
  • 垂直速度について:プレーヤーの落下加速度は一定です。彼が垂直プラットフォームから降りると、この下降する加速は、すでに下降している動きに追加され続けます。

あなたのプレーヤーは単に慣性に苦しんでいます:何かがそれを止めるまで彼の勢いは維持されます。

解決策:どちらの問題も、プラットフォームゲームで移動するプラットフォームどのように処理すればよいかというjSepiaのソリューションによって解決されますか?プラットフォームの動きからプレイヤーの動きのプロセスが完全に分離されるからです。あなたは、単にではないでしょう垂直プラットフォームをオフに歩くより速く落ちてないだろうなプラットフォームは、もはやプレーヤーの影響を与えますので、横1を離れてあなたの水平運動量のジャンプを保存しないVXVYを

注:コードをリファクタリングする前に、jSepiaのソリューションを実装するのが難しい場合があります。

水平プラットフォームの周りを左右に滑らせます

プレイヤーが実際に水平に動くのは、プラットフォームが動くほど速くありません。理由は明らかではありません。この問題はおそらくjSepiaのソリューションを実装し、コードを適切にリファクタリングすることで解決されます(後者は単に原因を明らかにするだけです)。

衝突検出:垂直プラットフォームとの重複

パスティライン381を参照してください:プレイヤーが垂直プラットフォームの下側と衝突する限り、プレイヤーのvyを0にリセットするすべてのステップ。次のステップでは、重力加速度によってvyが増加し、プレーヤーが移動します(その後、再度0にリセットされます)。

これは、プレイヤーがプラットフォームの底に衝突している限り、一定の速度(重力定数)で下降していることを意味します。垂直プラットフォームはそれよりも速いので、彼と重なります。垂直プラットフォームがより長い距離を移動した場合、プレーヤーがプラットフォームに立っていると登録されるまで、垂直プラットフォームは彼を右にスライドします。

解決策:プレーヤーのvyを0にリセットしないでください。プレーヤーのvyをプラットフォームの垂直速度に設定するだけです(プラットフォームが下に移動している場合)。その後、プレーヤーは垂直プラットフォームから少なくともプラットフォーム同じ速さで離れ、加速します。


優秀な!まず、垂直プラットフォームをジャンプして貫通するための解決策に感謝します(動作します!)。そして、第二に、あなたは正しいです、コードはこの状態でひどいです。これ自体はゲームではありませんが、動くプラットフォームをよりよく実験して理解するために作られた高速なプロトタイプです。それでも、これを実際のゲームコードに変換する場合は、より構造化されたオブジェクト指向のコードを維持する必要があります。転送がスムーズになります。今、jSpeiasソリューションに関して、私はノードツリーの概念を理解していると思います。適切に実装する方法がわからないだけです。
キッド

私の最初の考えは、「onFloor」、「onPlatform」、「onGround」、「falling」、「jumping」など、プレーヤーの状態を表すブール値を作成することです。その後、ifステートメントを実行します現在の状態を確認し、それに応じてPlayersプロパティを変更するenterFrameイベント(?)例:if(Hero.onPlatform == true){Player.x = platform.x(relatives globals x);} そのように何か。
キッド

私たちが話すように私はそれに取り組んでいますが、同時にあなたが提案したようにコードを異なるクラスに分離しています。これも少し混乱しています(プラットフォーム/衝突/プレーヤークラスの間でのやり取りは心が曲がっています)。
子供

@Kid:PlayerメソッドGetPositionと内部変数parent(その親ノード用)およびposition(その親に対する相対位置用)があります。Player.GetPosition()を返しますposition + parent.GetPosition()。ツリーのルート、つまりワールドノードに到達するまで、その親は同じことを行います。プレーヤーが移動するときは、プライベートposition変数のみを扱います。プレーヤーは、GetPosition()の値に従ってゲーム画面に描画されます。ノード間の遷移を理解させてください。;)
doppelgreener

もちろん、独自の速度を変更する方法を知っているプレーヤークラスを持つことは、懸念の分離を維持するものではありません
Andy Ray
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.