プラットフォーマーの構築-プレイヤーがジャンプを許可されているかどうかを判断する方法は?


16

シンプルなPlattformerジャンプアンドランスタイルゲームを構築しています。私はタイルを使用しません-代わりに、レベルエンティティの幾何学的図形を使用します(プレーヤーも1つです)。私は衝突検出コードを完成させましたが、これまでのところすべてが正常に機能しています。

次に、ジャンプを実装したかった。プレーヤーが適切なキーを打ったかどうかを確認し、上方向の速度を追加します。正常に動作します。しかし、プレイヤーが空中であっても機能しますが、これは私が望むものではありません。;-)

だから、プレイヤーが何かの上に立っているかどうかを確認する必要があります。私の最初のアイデアは、最後のフレームで衝突があったかどうかを確認し、プレーヤーを「ジャンプ可能」としてマークすることでしたが、プレーヤーが空中の壁に当たった場合でもトリガーされます。私の数学のスキルはそれほど良くないので、私は助けを求めます-ヒントでさえこれを実装する方法を行います。

ありがとう!

回答:


14

2つのオプションが思い浮かびます。

  • 最初に考えられるのは、ジオメトリにIDのタグを付け、次に衝突がフロアとしてタグ付けされたジオメトリにあるかどうかを確認することです。これにより、ジャンプ可能なサーフェスを最大限に制御できますが、レベルの作成に時間がかかります。
  • 2つ目は、衝突の法線を確認し、上向きの場合はジャンプを許可することです。または、ある程度余裕を持って、傾斜した床があるかどうかに依存します。これは柔軟であり、タグ付けは必要ありませんが、傾斜した床や壁がある場合は、不要な場所にジャンプする可能性があります。

通常のチェックは私にとって素晴らしいアイデアのようです。それを投稿してくれてありがとう。
クリストファーホレンシュタイン

通常のチェックの場合は+1。これにより、問題が発生することなく、フロアが壁にシームレスに移行できます。
ソビエト

1
+1衝突法線を確実にチェックします。さまざまなタイプのワールドジオメトリを使用することは問題なく、より柔軟なレベル設計を可能にしますが、主な問題は解決しません。「壁」のタイプは、地面にぶつかるか立っているかによって異なります。これがコリジョンノーマルが役立つ場所です。
bummzack

私は通常の解決策が非常にいいと思い、私の問題を解決します。他の高評価の回答でさえすてきです-しかし、これは私の質問によりよく答えます。あなたのwkerslakeに感謝します!
マラックス

8

何らかの表面タイプを確実に実装する必要があります。自分のキャラクターが壁や梯子に衝突したかどうかわからない場合、はしごを登ることができる場合、どのように管理しますか?単純にOOPを使用して、遺産を使用して型階層を管理できますが、列挙型を使用して実装された「カテゴリ」を使用することをお勧めします。

アイデアは次のとおりです。「Collisions」列挙には、カテゴリごとにフラグがあります。例えば:

namespace Collisions
{
    enum Type
    {
        None   = 0,
        Floor  = 1 << 0,
        Ladder = 1 << 1,
        Enemy  = 1 << 2,
        ... // And whatever else you need.

        // Then, you can construct named groups of flags.
        Player = Floor | Ladder | Enemy
    };
}

このメソッドを使用すると、プレーヤーのジャストが管理する必要があるものと衝突したかどうかをテストできるため、エンジンはエンティティの「Collided」メソッドを呼び出すことができます。

void Player::Collided( Collisions::Type group )
{
   if ( group & Collisions::Ladder )
   {
      // Manage Ladder Collision
   }
   if ( group & Collisions::Floor )
   {
      // Manage Floor Collision
   }
   if ( group & Collisions::Enemy )
   {
      // Manage Enemy Collision
   }
}

このメソッドは、ビットごとのフラグとビットごとの「Or」演算子を使用して、カテゴリのバイナリ値に基づいて各グループが異なる値を持つようにします。この方法はうまく機能し、簡単にスケーラブルであるため、税関衝突グループを作成できます。ゲーム内の各エンティティ(プレイヤー、敵など)には、「フィルター」と呼ばれるビットがあります。これは、衝突する可能性があるものを判別するために使用されます。衝突コードは、ビットが一致し、それに応じて反応するかどうかを確認する必要があります。コードは次のようになります。

void PhysicEngine::OnCollision(...)
{
    mPhysics.AddContact( body1, body1.GetFilter(), body2, body2.GetFilter() );
}

列挙型の代わりにconst intを使用する理由はありますか?単一のフラグまたは名前付きグループの縮退した場合、列挙型は読みやすくなり、ほとんどのコンパイラで追加の型チェック機能が得られます。

はい、列挙型は(カスタムバイナリ演算子を使用して新しいカスタムグループを作成することはできません)。私がこれらのconstを作成した理由は、読みやすさの理由でパブリック静的メンバーを持つConfigクラスを使用し、構成パラメーターのセキュリティを維持するためです。
フレデリックインボー

できる。列挙「右辺値」は、他の定数値に対するビット単位の操作になる場合があります(実際には任意の定数式になり得ると思いますが、標準をチェックするには面倒です)。非静的な値は、例とまったく同じ方法で実現されますが、より正確に入力されます。「セキュリティ」の意味がわかりませんが、クラスに関連するオーバーヘッドのないまったく同じ構文を名前空間で実現できます。

列挙型を使用するようにコード例を更新しました。

たぶん読みやすくなると思います。あなたが行った変更を承認し、使用した方法は正しいものでしたが、説明文のコードを調整していませんでした。修正していただきありがとうございます。名前空間については、あなたは非常に正しいですが、これはすべての言語(例のスクリプト言語)に当てはまるわけではありません。「セキュリティ」では、私の構成オプションは静的であるため、変更できませんが、列挙型を使用するとこれも防止されます。
フレデリックインボー

1

キャラクターの足を常にキャラクターの下に一定の距離があるとみなし、表面から離れていない場合、キャラクターは地面にいます。

大まかな擬似コードでは:

bool isOnGround(Character& chr)
{
   // down vector is opposite from your characters current up vector.
   // if you want to support wall jumps, animate the vecToFoot as appropriate.
   vec vecToFoot = -chr.up * chr.footDistanceFromCentre;

// if feet are moving away from any surface, can't be on the ground if (dot(chr.velocity, down) < 0.0f) return false;

// generate line from character centre to the foot position vec linePos0 = chr.position; vec linePos1 = chr.position + vecToFoot;

// test line against world. If it returns a hit surface, we're on the ground if (testLineAgainstWorld(line0, line1, &surface) return true;

return false; }


ダブルジャンプや壁ジャンプなどの機能を追加する場合、これは機能しませんか?
フレデリックインボー

OPがダブルジャンプやウォールジャンプに言及しているとは思わないでしょうか?
jpaver

文字中心から足にベクトルを抽象化する方法を示すためにコードを修正しました。これをアニメートし、足が横向きになって壁にぶつかると、壁ジャンプをサポートできるようになります。
jpaver

これは基本的に、コリジョン法線をチェックする柔軟性の低い方法です。(法線の方向を確認するだけで、壁ジャンプと床ジャンプを天井ジャンプから簡単に区別できるため、柔軟性が

2
変数を呼び出すことはありませんcharもない擬似コードで、。
右折
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.