# Probleme mit Kameraausrichtung bei ISO-Map



## Steev (11. Feb 2010)

Hallo liebe Forengemeinde,

ich habe einen kleinen Denkfehler bei der Ausrichtung einer Kamera auf einer isometrischen Tilemap. Wie in vielen (älteren) Spielen will ich meine isometrische Welt aus vier verschiedenen Perspektiven anzeigen lassen. Zu diesem Zweck habe ich jedem Objekt verschiedene Ansichten mitgegeben und lasse diese entsprechend rendern. Das klappt auch soweit. Jetzt habe ich nur das Problem, dass sich die Karte dreht und die Kamera auf eine völlig andere Stelle guckt. Ist ja auch klar, die Stelle, wo die Kamera jetzt steht ist die alte Position. Ich muss irgendwie die Kamera mitdrehen damit die Kamera auf exakt dieselbe Position guckt, von der aus ich die Ansicht geändert habe. Leider weis ich nicht ganz, wie ich das anstellen soll.

Eine Ansichtsänderung von Norden nach Süden habe ich schon hinbekommen, aber was ist, wenn die Ansicht von Norden nach Osten oder Westen geändert wird. :?: Keine Ahnung :-(

Hier mal eine kleine Skizze, auf der ich mal probiert habe aufzuzeichnen was ich meine. Die Raute ist meine Map und die verschiedenen Vierecke sind die Kameraansichten darauf.







Hier nochmal die bewuste Stelle im Code:
[Java]@Override
    public synchronized void setDirection(Direction direction) {
        Direction oldDirection = getDirection();

        super.setDirection(direction);

        // Translieren der Kameraposition
        if (camera != null && getTiles() != null && oldDirection != direction) {
            // Berechne den Offset der Kamera zum Mittelpunkt der Karte
            int width = getTiles().length;
            int height = getTiles()[0].length;

            double mapW = width * getTileWidth();
            double mapH = height * getTileHeight();
            double camMaxX = (mapW - camera.getWidth());
            double camMaxY = (mapH - camera.getHeight());
            double mapCenterX = mapW / 2.;
            double diffX = mapCenterX + camMaxX - camera.getX() - getX();
            double diffY = camMaxY - camera.getY() - getY();

            // Änderung von Nord nach Süd oder umgekehrt
            if ((oldDirection == Direction.NORTH || oldDirection == Direction.SOUTH) && (direction == Direction.NORTH || direction == Direction.SOUTH))
                camera.setY(diffY);

            // Alles weiter, keine Ahnung :-(
        }
    }[/Java]

Ich hoffe ihr habt mein Problem verstanden


----------



## Quaxli (12. Feb 2010)

Würde es nicht ausreichen, wenn Du die Kamera immer auf die Spielfigur zentrierst?


----------



## Steev (12. Feb 2010)

Hi Quaxli, das Problem ist, dass ich nicht umbedingt eine Spielfigur habe. Wenn man sich einfach nur beim Bauen mal schnell die Ansicht wechseln will, weil ein Objekt verdeckt wird, dann geht das ja auch nicht.

Ich habe mittlerweile mein Problem auch (fast) gelößt. In der Mitte der Karte muss die Position der Kamera ja nicht verschoben werden, weil die Position bei jeder Ausrichtungsänderung gleich bleibt. Deshalb gehe ich einfach von dem Mittelpunkt der Karte aus und berechne die Differenz. Auf der X-Achse habe ich dann noch zusätzlich das Problem, dass der Nullpunkt genau in der Mitte der Karte liegt. Da gehe ich jetzt einfach her und verschiebe den Nullpunkt auf den Anfang der Karte und berechne dann die Position genau wie auf der Y-Achse.

NORD nach SÜD und SÜD nach NORD funktioniert.
OST nach WEST und WEST nach OST funktioniert.

Das einzige Problem was ich jetzt nur habe ist, wenn ich von NORD nach OST oder OST nach SÜD die Ansicht wechsle.
Das weis ich noch nicht so ganz, wie ich das machen muss.


----------



## Steev (13. Feb 2010)

Ok,

das Problem hat sich erledigt :-D
Ich habe nur einen total dummen Denkfehler gemacht. Man muss natürlich die Kamera-Koordinaten in Verbindung mit dem Mittelpunkt der Map transformieren, sonst kann es ja nicht gehen...

Das hier wäre ist richtige Lösung:

[Java]    @Override
    public synchronized void setDirection(Direction direction) {
        Direction oldDirection = getDirection();

        super.setDirection(direction);

        // Translieren der Kameraposition
        if (camera != null && getTiles() != null && oldDirection != direction) {
            // Berechne den Mittelpunkt der Karte
            int height = getTiles()[0].length;
            double mapH = height * getTileHeight();
            double mapCenterY = mapH / 2.;

            // Berechne die Kamerakoordinaten auf der Karte
            double cameraCenterX = camera.getWidth() / 2.;
            double cameraCenterY = camera.getHeight() / 2.;
            double cameraX = camera.getX() + cameraCenterX - getX();
            double cameraY = camera.getY() + cameraCenterY - getY() - mapCenterY;

            if ((oldDirection == Direction.NORTH && direction == Direction.SOUTH) ||
                (oldDirection == Direction.SOUTH && direction == Direction.NORTH)) {
                camera.setY(-cameraY + mapCenterY - cameraCenterY);
            }

            if ((oldDirection == Direction.EAST && direction == Direction.WEST) ||
                (oldDirection == Direction.WEST && direction == Direction.EAST)) {
                camera.setX(-cameraX - cameraCenterX + (getTileWidth() * 1.5));
            }

            if ((oldDirection == Direction.NORTH && direction == Direction.EAST) ||
                (oldDirection == Direction.EAST && direction == Direction.NORTH) ||
                (oldDirection == Direction.SOUTH && direction == Direction.WEST) ||
                (oldDirection == Direction.WEST && direction == Direction.SOUTH)) {
                camera.setX(-(cameraY * 2.) - cameraCenterX + (getTileWidth() * 1.5));
                camera.setY(-(cameraX / 2.) + mapCenterY - cameraCenterY);
            }

            if ((oldDirection == Direction.EAST && direction == Direction.SOUTH) ||
                (oldDirection == Direction.SOUTH && direction == Direction.EAST) ||
                (oldDirection == Direction.WEST && direction == Direction.NORTH) ||
                (oldDirection == Direction.NORTH && direction == Direction.WEST)) {
                camera.setX((cameraY * 2.) - cameraCenterX + (getTileWidth() * 1.5));
                camera.setY((cameraX / 2.) + mapCenterY - cameraCenterY);
            }
        }
    }[/Java]


----------

