Level laden#

Ein häufiger Anwendungsfall: Du möchtest ein neues Level laden, wenn eine Spielfigur den Rand des Bildschirms erreicht oder durch eine Tür geht usw.

Das kannst du folgendermaßen umsetzen:

  • Speichere dein Level in einer Datenbank, einer Textdatei oder einer einfachen Liste.

  • Du brauchst eine Funktion, die das Level lädt, sobald etwas passiert (du erreichst den Rand, berührst einen Actor, …).

Speichern des Levels als Liste#

Du kannst dein Level in einer zweidimensionalen Liste speichern. Ein ganz einfacher Fall könnte so aussehen:

r00 = [    "  d",
           "  w",
           "www"]

w steht dabei für Wall, d für Door.

Du kannst deine Räume zum Beispiel in einer Liste oder einem Dictionary speichern:

rooms = [r00, r01]

…oder so:

rooms = {0: r00, 1: r01}

Klassen für einzelne Objekte erstellen#

Um Objekte einer bestimmten Art zu erzeugen, ist es sinnvoll, eine Klasse zu definieren:

class Wall(Actor):
    def on_setup(self):
        self.add_costume("wall")

Übersetzen der Liste#

Du kannst die Liste jetzt in Actors übersetzen:

def setup_room(room):
    for actor in world.actors:
        if actor != player:
            actor.remove()
    for i, row in enumerate(room):
        for j, column in enumerate(row):
            x = j
            y = i
            if room[i][j] == "w":
                t = Wall(x, y)
            if room[i][j] == "d":
                d = Door(x, y) 

Raumwechsel#

Mit dieser Vorarbeit ist ein Raumwechsel ganz einfach — du musst einfach nur setup_room im richtigen Moment aufrufen:

def on_key_down(self, keys):
    global r01
    if "SPACE" in keys:
        if self.detect_actor(Wall):
            setup_room(rooms[1]) 

Vollständiges Beispiel:

from miniworlds import *

world = TiledWorld()
world.columns = 3
world.rows = 3

r00 = [    "  d",
           "  w",
           "www"]

r01 =     ["w  ",
           "w  ",
           "w  ",
           ]

rooms = {0: r00, 1: r01}

class Player(Actor):
    
    def on_setup(self):
        self.add_costume("knight")
        self.costume.is_rotatable = False
        self.layer = 1
        
    def on_key_down_w(self):
        self.move_up()

    def on_key_down_s(self):
        self.move_down()

    def on_key_down_a(self):
        self.move_left()
    
    def on_key_down_d(self):
        self.move_right()
        
    def on_detecting_not_on_world(self):
        self.move_back()

    def on_detecting_wall(self, other):
        self.move_back()
        
    def on_key_down(self, keys):
        global r01
        if "SPACE" in keys:
            if self.detect_actor(Wall):
                setup_room(rooms[1])

class Wall(Actor):
    def on_setup(self):
        self.add_costume("wall")

class Door(Actor):
    def on_setup(self):
        self.add_costume("door_closed")


@world.register
def on_setup(self):
    setup_room(r00)
    
def setup_room(room):
    for actor in world.actors:
        if actor != player:
            actor.remove()
    for i, row in enumerate(room):
        for j, column in enumerate(row):
            x = j
            y = i
            if room[i][j] == "w":
                t = Wall(x, y)
            if room[i][j] == "d":
                d = Door(x, y)                
                
player = Player(0, 0)
world.run()

Wenn der Spieler auf der Tür steht und die Leertaste drückt, wird der Raum gewechselt.