2017-06-29 4 views
1

私は現在、トップダウン・シューターに取り組んでおり、衝突に関するいくつかの問題があります。 私の世界はタイルで作られています(64x64)。タイルとエンティティは長方形です。プレーヤーは、例えば2.74の速度で移動する(滑らかな動きのためにピクセルではない)。しかし、それはプレーヤー(エンティティ)と壁の間に衝突になると私はいくつかの問題があります。衝突があるかどうかを確認するには、プレーヤーの現在位置と移動速度を取って、次の位置がどこになるか、そして衝突があるかどうかを計算します。しかし、私は途中ですべてのピクセルをチェックするので、移動速度が非常に速い場合でも私は障害をスキップできません。プレイヤーの現在の位置がX:200 Y:200で、彼が2.74ピクセルをx方向に1チック動かしているとしましょう。私のゲームでは、X:201 Y:200、X:202 Y:200またはX:202.74 Y:200に衝突があるかどうかを確認し、そうでなければその位置にプレーヤーを移動します。私が今プレイヤーをx方向にさらに移動しようとすると、壁が0.26ピクセル離れていると、プレイヤーは動かずに小さなギャップを残します。私はプレーヤーと壁の距離を計算して、この量をプレーヤーの位置に追加しようとしましたが、そのためには、プレーヤーの壁のどちら側に当たるかを知る必要があります。また、彼が当たる壁が彼の目の前に、そして逆の方向に来ると、プレイヤーは上下に移動することができます。ここでJava - Pixel-Perfect Collision - プレイヤーと壁のギャップ

は私の衝突方法は、(Javaで)です:

public static boolean collision(float ex, float ey, int width, int height) { // ex, ey would be the next position of the player 
    if (ex < 0 || ex + width > worldWidth || ey < 0 || ey + height > worldHeight) return true; // checks if this position is in the world 
    int firstTileX = (int) (ex/Tile.TILE_SIZE); // calculates tiles he could possible collide width 
    int firstTileY = (int) (ey/Tile.TILE_SIZE); 
    int lastTileX = (int) ((ex + width - 1)/Tile.TILE_SIZE); 
    int lastTileY = (int) ((ey + height - 1)/Tile.TILE_SIZE); 
    for (int y = firstTileY; y <= lastTileY; y++) { 
     if (y < 0) continue; // checks for out of bounds 
     if (y >= worldTileHeight) break; 
     for (int x = firstTileX; x <= lastTileX; x++) { 
      if (x < 0) continue; 
      if (x >= worldTileWidth) break; 
      if (tiles[y][x].solid) return true; // if the tile is solid -> collision found 
     } 
    } 
    return false; // no collision found 
} 

そして、私の移動方法:

public void move(float xa, float ya) { 
    float nx, ny; 
    while (xa != 0 || ya != 0) { 
     nx = x; 
     ny = y; 
     if (xa != 0) { 
      if (Math.abs(xa) > 1) { // if the x-speed is greater than 1 
       nx = x + MathUtil.abs(xa); // returns -1 for negative numbers and 1 for positiv 
       xa -= MathUtil.abs(xa); 
      } else { // less than 1 
       nx = x + xa; 
       xa = 0; 
      } 
     } 
     if (ya != 0) { // same here 
      if (Math.abs(ya) > 1) { 
       ny = y + MathUtil.abs(ya); 
       ya -= MathUtil.abs(ya); 
      } else { 
       ny = y + ya; 
       ya = 0; 
      } 
     } 
     if (!Level.collision(nx, ny, width, height)) setPosition(nx, ny); // checks if there is an collision and sets the new position if not 
     else if (!Level.collision(nx, y, width, height)) x = nx; // if there was a collision check if the player can walk in x direction 
     else if (!Level.collision(x, ny, width, height)) y = ny; // or in y direction 
    } 
} 

私の問題は、彼のポスト()でCoderMusgroveの問題として、ほとんど同じです:

概要&質問

私はエンティティの速度がそれが進んでいるタイルからの距離よりも大きい場合、それは少なくともそれ自身とタイルの間のピクセルを残すでしょう、そして私は本当にこれが気に入らないという問題があります。どのような種類のアルゴリズムを使用してエンティティとタイルの最も小さな違いを見つけることができますか?

追加情報が必要な場合は、追加することができます。

ありがとうございました!

+0

この回答を確認してください。https://stackoverflow.com/a/43979300/5343269、それはJavascript用ですが、概念は同じだと思います。 – 11thdimension

答えて

0

解釈を変更して簡単に解決できます。

細かいスピードを目的として、分数位置を保持しています。衝突検出と表示のための割合を無視します(サブピクセルレンダリングを行う場合は、サブピクセルレンダリングの精度レベルで衝突させます)。

int screenX = (int) Math.round(objX); 
int screenY = (int) Math.round(objY); 
// rendering and collision detection based on rounded position