Sensoren#

Actors verfügen über Sensoren, mit denen sie ihre Umwelt abtasten können und z.B andere Actors an ihrer Position aufspüren können.

Ein Objekt aufspüren.#

Du kannst Objekte aufspüren, indem du die entsprechenden Sensoren direkt aufrufst. Dies geht z.B. so:

import miniworlds 

world = miniworlds.World(200, 100)

r = miniworlds.Rectangle((10,10),50,100)
c = miniworlds.Circle((200,50),20)

@c.register
def act(self):
    self.move_left()

@r.register
def act(self):
    actor = self.detect()
    if actor:
        self.color = (255,0,0)

world.run()

Die zweite act()-Methode enthält den Sensor. Mit der Methode self.detect wird abgefragt, welche Actors an der aktuellen Stelle gefunden wurde. Falls kein Actor gefunden wird, gibt die Methode None zurück.

Note

Die Anweisung if actor ist äquivalent zu if actor != None.

Wenn das Rechteck mit seinen Sensoren ein anderes Actor aufspürt, dann ändert sich die Farbe.

Ereignisse#

In dem Beispiel oben wurde aktiv nach Actors gesucht. Alternativ dazu kannst du auch ein Ereignis registrieren, dass automatisch dann aufgerufen wird, wenn der Sensor des Actors etwas aufspürt:

Das letzte Programm kann mit Hilfe von Ereignissen so programmiert werden:

from miniworlds import *

world = miniworlds.World(200, 100)

r = miniworlds.Rectangle((10,10),50,100)
c = miniworlds.Circle((200,50),20)

@c.register
def act(self):
    self.move_left()
 
@r.register
def on_detecting(self, other):
    self.color = (255,0,0)

world.run()

Was passiert hier?

  • Die registrierte Funktion on_detecting wird dann aufgerufen, wenn das Actor ein anderes Objekt am selben Ort aufspürt.

  • Der Parameter other ist ein Verweis auf das gefundene Objekt. Du kannst diesen benutzen um herauszufinden, welches andere Actor gefunden wurde.

Was wurde gefunden?#

Mit Hilfe von Sensoren und if-else Verzweigungen kannst du herausfinden, was genau gefunden wurde. Dies geht z.B. so:

import miniworlds 

world = World(200, 100)

r = Rectangle((10,10),50,100)

c1 = miniworlds.ircle((200,50),20)
c2 = miniworlds.Circle((120,50),20)

@c1.register
def act(self):
    self.move_left()

@c2.register
def act(self):
    self.move_left()
    
@r.register
def on_detecting(self, other):
    if other == c1:
        self.color = (255,0,0)
    if other == c2:
        self.color = (0, 255,0)

world.run()

In der on_detect_actor-Methode wird überprüft, ob other das gleiche Objekt ist wie c1 bzw. c2.

Wenn dies zutrifft, wird das Rechteck entsprechend eingefärbt.

Note

Exkurs: Globale Variablen: Normalerweise sind Variablen nur innerhalb einer Methode bekannt, damit z.B. verhindert wird, dass es zu Seiteneffekten kommt, wenn man an verschiedenen Stellen auf die gleiche Variable zugreift.

Der Ansatz mit dem hier auf Variablen aus anderen Programmteilen zugegriffen wird ist zwar einfach und intuitiv - Im Tutorial classes_first wirst du lernen, wie man dies vermeiden kann.

Wände#

Der folgende Code zeigt, wie du verhindern kannst, dass sich Objekte durch Wände hindurch bewegen können. Auch dies lässt sich mit Hilfe von Sensoren ermöglichen:

import miniworlds 

world = miniworlds.TiledWorld()
world.columns = 8
world.rows = 2
world.speed = 30
player = miniworlds.Actor()
player.add_costume("images/player_1.png")

wall = miniworlds.Actor((4,0))
wall.add_costume("images/wall.png")

@player.register
def act(self):
    if player.position != (0,4):
        player.direction = "right"
        player.move()

@player.register
def on_detecting(self, other):
    if other==wall:
        self.move_back()
    

world.run()

Weitere Sensoren#

Grenzen des Spielfelds überprüfen#

Du kannst auch überprüfen, ob eine Spielfigur an den Grenzen des Spielfelds ist (oder darüber hinaus):

Ist die Figur nicht auf dem Spielfeld?

@player3.register
def on_not_detecting_world(self):
  print("Warning: I'm not on the world!!!")

Beispiel:

Das folgende Programm simuliert einen umherschwimmenden Fisch:

import miniworlds 

world = TiledWorld()
world.columns = 4
world.rows = 1
world.add_background("images/water.png")
fish = miniworlds.Actor((0,0))
fish.add_costume("images/fish.png")
fish.costume.orientation = - 90
fish.direction = "right"
@fish.register
def act(self):
    self.move()

@fish.register
def on_not_detecting_world(self):
    self.move_back()
    self.flip_x()
        
world.run()

Ist die Figur an den Grenzen des Spielfelds?

@player4.register
def on_detecting_borders(self, borders):
  print("Borders are here!", str(borders))

Befindet sich eine Spielfigur an der Position (0,0) wird folgendes ausgegeben: Borders are here! ['right', 'top']

FAQ#

  • Meine Kollisionen werden nicht erkannt, was kann ich tun?

    Teste zunächst, ob die Methode überhaupt aufgerufen wird, z.B. mit:

    @player.register
    def on_detecting(self, actor):
      print(actor)
      ...
    

    Wenn die print-Anweisung nicht aufgerufen wird, dann funktioniert der Sensor nicht.