2012-03-22 6 views
0

これは私が同じ領域で問題を抱えている2番目のゲームです... 最初の1つ私はそれを正確にどのように修正したか分かりません。座標系も倍になりました。Java:2Dワールドコリジョン検出コードのバグ

これは、世界のすべてのオブジェクト(選手、敵、アイテム)によって継承される物理クラスの「更新」コードです。 これらのオブジェクトはすべて世界との衝突に従うことができなければならないので、xSpeedまたはySpeedを持っているときにコードのこの部分が実行され、オブジェクトが正しいスペースにスナップされますソリッド(ダビング状態2)ワールドタイル。各世界タイルは20×20ピクセルです。

問題: それはあなたが右のタイルにスナップなら、あなたは上下に移動したりすることはできません

...除いて完全に正常に動作します。 (左に移動して上または下に移動できますが)

下のタイルにスナップすると、左右に移動することはできません。 (上に移動して左または右に移動することはできますが)

if(xSpeed<0){ 
     try{ 
      int dest = hitbox.x + (int)(xSpeed/20*tick); 
      if(Ids.tiles[world[dest/20][hitbox.y/20]].getState() == 2 || Ids.tiles[world[dest/20][(hitbox.y+hitbox.width)/20]].getState() == 2){ 
       hitbox.x = (int)Math.ceil(dest/20.)*20; 
       xSpeed = 0; 
      }else{ 
       hitbox.x += (int)(xSpeed/20*tick); 
      } 
     }catch(Exception e){ 
      hitbox.x += (int)(xSpeed/20*tick); 
     } 
    }else if(xSpeed>0){ 
     try{ 
      int dest = hitbox.x+hitbox.width+(int)(xSpeed/20*tick); 
      if(Ids.tiles[world[dest/20][hitbox.y/20]].getState() == 2 || Ids.tiles[world[dest/20][(hitbox.y + hitbox.width)/20]].getState() == 2){ 
       hitbox.x = dest/20*20 - hitbox.width; 
       xSpeed = 0; 
      }else{ 
       hitbox.x += (int)(xSpeed/20*tick); 
      } 
     }catch(Exception e){ 
      hitbox.x += (int)(xSpeed/20*tick); 
     } 
    } 

    if(ySpeed<0){ 
     try{ 
      int dest = hitbox.y + (int)(ySpeed/20*tick); 
      if(Ids.tiles[world[hitbox.x/20][dest/20]].getState() == 2 || Ids.tiles[world[(hitbox.x + hitbox.width)/20][dest/20]].getState() == 2){ 
       hitbox.y = (int)Math.ceil(dest/20.)*20; 
       ySpeed = 0; 
      }else{ 
       hitbox.y += (int)(ySpeed/20*tick);; 
      } 
     }catch(Exception e){ 
      hitbox.y += (int)(ySpeed/20*tick);; 
     } 
    }else if(ySpeed>0){ 
     try{ 
      int dest = hitbox.y + hitbox.height + (int)(ySpeed/20*tick); 
      if(Ids.tiles[world[hitbox.x/20][dest/20]].getState() == 2 || Ids.tiles[world[(hitbox.x + hitbox.width)/20][dest/20]].getState() == 2){ 
       hitbox.y = dest/20*20 - hitbox.height; 
       ySpeed = 0; 
      }else{ 
       hitbox.y += (int)(ySpeed/20*tick);; 
      } 
     }catch(Exception e){ 
      hitbox.y += (int)(ySpeed/20*tick);; 
     } 
    } 
+0

あなたのコードは少し長いですが、私の本能は、それがどこかで '<='の代わりに '<'であるか、その逆であると言います。 – biziclop

+0

コード内のいくつかのコメントが間違いなく助けになるでしょう: 'world [x]'とはどういう意味ですか? 'magic 'の値' 20'はどういう意味ですか? – Thomas

+0

'hitbox.y/20'のようなコードには精密な問題があるかもしれません。あなたのコードをデバッグし、その計算の中間値をチェックしましたか? – Thomas

答えて

1

右端(右に移動する)の衝突を考慮してください。この条件は、合格:

Ids.tiles[world[dest/20][hitbox.y/20]].getState() == 2 

と仮定hitbox.widthはすぐhitbox.xとしては15です。しかし、あなたはその後、dest/20*20 - hitbox.widthhitbox.xをリセットし、それが既にある場所を正確になるように動作しているとして、これはtrueを返します5です。次に、垂直方向にオブジェクトが移動すると、右端が既にタイルに衝突しているため移動できません。

これを修正するには、グリッド位置を参照するためにヒットボックスサイズを使用するときにヒットボックスサイズから1ピクセルを減算します。

浮動小数点座標で作業していた場合は、Math.ceil((hitbox.x + hitbox.width)/20.0) - 1を使用して、任意のイプシロンを使用せずに同様の効果を生成します。