2012-03-07 8 views
1

私はさまざまな形の単純衝突検出を様々な結果で実装しています。私は衝突検出のかなり良いバージョンを持っていますが、うまくいかない奇妙な振る舞いがあります。オブジェクトの衝突検出と維持運動

ちょうど参考のために、私は単純なポンゲームを作って、衝突を洗練しようとしています。私が得る問題は、ボールが上面または底面のいずれかのパドルに衝突したときである。そのような場合、ボールはパドルの上(または下)に移動し、移動しません。私はこれを推測しているのは、どうやって衝突をチェックしているのか、そしてどのようにボールの移動速度を変えているからです。

私は、トップ/ボトムおよび左/右の衝突を区別する方法を実装したいと思いますが、これはちゃんと動作する唯一の方法である:

static void CheckCollision(PActor object1, PActor object2, PInput pinput) 
{ 
    if (CheckObjectCollision(object1, object2)) 
    { 
     AdjustMoveSpeed(object1, object2, pinput); 
    } 
} 



static bool CheckObjectCollision(PActor object1, PActor object2) 
{ 
    int object1LeftBound = object1.position.x; 
    int object1RightBound = object1.position.x + object1.actorTextureXSize; 
    int object1TopBound = object1.position.y; 
    int object1BottomBound = object1.position.y + object1.actorTextureYSize; 

    int object2LeftBound = object2.position.x; 
    int object2RightBound = object2.position.x + object1.actorTextureXSize; 
    int object2TopBound = object2.position.y; 
    int object2BottomBound = object2.position.y + object2.actorTextureYSize; 

    if (object1RightBound < object2LeftBound) 
     return false; 

    if (object1LeftBound > object2RightBound) 
     return false; 

    if (object1BottomBound < object2TopBound) 
     return false; 

    if (object1TopBound > object2BottomBound) 
     return false; 

    return true;   
} 

私は推測していますその問題のいくつかのルート私が抱えているここにある、関数AdjustMoveSpeedです:ボールであるオブジェクトを参照するには、最初のチェックで、この後、によってXの移動速度を掛け、

static void AdjustMoveSpeed(PActor object1, PActor object2, PInput pinput) 
{ 
    PVector prevMouseLocation = pinput.GetPrevMouseLocation(); 
    PVector currMouseLocation = pinput.GetCurrMouseLocation(); 

    int currentMoveSpeed; 
    int nextMoveSpeed; 

    if (typeid(object1) == typeid(PBall)) 
    { 

     object1.moveSpeed.x *= -1; 

     if (typeid(object2) == typeid(PPlayer)) 
     { 
      currentMoveSpeed = object1.moveSpeed.y; 
      nextMoveSpeed = prevMouseLocation.y - currMouseLocation.y; 

      object1.moveSpeed.y = (prevMouseLocation.y - currMouseLocation.y) * -1; 

     } 
     else 
     { 
      if (object1.moveSpeed.y > 0) 
       object1.moveSpeed.y *= -1; 
     } 
    } 
    else if (typeid(object2) == typeid(PBall)) 
    { 

     object2.moveSpeed.x *= -1; 

     if (typeid(object1) == typeid(PPlayer)) 
     { 
      currentMoveSpeed = object1.moveSpeed.y; 
      nextMoveSpeed = prevMouseLocation.y - currMouseLocation.y; 

      object2.moveSpeed.y = (prevMouseLocation.y - currMouseLocation.y) * -1; 
     } 
     else 
     { 
      if (object2.moveSpeed.y > 0) 
       object2.moveSpeed.y *= -1; 
     } 
    }  
} 

私はAdjustMoveSpeedをどうしようとしていた何を - その方向を逆にする。その後、他のオブジェクトがプレーヤーかどうかを確認します。もしそうなら、前のマウスの位置と現在のマウスの位置の差にyの移動速度を設定します。これは、ボールyの速度を変更するか、またはスピンを追加するプレーヤーオプションを与えるためです。

私は特定の側面を得ることができるようにオブジェクト間の交差をチェックしようとしました。その結果、ボールは実際にどちらのパドルにも当たらずに画面の真ん中を飛んでいます。

正方形である2つのオブジェクトの衝突検出を正しくチェックするにはどうすればよいですか?

AdjustMoveSpeedを修正して、衝突検出で正しく動作するようにするにはどうすればよいですか?

最後に、現在のスピードのボールの勢いを、ヒット前後のマウスの位置の差よりも大きくするにはどうすればよいですか?

私はcurrentMoveSpeedとnextMoveSpeedの絶対値を比較しようとしましたが、ボールはyスピードを変更しませんでした。

答えて

6

ポンではなくボールに各フレームを移動し、パドルとの衝突をチェックするよりも、あなたが実際には、パドルとボールがに衝突するときのための方程式を解くことができる、ということは十分に簡単です - その時があれば1フレーム未満では、衝突が存在する。

これはボールがパドルをすばやく動くという問題を完全に排除します。これは、単純な衝突検出方法を使用する多くのポンクローンを悩ませる問題です。

このソリューションはcontinuous collision detectionと呼ばれています。詳細はthis answerを参照してください。

+0

よろしくお願い致します。 – RedShft

2

ボールがバウンドするのではなくパドルにかかった場合は、ボールが前後に向きを変えている可能性が高いためです。ボールがパドルに向かっている場合、ボールは跳ね返るだけです。

if (sgn(object1.moveSpeed.x) == sgn(object1.x - object2.x)) { 
    // Ball is already moving away from the paddle, don't bounce! 
} 
else { 
    // Ok to bounce! 
    object1.moveSpeed.x *= -1; 
} 
+0

ありがとう、それは方向を前後に変える限り正しいです。 sgn(object1.moveSpeed.x)は何をしますか?私はまだDでそれに遭遇していません。そのD関数を仮定します。 – RedShft

+0

Dについては分かりませんが、sgnは正の数は+1、負の数は-1を返す符号関数です。 –