In this tutorial, we are going to explain how the ‘Bot’ game code works from the previous tutorial, and how to modify it. This allows you to for example add some servos, sensors, more players or additional game logic to it.
Start by running git pull
to get the latest updates. Then follow the first tutorial steps.
Next, navigate to games/bot/game.py
and you should see a code like this:
import logging
from gpiozero import Robot
from surrortg import Game
from surrortg.inputs import Directions, Joystick
class Bot(Joystick):
def __init__(self):
# Create new bot with the correct pins
self.robot = Robot(left=(17, 27), right=(18, 22))
async def handle_coordinates(self, x, y, seat=0):
# Parse direction out of coordinates
direction = self.get_direction_8(x, y)
# log the input
logging.info(f"Direction: {direction}")
# Drive the bot to the direction
if direction == Directions.TOP:
self.robot.forward()
elif direction == Directions.BOTTOM:
self.robot.backward()
elif direction == Directions.RIGHT:
self.robot.right()
elif direction == Directions.LEFT:
self.robot.left()
elif direction == Directions.MIDDLE:
self.robot.stop()
elif direction == Directions.TOP_RIGHT:
self.robot.forward(curve_right=1)
elif direction == Directions.TOP_LEFT:
self.robot.forward(curve_left=1)
elif direction == Directions.BOTTOM_RIGHT:
self.robot.backward(curve_right=1)
elif direction == Directions.BOTTOM_LEFT:
self.robot.backward(curve_left=1)
async def reset(self, seat=0):
# Stop between games
self.robot.stop()
class BotGame(Game):
async def on_init(self):
# Create a new bot and initialize it as input.
# The Bot class behaves as a Joystick.
self.io.register_inputs({"joystick_main": Bot()})
if __name__ == "__main__":
BotGame().run()
This is the game code running right now. You can verify this by running surroctl path
and it should return this file location.
If you want to change the game, but not to modify the original one, you can create a new folder to the games folder, such as mybot
and copy the game.py
file there. Then run surroctl path games/mybot/game.py
to start using the new file.
The line from
gpiozero
import
Robot
imports the Robot class from gpiozero library. If you encounter errors when running the game, you might need to run sudo apt install python3-gpiozero
if the gpiozero package was not installed previously.
Here self.robot = Robot(left=(17, 27), right=(18, 22))
we can see that the Robot expects two pins for each wheel. For more in-depth explanation for the L293D can be found here.Then to package that into a Joystick input:
class Bot(Joystick):
def __init__(self):
# Create new bot with the correct pins
self.robot = Robot(left=(17, 27), right=(18, 22))
Now you should process the x- and y-coordinate input. This can be done with the help of get_direction_8 method. And here all of the 8 directions + middle are handled with a simple if/else structure:
async def handle_coordinates(self, x, y, seat=0):
# Parse direction out of coordinates
direction = self.get_direction_8(x, y)
# log the input
logging.info(f"Direction: {direction}")
# Drive the bot to the direction
if direction == Directions.TOP:
self.robot.forward()
elif direction == Directions.BOTTOM:
self.robot.backward()
elif direction == Directions.RIGHT:
self.robot.right()
elif direction == Directions.LEFT:
self.robot.left()
elif direction == Directions.MIDDLE:
self.robot.stop()
elif direction == Directions.TOP_RIGHT:
self.robot.forward(curve_right=1)
elif direction == Directions.TOP_LEFT:
self.robot.forward(curve_left=1)
elif direction == Directions.BOTTOM_RIGHT:
self.robot.backward(curve_right=1)
elif direction == Directions.BOTTOM_LEFT:
self.robot.backward(curve_left=1)
(Slightly more compact way of handling different directions would be to use a dictionary, but this structure allows easier modifications)Then this Bot-Joystick can be registered as a game input, with a name main_joystick
, which is the default one with new games:
class BotGame(Game):
async def on_init(self):
# Create a new bot and initialize it as input.
# The Bot class behaves as a Joystick.
self.io.register_inputs({"joystick_main": Bot()})
And the BotGame is then started by calling run()
:
if __name__ == "__main__":
BotGame().run()
Here if __name__ == "__main__":
makes sure that the game is run only if the file explicitly run, more info here.
That’s it! Now you can start adding more complex movement by modifying the if/else structure inside the handle_coordinates
. Or add new game logic by extending on_start
or on_prepare
methods. We would love to see where your game development journey leads you to! We and our community can help you if you encounter problems on our discord.
Comments
Please log in or sign up to comment.