Title: miniworlds: Kamera benutzen

# Die Kamera in miniworlds

In einer miniworlds-Welt gibt es oft mehr Inhalte als gerade auf den Bildschirm
passen. Die **Kamera** entscheidet, welchen Ausschnitt der Welt sichtbar ist.

Am Anfang ist das noch unsichtbar: Wenn die Welt genauso groß ist wie das
Fenster, muss die Kamera nichts verschieben.

import miniworlds

world = miniworlds.World(500, 300)

spieler = miniworlds.Actor((120, 150))

ziel = miniworlds.Circle((400, 150), 25)

world.run()

### Eine größere Welt

Jetzt machen wir die Welt breiter als den sichtbaren Ausschnitt. Das Fenster
bleibt 500 Pixel breit, aber die Welt bekommt mehr Platz. Dafür setzen wir
`world.camera.world_size_x`.

import miniworlds

world = miniworlds.World(500, 300)

world.camera.world_size_x = 1200

spieler = miniworlds.Actor((120, 150))

world.run()

Das Ziel liegt bei `x = 1000`. Es existiert in der Welt, ist aber am Anfang
nicht sichtbar, weil die Kamera noch links steht.

!!! note Weltkoordinaten und Bildschirmkoordinaten
Die Position eines Actors ist seine Position in der ganzen Welt. Die Kamera
zeigt nur einen Ausschnitt davon. Ein Actor kann also in der Welt sein, aber
außerhalb des sichtbaren Bildes liegen.

### Kamera von Hand verschieben

Die Kamera hat eine linke obere Ecke. Diese kannst du direkt setzen:

* `world.camera.x = 300` verschiebt den sichtbaren Ausschnitt nach rechts.
* `world.camera.y = 100` verschiebt den sichtbaren Ausschnitt nach unten.
* `world.camera.topleft = (300, 0)` setzt beide Werte zusammen.

import miniworlds

world = miniworlds.World(500, 300)
world.camera.world_size_x = 1200

spieler = miniworlds.Actor((120, 150))

ziel = miniworlds.Circle((500, 150), 25)

@world.register
def on_key_pressed_right(self):
world.camera.x = world.camera.x + 1

@world.register
def on_key_pressed_left(self):
world.camera.x = world.camera.x - 1

world.run()

Mit den Pfeiltasten verschiebst du den sichtbaren Ausschnitt nach links und
rechts. Der Spieler ist nicht weg, er liegt nur außerhalb des
Kameraausschnitts.

### Kamera einem Actor folgen lassen

Meist soll die Kamera nicht fest stehen, sondern dem Spieler folgen. Dafür
gibt es `world.camera.from_actor(spieler)`.

import miniworlds

world = miniworlds.World(500, 300)
world.camera.world_size_x = 1200

spieler = miniworlds.Actor((120, 150))

ziel = miniworlds.Circle((500, 220), 25)

@spieler.register
def act(self):
self.x = self.x + 2
world.camera.from_actor(self)

world.run()

Die Kamera wird in jedem Frame neu auf den Spieler ausgerichtet. Dadurch
wandert der sichtbare Ausschnitt mit.

### Mit Tasten steuern

Jetzt steuerst du den Spieler selbst. Die Kamera folgt weiterhin automatisch.

import miniworlds

world = miniworlds.World(500, 300)
world.camera.world_size_x = 1200

spieler = miniworlds.Actor((120, 150))

marke = miniworlds.Actor((x, 250))

@spieler.register
def act(self):
world.camera.from_actor(self)

@spieler.register
def on_key_down_right(self):
self.x = self.x + 20

@spieler.register
def on_key_down_left(self):
self.x = self.x - 20

world.run()

Wenn du nach rechts läufst und die Taste mehrfach drückst, bleibt der Spieler
ungefähr in der Mitte des Bildes. Die Welt bewegt sich scheinbar unter ihm
weiter.

### Wo ist etwas auf dem Bildschirm?

Manchmal brauchst du die Bildschirmposition eines Weltpunktes. Das geht mit
`world.camera.get_screen_position(...)`.

import miniworlds

world = miniworlds.World(500, 300)
world.camera.world_size_x = 1200

spieler = miniworlds.Actor((500, 150))

world.camera.from_actor(spieler)

anzeige = miniworlds.Text((400, 100), "")
anzeige.font_size = 20

bildschirm_position = world.camera.get_screen_position(spieler.position)
anzeige.text = f"Spieler auf dem Bildschirm: {bildschirm_position}"

world.run()

Die Weltposition des Spielers ist hier etwa `(500, 150)`. Auf dem Bildschirm
steht er aber viel weiter links, weil die Kamera mit verschoben wurde.

### Mausposition in Weltposition umrechnen

Auch die andere Richtung ist nützlich: Aus einer Bildschirmposition wird eine
Position in der Welt. Dafür nutzt du
`world.camera.get_global_coordinates_for_world(...)`.

import miniworlds

world = miniworlds.World(500, 300)
world.camera.world_size_x = 1200

marke = miniworlds.Circle((x, 150), 20)

mauspunkt = miniworlds.Circle((0, 0), 8)

@world.register
def act(self):
lokale_position = world.mouse.get_position()
welt_position = world.camera.get_global_coordinates_for_world(lokale_position)
mauspunkt.position = welt_position

@world.register
def on_key_down_right(self):
world.camera.x = world.camera.x + 50

@world.register
def on_key_down_left(self):
world.camera.x = world.camera.x - 50

world.run()

Bewege die Kamera mit den Pfeiltasten und halte die Maus an derselben Stelle
im Fenster. Der rote Punkt landet trotzdem an einer anderen Weltposition.