Sensors#
Actors have sensors that allow them to scan their environment — for example, to detect other actors at their position.
There are two ways to use sensors:
You can actively detect other objects.
You can register events that are triggered by sensor detection.
Actively Detecting Objects#
You can actively detect objects by using an actor’s sensors directly. Here’s an example of how it works:
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() # Sensor detects objects at current position
if actor:
self.color = (255, 0, 0) # Change color if an object is detected
world.run()
Output#
Explanation#
In the rectangle’s
act()
method, the sensorself.detect()
checks if there’s another actor at the same position.If another actor is detected, the rectangle changes color.
The variable
actor
contains the detected object, orNone
if nothing is found.The line
if actor
is shorthand forif actor != None
.
Registering Detection Events#
In the example above, actors actively checked for collisions. Alternatively, you can register a method that is automatically triggered when a sensor detects something:
from miniworlds import World, Rectangle, Circle
world = World(200, 100)
r = Rectangle((10, 10), 50, 100)
c = Circle((200, 50), 20)
@c.register
def act(self):
self.move_left()
@r.register
def on_detecting(self, other):
self.color = (255, 0, 0) # Change color when another object is detected
world.run()
Explanation:#
The method
on_detecting(self, other)
is called automatically when an object is detected.The
other
parameter refers to the detected object, allowing you to identify what was found.
Detecting Specific Objects#
Using sensors along with if-else statements, you can distinguish which object was detected:
import miniworlds
world = miniworlds.World(200, 100)
r = miniworlds.Rectangle((10, 10), 50, 100)
c1 = miniworlds.Circle((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) # Turn red when detecting c1
elif other == c2:
self.color = (0, 255, 0) # Turn green when detecting c2
world.run()
Output#
Explanation#
In the on_detecting
method, the actor checks whether it has detected c1
or c2
and changes color accordingly.
Note
Note: Global Variables — Normally, variables are only accessible within a method.
Accessing global variables (as in this example) is simple but can cause unwanted side effects.
You’ll learn how to avoid this in the classes_first tutorial.
Example: Prevent Actors from Passing Through Walls#
Sensors can also be used to prevent actors from walking through walls. Here’s an example:
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() # Move back when wall is detected
world.run()
FAQ#
My collision detection doesn’t work — what can I do?
First, test whether your method is even being called. Add a print
statement like this:
@player.register
def on_detecting(self, actor):
print(actor)
If nothing prints, the sensor is not working as expected.