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.