Racing with Pygame Zero and Phidgets

Pygame Zero allows you to create simple games in Python. In this project, you will create a racing game that uses a Phidget Accelerometer and the Getting Started Kit!

Prerequisites

You should review the following before moving on:

Setup

Replace the Humidity Phidget in your Getting Started kit with the Accelerometer Phidget (or any Phidget with an Accelerometer).

Getting Started Kit

Accelerometer Phidget

Assembly

Place your Accelerometer Phidget (or any Phidget with an Accelerometer) in the location shown below.

Install Pygame Zero

In order to use Pygame Zero, you first have to install it. You do this in the same way you previously installed the Phidget22 library. Simply navigate to your package manager, search for pgzero and press install!

Thonny

If you're using Thonny, select Tools > Manage Packages and search for pgzero.

PyCharm

If you're using PyCharm, select File > Settings > Python Interpreter and use the + symbol to install pgzero.

PyScripter

If you're using PyScripter, select Tools > Tools > Install Packages with pip and enter pgzero.

Create Project Structure

Create a python script called racing.py in a location of your choice.

Download the required images and place them in a folder called images in the same location as your python file.

Write code (Python)

Copy the code below into your python script racing.py.

  
#Add Phidgets Library
from Phidget22.Phidget import *
from Phidget22.Devices.Accelerometer import *
from Phidget22.Devices.DigitalInput import *
from datetime import datetime
from sys import exit

import pgzrun

#Set Game Board Dimensions
WIDTH = 700
HEIGHT = 700

car = Actor('car', center=(WIDTH / 2, HEIGHT / 2))
background_1 = Actor('road')
background_1.right = WIDTH
background_2 = Actor('road')
background_2.right = -1400
game_speed = 1 #Speed at which everything moves

def increase_game_speed():
    global game_speed
    game_speed += 1

clock.schedule_interval(increase_game_speed, 10)

def draw():
    screen.clear()
    background_1.draw()
    background_2.draw()
    car.draw()
    #Draw helpful text
    screen.draw.text("TIME: " + str(int(timer)), (20, 20), fontsize=40, owidth=1)
    screen.draw.text("LEVEL " + str(game_speed), topright=(680, 20), fontsize=40, owidth=1)

initial_time = datetime.now().timestamp()

def update():
    global timer
    timer = datetime.now().timestamp() - initial_time

    background_1.right += game_speed
    background_2.right += game_speed
    car.x += game_speed

    #Reset background to original position once it leaves the area
    if background_1.right >= WIDTH * 4: background_1.right = -1400
    if background_2.right >= WIDTH * 4: background_2.right = -1400

    #Turn the car
    animate(car, duration=0.1, angle=(accelerometer.getAcceleration()[0] * 90))
    #Move the car
    if accel: animate(car, duration=0.1, pos=(car.x - (20 + level * 2 - abs(car.angle / 5)), car.y + (car.angle / 4)))
    if reverse: animate(car, duration=0.1, pos=(car.x + (20 - abs(car.angle / 5)), car.y - (car.angle / 4)))
    #End the game
    if car.x > WIDTH or car.x < 0: exit()
    if car.y > HEIGHT or car.y < 0: exit()

#Phidgets Code Start    
def mapAcceleration(val):
    try:
        #for simple tilting, -1 to 1 is an appropriate range
        minA = -1 
        maxA = 1
        output = ((val - minA)/(maxA - minA) * WIDTH)
        return output
    except:
        print("error")
        #if sensor is out of range, return last position
        return car.pos[1] 

def accelerateHook(self, state):
    global accel
    if state: accel = True
    else: accel = False

def reverseHook(self, state):
    global reverse
    if state: reverse = True
    else: reverse = False

#Create
accelerometer = Accelerometer()
redButton = DigitalInput()
greenButton = DigitalInput()

#Address
redButton.setIsHubPortDevice(True)
redButton.setHubPort(1)
greenButton.setIsHubPortDevice(True)
greenButton.setHubPort(4)

#Subscribe to Events
greenButton.setOnStateChangeHandler(accelerateHook)
redButton.setOnStateChangeHandler(reverseHook)

#Open
accelerometer.openWaitForAttachment(1000)
redButton.openWaitForAttachment(1000)
greenButton.openWaitForAttachment(1000)

#Set Data Interval to minimum | This will increase the data rate and allow for a more responsive controller
accelerometer.setDataInterval(accelerometer.getMinDataInterval())
#Phidgets Code End

pgzrun.go()
  

Run Your Program

Tilt your Getting Started Kit to steer, and press the buttons for acceleration and braking.

Code Review

Two backgrounds are used in order to create the scrolling effect. Every time a background goes off-screen, it jumps back to the left to be reused.

Practice

  1. Try to add sound effects to the game like when the car accelerates.
  2. Add a second car so you can play against someone else. Note: A second Getting Started Kit and Accelerometer Phidget will be required.

What are Phidgets?

Phidgets are programmable USB sensors. Simply plug in your sensor, write code in your favorite language and go!

Phidgets have been used by STEM professionals for over 20 years and are now available to students.

Learn more

Set your preferences

Windows

Mac OS

Raspberry Pi

Java

Python

C#

Swift

NetBeans

Processing

Eclipse

Thonny

PyCharm

PyScripter

Visual Studio

Xcode

Setting your preferred operating system, programming language and environment lets us display relevant code samples for the Getting Started Tutorial, Device Tutorials and Projects

Done