2016-04-13 11 views
3

私はこの問題を解決するためにどのようなテクニックを採用するのですか?私のスペルがあまり良くない場合は、お詫び申し上げます。2D C++衝突検出はほぼ完璧ですが、それほど正確ではありませんか?

私はプレイヤーの位置をすべてのタイル(ループ内)と比較する2Dプラットフォームゲームを持っていますので、それに応じて衝突を解決します。これは、ゲームのメインループのかなりの構造である:

  1. チェックすべての衝突(そして プレイヤー怒鳴る衝突が発生した場合はジャンプイネーブル)に応じて
  2. に重力を追加
  3. は、入力および変更プレーヤーの速度を取得しますY速度
  4. はドロー選手の位置
  5. にゲームを速度と摩擦を適用
  6. 繰り返し

しかし、このシステムが動作しているにもかかわらず、衝突システムには2つのマイナーであるが目立った問題があります(私は簡単にするために画像を提供しています)。 2つの問題があります。最初はそれほど悪くはありませんが、2番目のレンダリングではゲームはほとんど再生できません!

問題1.ゲームの床を横切って左右に移動するだけで、時々、プレーヤーは得られたすべての速度を失い、その速度を再蓄積する必要があります。私はこれが、今、そして私の衝突検出機能が適切に戻ってこないためだと思う。ここでの画像は、次のとおりです。

The prblem that is occuring

私はそれがはっきりしていた願ってい平地の多くを横切って移動するとき、問題は本当に明らかになります。

問題2この問題は、プレーヤーが本質的に壁を飛び越えることができるということです。たとえば、左矢印を押しながらジャンプしていると言うと、プレーヤーは壁を上って飛びます。私は、衝突が側面から来ている場合(私はそうではないはずですが)、私の衝突検出機能が真を返すためですと仮定しています。 Edge collision bug ここで私の衝突検出機能は2つの 'オブジェクト'を取り、衝突が発生した最初のオブジェクトからの方向を返します。これは方向を返します

//Find the collision vectors 
     float vectorX = (a.Position.x + (a.Scale.x/2)) - (b.Position.x + (b.Scale.x/2)); 
     float vectorY = (a.Position.y + (a.Scale.y/2)) - (b.Position.y + (b.Scale.y/2)); 

     //Find the distance between the two objects 
     float deltaWidth = (a.Scale.x/2) + (b.Scale.x/2); 
     float deltaHeight = (a.Scale.y/2) + (b.Scale.y/2); 

     //Stores the direction of collision 
     Direction collisionDir = Direction::None; 

     //Check if the two objects are intersecting on the x and y axis 
     if (fabs(vectorX) < deltaWidth && fabs(vectorY) < deltaHeight) 
     { 
      //The direction of collision 
      float directionX = deltaWidth - fabs(vectorX); 
      float directionY = deltaHeight - fabs(vectorY); 

      //Check for vertical collision 
      if (directionX >= directionY) 
      { 
       //Check for collisions from the top 
       if (vectorY > 0) 
       { 
        a.Velocity.y = 0; 
        a.Position.y += directionY; 
        collisionDir = Direction::Up; 
       } 

       //Collisions form the botttom 
       else 
       { 
        a.Velocity.y = 0; 
        a.Position.y -= directionY; 
        collisionDir = Direction::Down; 
       } 
      } 

      else if (directionX < directionY/2) 
      { 
       //Check for collisions from the left 
       if (vectorX > 0) 
       { 
        a.Velocity.x = 0; 
        a.Position.x += directionX; 
        collisionDir = Direction::Left; 
       } 

       //Collisions form the right side 
       else 
       { 
        a.Velocity.x = 0; 
        a.Position.x -= directionX; 
        collisionDir = Direction::Right; 
       } 
      } 
     } 

     //Return the direction. 
     return collisionDir; 
、私の他のコードもその方向かどうかを確認する==ボトム、それができるようになります:上記のようにそれは、これが問題を引き起こしていると方向を決定することになると問題がそそりだと思いますジャンプする。

ありがとうございました。私はLudum Dareのために練習しています。(おそらく)プラットフォーマーを作ろうとしているからです。もし私が衝突検知を理解できなければ、私のゲームがどれくらい良いか分からないでしょう。

とにかく感謝 - コーダキャメロンは私が推薦する

+1

ゲームにロギングを追加すると、衝突検出に関連するすべてのデータが書き込まれます。こうすることで、誤った動作をする条件を見つけることができます。 –

答えて

3

まず最初は、自分自身の加算と減算2 Vector2Dsの乗算や除算を可能にするためにあなたのx、y座標といくつかの過負荷いくつかの演算子を保持しているVector2Dクラスを作成していますint、float、doubleによってあなたがすべての力と衝突点を持つことができるので、あなたの人生をもっと楽にしてくれると信じてください。デバッグするのは難しい)

A:私は衝突のスタイルを使用しているとき

次は、現在、私はいつもそれだことを発見したを使用しています。

B)他人があなたのコードに従うのが難しい。

他の四角形との衝突やその他の必要な機能を処理するRectangle2Dクラスの作成をお勧めします。

スケーリングと衝突検出をより簡単にする四角形の中心からのベクトルとして、左上隅と右下隅を推奨すると、他のコーナーを直接格納する必要なしに派生させることができます。

bool Intersects(Rectangle2D other) 
{ 
    //Checks the right, left, bottom then top of the rectangle 
    //against the other. 
    if(other.topLeftCorner.x >= bottomRightCorner.x  //Checks the right 
     || other.bottomRightCorner.x <= topLeftCorner.x //Checks the left 
     || other.topLeftCorner.y >= bottomRightCorner.y //Checks the bottom 
     || other.bottomRightCorner.y <= topLeftCorner.y) //Checks the top 
     return false; 
    else 
     return true; 
} 

あなたが簡単にあなたの衝突の方向性を与えるために、このコードを操作することができます:ここでは

は、おそらく私が説明しようとしている何に役立つのコード例です。お役に立てれば。

関連する問題