Um sich Camera
in TiledMap
Grenzen zu bewegen , OrthogonalTiledMapRenderer
wurde verwendet.
Mir ist auch aufgefallen, dass es sich unerwartet verhält: Während Camera
die Kartengrenzen erreicht werden, bewegt sich die gekachelte Karte wie durch Trägheit einige Pixel zu weit (dies hängt von der Geschwindigkeit des Wischens ab).
Als Lösung wird bei jeder Camera
Bewegung Camera
zwangsweise in Kartengrenzen gesetzt. Siehe putInMapBounds()
Methode.
Um Störungen beim TiledMap
Rendern zu vermeiden , wird verwendet Math.min(float, float)
.
Verwenden Sie diesen Listener, um Folgendes zu handhaben Camera
:
/**
* @author Gram <gram7gram@gmail.com>
*/
public class CameraListener extends InputAdapter {
private final UIStage stage;
private final Camera camera;
private final Vector3 curr;
private final Vector3 last;
private final Vector3 delta;
private final int mapWidth;
private final int mapHeight;
public CameraListener(UIStage stage) {
this.stage = stage;
this.camera = stage.getViewport().getCamera();
curr = new Vector3();
last = new Vector3(-1, -1, -1);
delta = new Vector3();
TiledMapTileLayer layer = stage.getLevel().getMap().getFirstLayer();
mapWidth = layer.getWidth() * DDGame.TILE_HEIGHT;
mapHeight = layer.getHeight() * DDGame.TILE_HEIGHT;
}
@Override
public boolean touchDragged(int x, int y, int pointer) {
camera.unproject(curr.set(x, y, 0));
if (!(last.x == -1 && last.y == -1 && last.z == -1)) {
camera.unproject(delta.set(last.x, last.y, 0));
delta.sub(curr);
camera.translate(Math.min(delta.x, 5), Math.min(delta.y, 5), 0);
if (isInMapBounds()) {
stage.moveBy(Math.min(delta.x, 5), Math.min(delta.y, 5));
}
}
last.set(x, y, 0);
putInMapBounds();
return false;
}
private boolean isInMapBounds() {
return camera.position.x >= camera.viewportWidth / 2f
&& camera.position.x <= mapWidth - camera.viewportWidth / 2f
&& camera.position.y >= camera.viewportHeight / 2f
&& camera.position.y <= mapHeight - camera.viewportHeight / 2f;
}
private void putInMapBounds() {
if (camera.position.x < camera.viewportWidth / 2f)
camera.position.x = camera.viewportWidth / 2f;
else if (camera.position.x > mapWidth - camera.viewportWidth / 2f)
camera.position.x = mapWidth - camera.viewportWidth / 2f;
if (camera.position.y < camera.viewportHeight / 2f)
camera.position.y = camera.viewportHeight / 2f;
else if (camera.position.y > mapHeight - camera.viewportHeight / 2f)
camera.position.y = mapHeight - camera.viewportHeight / 2f;
stage.moveTo(
camera.position.x,
camera.position.y);
}
@Override
public boolean touchUp(int x, int y, int pointer, int button) {
last.set(-1, -1, -1);
Log.info("Camera at " + camera.position.x + ":" + camera.position.y);
return false;
}
}
setPosition()
Methode aufzurufen , die die Grenzen festlegt, habe ich immer noch die Nockenposition direkt eingestellt (zBcam.position.set()
). Das funktioniert wie ein Zauber! Danke für die Erklärung!