Prerequisites
You should review the following before moving on:
Setup
All you need for this project is the Getting Started Kit.
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!
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 space_invaders.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 spaceinvaders.py.
#Add Phidgets Library
from Phidget22.Phidget import *
from Phidget22.Devices.VoltageRatioInput import *
from Phidget22.Devices.DigitalInput import *
import pgzrun
from random import randint
import math
DIFFICULTY = 1
player = Actor("player", (400, 550)) # Load in the player Actor image
def draw(): # Pygame Zero draw function
screen.blit('background', (0, 0))
player.image = player.images[math.floor(player.status/6)]
player.draw()
drawLasers()
drawAliens()
drawBases()
screen.draw.text(str(score) , topright=(780, 10), owidth=0.5, ocolor=(255,255,255), color=(0,64,255) , fontsize=60)
if player.status >= 30:
screen.draw.text("GAME OVER\nPress Enter to play again" , center=(400, 300), owidth=0.5, ocolor=(255,255,255), color=(255,64,0) , fontsize=60)
if len(aliens) == 0 :
screen.draw.text("YOU WON!\nPress Enter to play again" , center=(400, 300), owidth=0.5, ocolor=(255,255,255), color=(255,64,0) , fontsize=60)
def update(): # Pygame Zero update function
global moveCounter,player
if player.status < 30 and len(aliens) > 0:
checkThumbstick() #Check Phidgets Thumbstick
updateLasers()
moveCounter += 1
if moveCounter == moveDelay:
moveCounter = 0
updateAliens()
if player.status > 0: player.status += 1
else:
if keyboard.RETURN: init()
def drawAliens():
for a in range(len(aliens)): aliens[a].draw()
def drawBases():
for b in range(len(bases)): bases[b].drawClipped()
def drawLasers():
for l in range(len(lasers)): lasers[l].draw()
#Phidgets Code Start
def checkThumbstick():
global player
if (horizontal.getVoltageRatio() < -0.2):
if (player.x > 40):
player.x-=5
if (horizontal.getVoltageRatio() > 0.2):
if (player.x < 760):
player.x+=5
#Phidgets Code End
def makeLaserActive():
global player
player.laserActive = 1
def checkBases():
for b in range(len(bases)):
if l < len(bases):
if bases[b].height < 5:
del bases[b]
def updateLasers():
global lasers, aliens
for l in range(len(lasers)):
if lasers[l].type == 0:
lasers[l].y += (2*DIFFICULTY)
checkLaserHit(l)
if lasers[l].y > 600: lasers[l].status = 1
if lasers[l].type == 1:
lasers[l].y -= 5
checkPlayerLaserHit(l)
if lasers[l].y < 10: lasers[l].status = 1
lasers = listCleanup(lasers)
aliens = listCleanup(aliens)
def listCleanup(l):
newList = []
for i in range(len(l)):
if l[i].status == 0: newList.append(l[i])
return newList
def checkLaserHit(l):
global player
if player.collidepoint((lasers[l].x, lasers[l].y)):
player.status = 1
lasers[l].status = 1
for b in range(len(bases)):
if bases[b].collideLaser(lasers[l]):
bases[b].height -= 10
lasers[l].status = 1
def checkPlayerLaserHit(l):
global score
for b in range(len(bases)):
if bases[b].collideLaser(lasers[l]): lasers[l].status = 1
for a in range(len(aliens)):
if aliens[a].collidepoint((lasers[l].x, lasers[l].y)):
lasers[l].status = 1
aliens[a].status = 1
score += 1000
def updateAliens():
global moveSequence, lasers, moveDelay
movex = movey = 0
if moveSequence < 10 or moveSequence > 30: movex = -15
if moveSequence == 10 or moveSequence == 30:
movey = 50 + (10 * DIFFICULTY)
moveDelay -= 1
if moveSequence >10 and moveSequence < 30: movex = 15
for a in range(len(aliens)):
animate(aliens[a], pos=(aliens[a].x + movex, aliens[a].y + movey), duration=0.5, tween='linear')
if randint(0, 1) == 0:
aliens[a].image = "alien1"
else:
aliens[a].image = "alien1b"
if randint(0, 5) == 0:
lasers.append(Actor("laser1", (aliens[a].x,aliens[a].y)))
lasers[len(lasers)-1].status = 0
lasers[len(lasers)-1].type = 0
if aliens[a].y > player.y and player.status == 0:
player.status = 1
moveSequence +=1
if moveSequence == 40: moveSequence = 0
def init():
global lasers, score, player, moveSequence, moveCounter, moveDelay
initAliens()
initBases()
moveCounter = moveSequence = player.status = score = player.laserCountdown = 0
lasers = []
moveDelay = 30
player.images = ["player","explosion1","explosion2","explosion3","explosion4","explosion5"]
player.laserActive = 1
def initAliens():
global aliens
aliens = []
for a in range(18):
aliens.append(Actor("alien1", (210+(a % 6)*80,100+(int(a/6)*64))))
aliens[a].status = 0
def drawClipped(self):
screen.surface.blit(self._surf, (self.x-32, self.y-self.height+30),(0,0,64,self.height))
def collideLaser(self, other):
return (
self.x-20 < other.x+5 and
self.y-self.height+30 < other.y and
self.x+32 > other.x+5 and
self.y-self.height+30 + self.height > other.y
)
def initBases():
global bases
bases = []
bc = 0
for b in range(3):
for p in range(3):
bases.append(Actor("base1", midbottom=(150+(b*200)+(p*40),520)))
bases[bc].drawClipped = drawClipped.__get__(bases[bc])
bases[bc].collideLaser = collideLaser.__get__(bases[bc])
bases[bc].height = 60
bc +=1
#Phidgets Code Start
#Event
def onRedButton_StateChange(self, state):
global player, lasers
if (state):
if (player.laserActive == 1):
player.laserActive = 0
clock.schedule(makeLaserActive, 1.0)
l = len(lasers)
lasers.append(Actor("laser2", (player.x,player.y-32)))
lasers[l].status = 0
lasers[l].type = 1
#Create
redButton = DigitalInput()
horizontal = VoltageRatioInput()
#Address
redButton.setHubPort(0)
redButton.setIsHubPortDevice(True)
horizontal.setChannel(1)
#Subscribe to Events
redButton.setOnStateChangeHandler(onRedButton_StateChange)
#Open
redButton.openWaitForAttachment(1000)
horizontal.openWaitForAttachment(1000)
#Set data interval to minimum
horizontal.setDataInterval(horizontal.getMinDataInterval())
#Phidgets Code End
init()
pgzrun.go()
Code Review
In this example, the Thumbstick Phidget is being used instead of the left and right keys, and the red button is used instead of the spacebar. You can view the original code here to compare
Practice
- Add new functionality to your game using the green button. Some examples may be pausing the game, ending the game, speeding the game up, slowing the game down, etc.