Title: miniworlds: Tiled Worlds und einfache RPGs

# Tiled Worlds und einfache RPGs

Eine normale `World` arbeitet mit Pixeln: Ein Actor kann zum Beispiel bei
`(137, 82)` stehen. Eine `TiledWorld` arbeitet dagegen mit Feldern. Die Position
`(3, 2)` bedeutet: vierte Spalte, dritte Zeile.

Das passt sehr gut zu RPGs, Brettspielen und Labyrinthen.

import miniworlds

world = miniworlds.TiledWorld(10, 7)

spieler = miniworlds.Actor((1, 1))

ziel = miniworlds.Actor((8, 5))

world.run()

Der Spieler steht auf Feld `(1, 1)`, das Ziel auf Feld `(8, 5)`. Du denkst also
nicht mehr in Pixeln, sondern in Spielfeld-Koordinaten.

### Feldweise bewegen

In einer `TiledWorld` bewegt sich ein Actor standardmäßig feldweise. Mit
`direction` legst du die Richtung fest:

* `0` bedeutet nach rechts
* `90` bedeutet nach unten
* `180` bedeutet nach links
* `270` bedeutet nach oben

import miniworlds

world = miniworlds.TiledWorld(10, 7)

spieler = miniworlds.Actor((1, 1))

@spieler.register
def on_key_down_w(self):
self.y = self.y + 1

@spieler.register
def on_key_down_s(self):
self.y = self.y - 1

@spieler.register
def on_key_down_a(self):
self.x = self.x - 1

@spieler.register
def on_key_down_d(self):
self.x = self.x + 1

world.run()

### Wände ergänzen

Für ein RPG braucht man Hindernisse. Ein Actor kann eine Wand sein, wenn
`is_blocking = True` gesetzt wird. Der Spieler muss zusätzlich
`is_blockable = True` bekommen. Dann kann er nicht durch blockierende Actors
hindurchlaufen.

import miniworlds

world = miniworlds.TiledWorld(10, 7)

spieler = miniworlds.Actor((1, 1))
spieler.is_blockable = True

wand = miniworlds.Actor(position)
wand.is_blocking = True

@spieler.register
def on_key_down_w(self):
self.y = self.y + 1

@spieler.register
def on_key_down_s(self):
self.y = self.y - 1

@spieler.register
def on_key_down_a(self):
self.x = self.x - 1

@spieler.register
def on_key_down_d(self):
self.x = self.x + 1

world.run()

### Ein Ziel und eine Nachricht

Jetzt wird daraus ein kleines RPG: Der Spieler läuft durch die Welt, sammelt
einen Schatz ein und bekommt eine Nachricht.

import miniworlds

world = miniworlds.TiledWorld(10, 7)

spieler = miniworlds.Actor((1, 1))
spieler.is_blockable = True
spieler.hat_gewonnen = False

schatz = miniworlds.Actor((8, 5))

wand = miniworlds.Actor(position)
wand.is_blocking = True

@spieler.register
def act(self):
if self.detect(schatz) and not self.hat_gewonnen:
print("Geschafft! Du hast den Schatz gefunden.")
self.hat_gewonnen = True

@spieler.register
def on_key_down_w(self):
self.y = self.y + 1

@spieler.register
def on_key_down_s(self):
self.y = self.y - 1

@spieler.register
def on_key_down_a(self):
self.x = self.x - 1

@spieler.register
def on_key_down_d(self):
self.x = self.x + 1

world.run()

!!! note Warum TiledWorld?
Für RPGs ist eine TiledWorld angenehm, weil deine Spiellogik einfach wird:
`(1, 1)` ist ein Feld, `(3, 2)` ist eine Wand, `(8, 5)` ist ein Schatz. Dadurch
kannst du Level später sehr gut mit Listen oder Strings beschreiben.