2011-10-16 25 views
0

可能性の重複:
Java 2D Collision?のJava 2Dの衝突

やあみんな、私は私は私はこのに関するいくつかの新鮮な答えを得る試してみようと思いましただけで死んでしまったこのに関する別のポストを持っています。

私は衝突検出機能を働かせようとしています。私の衝突の検出は、私が地図ブロックの上に来るときにうまく動作します。上または下を押さえつけるだけで上または下からブロックを叩くだけです。しかし、私は右または左を保持したり、上または下からブロックを当てると面白い方向に進むでしょう。

私の小さなビデオ(明白でない場合は申し訳ありません):http://www.youtube.com/watch?v=6ILccRtw8MEこれはうまくいけば助かります。

あなたはここでビデオを見ていなかった場合は、マップの私が使用するの絵です:

public void checkCollision() { 
    Rectangle player_rectangle = new Rectangle(player.getX(),player.getY(),32,32); 

    for(Wall wall : walls) { 

     Rectangle wall_rectangle = new Rectangle(wall.getX(), wall.getY(), 32,32); 

     if (player_rectangle.intersects(wall_rectangle)) { 
      Rectangle intersection = (Rectangle) player_rectangle.createIntersection(wall_rectangle); 


      if (player.xspeed < 0 && player.x >= intersection.x) { 
       player.x += intersection.getWidth(); 
      } else { 

      if (player.xspeed > 0 && player.x <= intersection.x) { 
       player.x -= intersection.getWidth(); 
      } else { 

      if (player.yspeed < 0 && player.y >= intersection.y) { 
       player.y += intersection.getHeight(); 
      }else { 

      if (player.yspeed > 0 && player.y <= intersection.y) { 
       player.y -= intersection.getHeight(); 
      } 
      } 
      } 
      } 



      Print(Integer.toString(intersection.width) + ", " + Integer.toString(intersection.height)); 

     } 

    } 

} 

すべての助けになります。

enter image description here

をここでは私の現在の衝突コードがありますありがとう、ありがとう。

+0

