私はキャラクターがタイルの間を自由に歩くことができる等尺性タイルベースのゲームを書いていますが、衝突フラグを持つ特定のタイルにクロスオーバーすることはできません. 簡単に聞こえますが、Screen Coordinates to Tile メソッドを使用してプレーヤーが移動する場所を事前にチェックし、返された xy インデックスを使用してタイル配列をチェックして、衝突可能かどうかを確認するだけです。そうでない場合は、キャラクターを動かさないでください。私が抱えている問題は、Screen to Tile メソッドが適切な X、Y タイル インデックスを吐き出していないことです。この方法は、マウスでタイルを選択する場合に問題なく機能します。注: X タイルは左から右に、Y タイルは上から下に配置します。ネット上のいくつかの例から逆。関連するコードは次のとおりです。
public Vector2 ScreentoTile(Vector2 screenPoint) {
//Vector2 is just a object with x and y float properties
//camOffsetX,Y are my camera values that I use to shift everything but the
//current camera target when the target moves
//tilescale = 128, screenheight = 480, the -46 offset is to center
// vertically + 16 px for some extra gfx in my tile png
Vector2 tileIndex = new Vector2(-1,-1);
screenPoint.x -= camOffsetX;
screenPoint.y = screenHeight - screenPoint.y - camOffsetY - 46;
tileIndex.x = (screenPoint.x / tileScale) + (screenPoint.y / (tileScale / 2));
tileIndex.y = (screenPoint.x / tileScale) - (screenPoint.y / (tileScale / 2));
return tileIndex;
}
このコードを呼び出すメソッドは次のとおりです。
private void checkTileTouched () {
if (Gdx.input.justTouched()) {
if (last.x >= 0 && last.x < levelWidth && last.y >= 0 && last.y < levelHeight) {
if (lastSelectedTile != null) lastSelectedTile.setColor(1, 1, 1, 1);
Sprite sprite = levelTiles[(int) last.x][(int) last.y].sprite;
sprite.setColor(0, 0.3f, 0, 1);
lastSelectedTile = sprite;
}
}
if (touchDown) {
float moveX=0,moveY=0;
Vector2 pos = new Vector2();
if (player.direction == direction_left) {
moveX = -(player.moveSpeed);
moveY = -(player.moveSpeed / 2);
Gdx.app.log("Movement", String.valueOf("left"));
} else if (player.direction == direction_upleft) {
moveX = -(player.moveSpeed);
moveY = 0;
Gdx.app.log("Movement", String.valueOf("upleft"));
} else if (player.direction == direction_up) {
moveX = -(player.moveSpeed);
moveY = player.moveSpeed / 2;
Gdx.app.log("Movement", String.valueOf("up"));
} else if (player.direction == direction_upright) {
moveX = 0;
moveY = player.moveSpeed;
Gdx.app.log("Movement", String.valueOf("upright"));
} else if (player.direction == direction_right) {
moveX = player.moveSpeed;
moveY = player.moveSpeed / 2;
Gdx.app.log("Movement", String.valueOf("right"));
} else if (player.direction == direction_downright) {
moveX = player.moveSpeed;
moveY = 0;
Gdx.app.log("Movement", String.valueOf("downright"));
} else if (player.direction == direction_down) {
moveX = player.moveSpeed;
moveY = -(player.moveSpeed / 2);
Gdx.app.log("Movement", String.valueOf("down"));
} else if (player.direction == direction_downleft) {
moveX = 0;
moveY = -(player.moveSpeed);
Gdx.app.log("Movement", String.valueOf("downleft"));
}
//Player.moveSpeed is 1
//tileObjects.x is drawn in the center of the screen (400px,240px)
// the sprite width is 64, height is 128
testX = moveX * 10;
testY = moveY * 10;
testX += tileObjects.get(player.zIndex).x + tileObjects.get(player.zIndex).sprite.getWidth() / 2;
testY += tileObjects.get(player.zIndex).y + tileObjects.get(player.zIndex).sprite.getHeight() / 2;
moveX += tileObjects.get(player.zIndex).x + tileObjects.get(player.zIndex).sprite.getWidth() / 2;
moveY += tileObjects.get(player.zIndex).y + tileObjects.get(player.zIndex).sprite.getHeight() / 2;
pos = ScreentoTile(new Vector2(moveX,moveY));
Vector2 pos2 = ScreentoTile(new Vector2(testX,testY));
if (!levelTiles[(int) pos2.x][(int) pos2.y].collides) {
Vector2 newPlayerPos = ScreentoTile(new Vector2(moveX,moveY));
CenterOnCoord(moveX,moveY);
player.tileX = (int)newPlayerPos.x;
player.tileY = (int)newPlayerPos.y;
}
}
}
プレイヤーが左に移動している場合 (視聴者の視点からは左下っぽい)、Pos2 の X 値は期待どおりに減少しますが、pos2 は x タイルを先にチェックしておらず、Y タイルを先にチェックしています (あたかも左ではなく下に移動します)、およびその逆の場合、プレイヤーが下に移動すると、X 値を先にチェックします (下ではなく左に移動しているかのように)。Y 値の代わりに