2009-08-19 23 views
2

私の衝突検出を正しく動作させる方法を見つけようとしているのですが、私の壁のオブジェクトはリストの中に積み重ねられています。 DetectCollisionメソッドでは、オブジェクトが壁の内側にあるかどうかによってtrueまたはfalseを返します。C#2D衝突検出の問題

ウォールが衝突を検出プレイヤーが移動しようとする私のプレーヤー機能でそう

public bool DetectCollision(float x, float y) 
    { 
     if ((x >= this.XCoordinate && x <= (this.XCoordinate + this.BlockWidth)) && (y >= this.YCoordinate && y <= (this.YCoordinate + this.BlockHeight))) 
      return true;    
     else 
      return false; 
    } 

(X軸、Y座標は壁の位置です)、私は一時的なX、Yへの移動を追加しますそれらが壁に衝突するかどうかチェックします。もし何も起こらなければ、そうでなければ私はプレーヤーを動かします。

しかし、私はそれがすべきではないことに気付きました。私がゲームフィールドの中に壁の部分を追加すると、コリジョン検出の右下隅のみがチェックされます。

プレーヤーの移動方法:

 float x, y; 
     if (direction == Direction.E) 
     { 
      x = LiveObjects.player.XCoordinate - MovementSpeed; 
      y = LiveObjects.player.YCoordinate; 
     } 
     else if (direction == Direction.W) 
     { 
      x = LiveObjects.player.XCoordinate + MovementSpeed; 
      y = LiveObjects.player.YCoordinate; 
     } 
     else if (direction == Direction.N) 
     { 
      x = LiveObjects.player.XCoordinate; 
      y = LiveObjects.player.YCoordinate - MovementSpeed; 
     } 
     else 
     { 
      x = LiveObjects.player.XCoordinate; 
      y = LiveObjects.player.YCoordinate + MovementSpeed; 
     } 

     if (GameMechanics.DetectWallCollision(x, y) || GameMechanics.DetectWallCollision((x + LiveObjects.player.BlockWidth), (y + LiveObjects.player.BlockHeight)) 
     { 
      OnPlayerInvalidMove(null, new PlayerEventArgs()); 
      return; 
     } 

とDetectWallCollisionためのループだけです:

foreach (Wall wall in LiveObjects.walls) 
     { 
      if (wall.DetectCollision(x, y)) 
       return true; 
     } 
     return false; 

任意のアイデア?

+0

座標系のレイアウトはどのようになっていますか(0,0ポイントはどこですか)? – Niko

+0

左上隅が0, – Patrick

+0

です。DetectCollisonメソッドを "return(x> = this.XCoordinate && x <=(this.XCoordinate + this.BlockWidth))&&(y> = this.YCoordinate && y <=(this.YCoordinate + this.BlockHeight)); " –

答えて

0

DetectCollisionメソッドは壁の位置を取得すると言いましたが、コードを正しく解釈するとDetectWallCollisionにxとyパラメータが渡されます(移動後)。 DetectCollisionメソッドの位置にあるプレイヤーとハンド...

コードをデバッグして、どの座標がコリジョンメソッドに渡されているかを確認し、if文が実行されているルートをトレースしましたか?

何らかの理由であなたのコードをデバッグすることができない場合は - トレースファイルの書き込み - 私は解決策をひざに落ちるだろうと思います;)

+0

私は抽象クラスブロックを使用する基本ビルディングブロックがあります。このブロックには、ブロックの高さと幅が印刷される場所のX座標とY座標が含まれています。 したがって、壁オブジェクトはベースブロックを継承し(プレーヤーと同じです)、壁クラスはDetectCollisionメソッドを追加します。 メソッドdetect collisionは、2つのパラメータXとYを取り、XまたはYがブロック(壁)の内側にあるかどうかをチェックします。 – Patrick

+1

時にはコード上で目が見えないことがありますが、解決策はもちろん、左上隅と右下だけでなく、プレーヤーオブジェクトのすべてのコーナーをチェックすることでした。トレースは時には非常に便利です=) – Patrick

0

あなたの東西は約間違った方法です。左下が0,0の座標系を持ち、右または下に移動すると積極的に増加し、西の動きは通常Xの値が減少することを意味する動きが残っていることを意味し、東の動きは逆になります。あなたはその反対をしています。

+0

修正してください。しかし、それはまだ衝突検出の問題を解決しません – Patrick

1

あなたの世界には無限に小さいものはないと仮定しています(つまり、ピクセルのサイズです)。真のバウンディングボックスのコリジョンを得るには、のサイズを両方とものオブジェクトだけでなく考慮する必要があります。

boolean intersectsEntity(Entity e) 
{ 
    return (e.position.x <= position.x + size.x) && 
      (e.position.y <= position.y + size.y) && 
      (e.position.x + e.size.x >= position.x) && 
      (e.position.y + e.size.y >= position.y); 
} 

もちろんエンティティには位置とサイズのベクトルがあるとします。したがって、size.x == width、size.y == height。