それはあなたがあなたの[古いポスト]に尋ねた同じ質問ではないです(http://stackoverflow.com/questions/7763244/java-2d-collision)?はいの場合は、最後の質問に対して賞金を編集または開始し、再投稿しないでください。そうでない場合は、問題の詳細を説明してください。 – amit

+0

+1面白い動画です。ブロックワーピングftw。 –

+0

@ThomasJungblutおかしいとはどういう意味ですか? :L –

答えて

3

これは私の最初のStackOverflowに関する質問にお答えするためのものです。最初に問題を診断し、問題を引き起こす可能性のある症状を見つけ、最後に解決策を提示し、それがあなたと一緒に働くかどうかを確認することによって、この回答を構造化しようとします。

まず、正しいレベルのインデントでコードを書式設定して、何が起こっているのかをより明確に把握できるようにします。

public void checkCollision() { 
    Rectangle player_rectangle = new Rectangle(player.getX(), 
      player.getY(), 32, 32); 

    for (Wall wall : walls) { 

     Rectangle wall_rectangle = new Rectangle(wall.getX(), wall.getY(), 
       32, 32); 

     if (player_rectangle.intersects(wall_rectangle)) { 
      Rectangle intersection = (Rectangle) player_rectangle 
        .createIntersection(wall_rectangle); 

      if (player.xspeed < 0 && player.x >= intersection.x) { 
       player.x += intersection.getWidth(); 
      } else { 

       if (player.xspeed > 0 && player.x <= intersection.x) { 
        player.x -= intersection.getWidth(); 
       } else { 

        if (player.yspeed < 0 && player.y >= intersection.y) { 
         player.y += intersection.getHeight(); 
        } else { 

         if (player.yspeed > 0 && player.y <= intersection.y) { 
          player.y -= intersection.getHeight(); 
         } 
        } 
       } 
      } 

      Print(Integer.toString(intersection.width) + ", " 
        + Integer.toString(intersection.height)); 

     } 

    } 

} 

ここまでで、あなたがしていることがより明確になりました。私が気づいた最初のことは、条件文を入れ子にしていることです。明確にするために、あなたはこれをやっている:

if (condition){ 
    // do something 
    else{ 
     if(anotherCondition){ 
      // do something 
      else{ 
       //etc 
      } 
     } 
    } 
} 

このような行で複数の条件文を使用しているあなたがやるべきこと:

if (condition){ 
    //do something 
} 

if (anotherCondition){ 
    //do something else 
} 

//etc 

次の2つのケースを持っている場合ので、これはあなたのような、あります左下にある場合は、左に交差する条件と下に交差する条件を実行する必要があります。ただし、個々の壁を個別に通過するので、これはあなたの例とは無関係です。

これはなぜ重要なのですか?

最初の条件が満たされない場合、他の条件はすべて実行されないようです。 player.xspeed < 0 && player.x >= intersection.xtrueを返した場合、それにネストされた他の3つのステートメントがtrueを返しても、その最初のステートメントがfalseであるために実行されません。したがって、2つ以上のケースが真となるエッジに行くと、そのうちの1つだけが実行されます。

したがって、上記のすべてに基づいて、私の提案された解決策は、これです:

public void checkCollision() { 
     Rectangle player_rectangle = new Rectangle(player.getX(), 
       player.getY(), 32, 32); 

     for (Wall wall : walls) { 

      Rectangle wall_rectangle = new Rectangle(wall.getX(), wall.getY(), 
        32, 32); 

      if (player_rectangle.intersects(wall_rectangle)) { 
       Rectangle intersection = (Rectangle) player_rectangle 
         .createIntersection(wall_rectangle); 

       if (player.xspeed < 0 && player.x >= intersection.x) { 
        player.x += intersection.getWidth(); 
       } 

       if (player.xspeed > 0 && player.x <= intersection.x) { 
        player.x -= intersection.getWidth(); 
       } 

       if (player.yspeed < 0 && player.y >= intersection.y) { 
        player.y += intersection.getHeight(); 
       } 

       if (player.yspeed > 0 && player.y <= intersection.y) { 
        player.y -= intersection.getHeight(); 
       } 

       Print(Integer.toString(intersection.width) + ", " 
         + Integer.toString(intersection.height)); 

      } 

     } 

    } 

はこれを試してみて、それが動作するかどうかを確認します。そうでない場合は、そこから取り出して、問題を改善して解決する方法を見てください。

+0

返事ありがとうございます、悲しいことに、今でもそのコードを使用していません:L右から左に来て、上/下を押してもランダムにジャンプします –

+0

面白いです。私はすぐに私の答えを編集する必要があります。さらにそれについて考える必要があります。 – CodingMo

0

私は、checkCollisionが対処する必要があると想像できるすべての異なる状態の単体テストを書くことをお勧めします。 この方法で、あなたがよ:(ユニットテストが不足しているとよく含まれているため)

  • 簡単に特定の入力はブロックがジャンプする原因となっている
  • を見つけるこの機能は破られないことを確認してください

    public class CollisionTests { 
    
        @Test 
        public void hitFromLeftHeadOn() throws Exception { 
         List<Wall> walls = Lists.newArrayList(
          new Wall(...), // south wall 
          new Wall(...), // east wall 
          // etc. 
         ); 
         Player player = new Player(...); 
    
         // Set player to collide with the east wall head on 
         player.setX(...); 
         player.setY(...); 
         player.setXSpeed(...); 
         player.setYSpeed(...); 
    
         checkCollision(); 
    
         // Now check if the checkCollision method worked properly 
         assertEquals("Player's x coordinate should be set to ...", ..., player.getX()); 
         assertEquals("Player's y coordinate should be set to ...", ..., player.getY()); 
        } 
    
    012:
    将来の変化によって

は、このためのサンプルユニットテストは、次のようになります(ユニットテストは、各ビルドで実行されているので)

一度テストを書いたら、さらに追加するのは簡単です。壁、プレーヤーなどを作成するさまざまなヘルパーメソッドを作成して、各テストケースを数行に縮小することができます。おまけとして

Here's a tutorial on unit testing.

あなたはユニットテストを書く場合、あなたはまた、SSCCEを書かれているよ:)