Simple Game on Circuit Playground Express
Introduction
Circuit Playground Express packs a lot of interesting sensors and a beautiful array of NeoPixels. I just bought one to play around and was writing a simple code to test out the CircuitPython and onboard sensors.
So I wrote a very basic game that interacts with onboard speakers, capacitive touch pads, buttons and NeoPixels.
The Game
Game is called Catch Neo
and the initial setup is like this.
The Red pixel on the top is Neo
and it moves around as it wishes. Every turn it decides whether it wants to move and if it does it either one step left or right.
Game starts when the player presses the button b
on the board, at that time the start tune is played and pieces start moving.
The player controls the Green array at the bottom using capacitive touch pad A1
and A3
. If the player touches A1
then the green array moves left. If the player touches A3
it moves right. Players can choose to not move at all.
Game halts if Neo
lands on one of the player lit positions, at that moment the game state freezes and the score is printed on serial console.
The player wins if they manage to catch Neo
on pixel position 7
which is opposite to red pixel’s original position.
The player loses if Neo
lands on any green lit pixel which is not 7
.
Press button a
on the board to restart the game.
At any time during the play, the player can press button b
and pause/unpause the game.
The Code
Entire code is a single file code.py
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
from adafruit_circuitplayground import cp
import random
cp.pixels.brightness = 0.1
cp.pixels.fill((0, 0, 0))
def win_tune():
cp.play_tone(280, 0.1)
cp.play_tone(180, 0.1)
cp.play_tone(280, 0.1)
cp.play_tone(180, 0.1)
cp.play_tone(280, 0.1)
cp.play_tone(180, 0.1)
cp.play_tone(280, 0.1)
cp.play_tone(180, 0.1)
cp.play_tone(280, 0.1)
def reset_tune():
cp.play_tone(180, 1)
def start_tune():
cp.play_tone(294, 1)
def lose_tune():
cp.play_tone(280, 0.5)
cp.play_tone(180, 0.5)
cp.play_tone(280, 0.5)
def move_tune():
cp.play_tone(100, 0.1)
class PlayState:
def __init__(self):
self.running = False
self.player_pixels = [5,6,7,8,9]
self.enemy_pixels = 2
self.score = 0
def reset_state(self):
self.running = False
self.player_pixels = [5,6,7,8,9]
self.enemy_pixels = 2
self.score = 0
def light_board(self):
cp.pixels.fill((0, 0, 0))
for pp in self.player_pixels:
cp.pixels[pp] = (0, 255, 0)
cp.pixels[self.enemy_pixels] = (255, 0, 0)
def toggle_running(self):
self.running = not self.running
def is_running(self):
return self.running
def is_game_over(self):
print("Score : {0}".format(self.score))
return self.enemy_pixels in self.player_pixels
def is_winner(self):
return self.is_game_over() and self.enemy_pixels == 7
def move_left(self):
self.player_pixels.pop(-1)
val = (self.player_pixels[0] -1)%10
self.player_pixels.insert(0, val)
self.score += 1
def move_right(self):
self.player_pixels.pop(0)
val = (self.player_pixels[-1] +1)%10
self.player_pixels.append(val)
self.score += 1
def move_enemy(self):
self.enemy_pixels = (self.enemy_pixels + random.randint(-1, 1)) % 10
ps = PlayState()
ps.light_board()
while True:
time.sleep(1.0)
if cp.button_a:
reset_tune()
ps.reset_state()
ps.light_board()
continue
if cp.button_b:
start_tune()
ps.toggle_running()
continue
if not ps.is_running():
continue
ps.move_enemy()
if cp.touch_A1:
ps.move_left()
if cp.touch_A3:
ps.move_right()
ps.light_board()
if ps.is_game_over():
if ps.is_winner():
win_tune()
else:
lose_tune()
ps.toggle_running()
else:
move_tune()