2Dプラットフォーマーでプレイヤーが押しつぶされていることを検出するにはどうすればよいですか?


19

#1に示すように、プラットフォーマーキャラクターの衝突をチェックしています。赤い点はチェックされるピクセルで、灰色の線はそれらが関係する軸を示します。この方法で衝突をチェックすることで得られる結果が気に入っています(たとえば、バウンディングボックスに対して)。クラッシュ検出という1つの問題を除いて、すべてが希望どおりに機能します。

次の画像では、水色のボックスは地面を表し、オレンジ色のボックスはオブジェクトを表し、矢印は移動の方向を示します。

プレイヤーが押しつぶされたときを検出する簡単な解決策は、反対側の衝突ポイントが両方ともトリガーしているかどうかを確認することです。もしそうなら、プレイヤーは粉砕されています。#2では、通常のクラッシュシナリオを見ることができます。プレーヤーは接地され、上部の衝突点は落下オブジェクトと交差します。これはクラッシュを引き起こします。

#3、4、および5は、問題のあるシナリオを示しています。#3では、プレーヤーはオブジェクトに向かって移動し、オブジェクトは上に移動します。右側の衝突点がオブジェクトに当たり、衝突を引き起こしてプレイヤーを停止させます。

これで、オブジェクトが上に移動し続け、プレイヤーが右に移動し続けると(#4に示すように)、オブジェクトはプレイヤーの右側の衝突点をクリアし、プレイヤーは右に移動します。しかし、今では、オブジェクトが上部の衝突点と交差しているため、不要な垂直クラッシュが発生しています。

同様のシナリオを#5に示します。2つのオブジェクトは、下部の衝突点をクリアするのに十分離れているため、プレーヤーは落下できますが、側面の衝突点がクリアされるまではできず、不要な水平クラッシュが発生します。

私は解決策に頭を悩ませてきましたが、私が思いついたものは何も特にうまくいきませんでした。

ここに画像の説明を入力してください

混乱を解消するために、赤い衝突点はスプライト内にあり、灰色の線は各衝突点に関連する軸を示すためにのみ使用されていました。たとえば、キャラクターのスプライトが単純な緑の正方形の場合、衝突点は次のようになります。

ここに画像の説明を入力してください

回答:


34

ボックスの動きを考慮する必要があると思います。つまり、ボックスがプレイヤーに向かって移動している場合にのみクラッシュします。

これは、動きが重要なプラットフォーマーの他の問題と似ています。たとえば、下から上にジャンプできるプラットフォームの場合、プレーヤーが上に動いている場合は衝突をチェックしないでください。

そのため、ブロックが下に動いている場合にのみ、ブロックは上からプレイヤーを押しつぶすことができます。ブロックが上方に移動する場合のみ、下から。ブロックが右に移動している場合のみ、左から。


13
+1ブロックはプレーヤーではなくここで機能していることを考慮してください。だから、あなたがチェックする場合は、このボックスには、プレーヤーを破砕された場合に代わりのプレイヤーは、問題が解決することが容易であるべき破砕されているかどうかをチェックする
ニールス・

ブロックが動いていないときはどうですか?#5のブロックに矢印を付けたのに気づきましたが、それは2つの固定ブロックでした。
IanLarson

固定ブロックがつぶれてはならないと判断した場合は、プレイヤーが動けず、邪魔にならないようにしてください。
コンガスボン

ああ、私は実際にお互いから離れている2つのオブジェクトに押しつぶされるのが嫌いです。ピクセルとフレームが完璧になり、開発者が怠けていたからです。
サイ

9

「クラッシュテスト」ポイントがあること持っている内部のあなたのイメージ#1に示す灰色のボックス-つまり、あなたがそこ画素の1つにヒットを検出した場合にのみプレーヤーを殺します。


1
衝突点の境界の「内側」にクラッシュチェックポイントを追加するということですか?私が見る問題は、オブジェクトが内側のクラッシュチェックポイントに到達する前に衝突ポイントの1つが「トリガー」されると、各軸で衝突解決が発生することです。
IanLarson

6

80年代のプラットフォーマーで育った私としての最初のコメントは、接点はスプライトの外側にあるのではなく、スプライト上にある必要があるということです。武器/粉砕機/敵がキャラクターから明らかに数ピクセル離れている場合、死ぬほどイライラする経験はほとんどありませんでした。

それを念頭に置いて、水平衝突と垂直衝突に別々のポイントを設けるという考えは、単に飛ぶことはありません。したがって、ケース3と5は存在しません。

前述したように、衝突検出に関しては、移動方向を考慮する必要があり、考慮する2つの移動軸があります。クラッシャーがダウンしている場合、プレイヤーは前方に歩くことができません-それは壁のように動作する必要があります。したがって、同じ場所に水平および垂直の検出ポイントがあると、ミックスに移動方向を追加する前でも、ケース4を取得できません。

上方に移動するクラッシャーは、さらに複雑になります。プレイヤーが逃げるチャンスがないほど速いなら、OK。しかし、それが遅い場合、プレイヤーは上昇しているプラ​​ットフォーム上を走り、反対側から飛び降りることができると期待します。プレイヤーのスプライトはクラッシャー上で上昇し、クラッシュ検出は天井で発生します


3
軽微な点-あなたは彼のスプライトがどのように見えるかわかりません。上の画像に示されているとおりであることがわかっているため、ケース3と5は完全に有効です。
アレックス

1
アレックスは正しい。明確にするために編集しました。不一致の衝突ボックスほど悪いものはないことに同意します。異なる軸に別々のポイントを使用しないことについてのあなたのポイントを理解していると思います。もしそうなら、それは上記の例を8つのポイントから4つのポイントに変えます。私は実際にそれを念頭に置いていくつかのテストを行いました(望ましい結果は得られませんでした)が、コーナーを「分離」することでほぼ完全に求めている動作を実現できるため、それを実行することにstronglyしています。これらは実際に私が遭遇した唯一の問題シナリオです。
IanLarson

0

オブジェクトを地面よりも「硬く」することができます。つまり、衝突していると仮定すると、プレイヤーは移動するオブジェクトに「押し込まれる」のではなく、地面に「押し込まれる」ことになります。

これは、プレーヤーが自分自身をオブジェクトまたは地面のいずれかに「押し込む」ことができないことを前提としています。


0

オブジェクトの表示を待たずにオブジェクトのオーバーラップを検出できる場合、単純なアプローチは、プレーヤーと他のオブジェクトのモーションを、一度に1ピクセルずつ個別に処理し、後で個別の衝突チェックを行うことです。プレーヤーが自由に動いていて、そのような動きの結果としてオブジェクトと衝突する場合、それを後退させます。オブジェクトの動きの結果としてオブジェクトと衝突が発生した場合、プレイヤーがそのオブジェクトと同じ方向に移動できるかどうかを確認します。その場合、プレーヤーを移動します。そうでない場合は、「クラッシュ」状況を適切に処理します(接触に応じて、プレーヤーの損傷または殺害、および/または衝突するオブジェクトの後方への移動)。

ところで、限られた数の形状の組み合わせだけが衝突する場合、「衝突検出」ビットマップを事前に計算しておくと、ピクセルが最初のスプライトのオフセット(x1、y1)と2番目の2番目のオフセット(x2、y2)で、オフセット(x1-x2、y1-y2)のピクセルが衝突マップに設定されます。このような事前に計算された衝突マップにより、衝突マップ内の単一ピクセルの状態をチェックすることにより、2つのスプライト間の衝突を検出できます。


0

プレイヤーを粉砕するには2つのオブジェクトが必要です。クラッシュ検出では、プレーヤーが2つのオブジェクトの間にあり、それらの間のスペースがプレーヤーのサイズに等しく、距離が減少していることを確認する必要があります。


0

今のところ、私はこれまで働いていることがわかりました。クラッシャーの動きに関する「外部」情報を必要とせず、誤検知の問題を解決します。誤検知が検出されると、それは衝突として扱われます(これが実際の状態です)。

アイデアは次のとおりです。キャラクターが動いているかどうかを実際に確認するときに、クラッシャーが動いているかどうかを確認する理由。どちらも、キャラクター自身の動きによるクラッシュが誤検知であるか、クラッシャーオブジェクトの動きによる真のクラッシュである場合に回答できます。

キャラクターが動いて押しつぶされている場合(着信フレームの反対側の衝突)、最後のフレーム/反復座標の押しつぶしを再度確認します。

  1. 再度確認されない場合は、キャラクター自身の動きによるものであり、キャラクターは衝突のように最後のフレーム/反復座標に戻される必要があります

  2. クラッシュが2回目に確認された場合は、クラッシュを続行します。

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