Aula Jazmati
Published © MIT

DIY Games with Raspberry Pi Pico 🙂🕹️

Welcome to this project where we will be creating an exciting games using MicroPython and Raspberry Pi Pico.

IntermediateFull instructions provided1 hour556
DIY Games with Raspberry Pi Pico 🙂🕹️

Things used in this project

Hardware components

PCBWay Raspberry Pi Pico
×1
PCBWay Raspberry Pi Pico Case
×1
PCBWay Jumper Wires
×1
PCBWay Breakout Module Shield PS2 Joystick Game Controller
×1
LED Dot Matrix Display, Red
LED Dot Matrix Display, Red
×1
Raspberry Pi Pico USB Cable
Raspberry Pi Pico USB Cable
×1
MAX7219/MAX7221 LED Display Drivers
Maxim Integrated MAX7219/MAX7221 LED Display Drivers
×1
PCBWay Custom PCB
PCBWay Custom PCB
×1

Software apps and online services

MicroPython
MicroPython

Story

Read more

Schematics

Diagram

Code

MicroPython max7219 cascadable 8x8 LED matrix driver

MicroPython
"""
MicroPython max7219 cascadable 8x8 LED matrix driver
https://github.com/mcauser/micropython-max7219

MIT License
Copyright (c) 2017 Mike Causer

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""

from micropython import const
import framebuf

_NOOP = const(0)
_DIGIT0 = const(1)
_DECODEMODE = const(9)
_INTENSITY = const(10)
_SCANLIMIT = const(11)
_SHUTDOWN = const(12)
_DISPLAYTEST = const(15)

class Matrix8x8:
    def __init__(self, spi, cs, num):
        """
        Driver for cascading MAX7219 8x8 LED matrices.

        >>> import max7219
        >>> from machine import Pin, SPI
        >>> spi = SPI(1)
        >>> display = max7219.Matrix8x8(spi, Pin('X5'), 4)
        >>> display.text('1234',0,0,1)
        >>> display.show()

        """
        self.spi = spi
        self.cs = cs
        self.cs.init(cs.OUT, True)
        self.buffer = bytearray(8 * num)
        self.num = num
        fb = framebuf.FrameBuffer(self.buffer, 8 * num, 8, framebuf.MONO_HLSB)
        self.framebuf = fb
        # Provide methods for accessing FrameBuffer graphics primitives. This is a workround
        # because inheritance from a native class is currently unsupported.
        # http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
        self.fill = fb.fill  # (col)
        self.pixel = fb.pixel # (x, y[, c])
        self.hline = fb.hline  # (x, y, w, col)
        self.vline = fb.vline  # (x, y, h, col)
        self.line = fb.line  # (x1, y1, x2, y2, col)
        self.rect = fb.rect  # (x, y, w, h, col)
        self.fill_rect = fb.fill_rect  # (x, y, w, h, col)
        self.text = fb.text  # (string, x, y, col=1)
        self.scroll = fb.scroll  # (dx, dy)
        self.blit = fb.blit  # (fbuf, x, y[, key])
        self.init()

    def _write(self, command, data):
        self.cs(0)
        for m in range(self.num):
            self.spi.write(bytearray([command, data]))
        self.cs(1)

    def init(self):
        for command, data in (
            (_SHUTDOWN, 0),
            (_DISPLAYTEST, 0),
            (_SCANLIMIT, 7),
            (_DECODEMODE, 0),
            (_SHUTDOWN, 1),
        ):
            self._write(command, data)

    def brightness(self, value):
        if not 0 <= value <= 15:
            raise ValueError("Brightness out of range")
        self._write(_INTENSITY, value)

    def show(self):
        for y in range(8):
            self.cs(0)
            for m in range(self.num):
                self.spi.write(bytearray([_DIGIT0 + y, self.buffer[(y * self.num) + m]]))
            self.cs(1)

Snake-Game

MicroPython
from machine import Pin, PWM, ADC , SPI
from utime import sleep
import max7219
import math
import random
spi = SPI(0,sck=Pin(6),mosi=Pin(7))
CS_PIN = machine.Pin(5, machine.Pin.OUT)
xAxis = ADC(Pin(27))
yAxis = ADC(Pin(26))
button = Pin(22,Pin.IN, Pin.PULL_UP)
display= max7219.Matrix8x8(spi, CS_PIN, 1)
display.brightness(10)
screenWidth=8
screenHeight=8
snakeSize=1
isGameOver=False
tailX=[]
tailY=[]
direction=""
snakeX=4
snakeY=4
foodX=6
foodY=6
eat=False
spd=0.2
def setupFoodPosition():
    global foodX,foodY
    foodX, foodY = random.randrange(0, 7), random.randrange(0, 7)
    
def initSnake():
    tailX.append(snakeX)
    tailY.append(snakeY)
  
def showGameOverScreen():
    for row in range(8):
        for col in range(8):
            if(c>1):
                if face_smile[row][col] == 0:
                    display.pixel(col,row,1)
                else:
                    display.pixel(col,row,0)
                    display.show()
            sleep(0.1)
            if(c<3):
                if face_sad[row][col] == 0:
                    display.pixel(col,row,1)
                else:
                    display.pixel(col,row,0)
                    display.show()
            sleep(0.1)
    sleep(5)
    resetVariables()

def showLed(row, column, c):
    display.pixel(row, column, c)
    display.show()

def resetVariables():
    global direction, isGameOver, snakeSize, spd
    setupSnakePosition()
    setupFoodPosition()
    direction=""
    isGameOver=False
    snakeSize=1
    tailX.clear()
    tailY.clear()
    spd=0.2
    display.fill(0)
    display.show()
    initSnake()

def setupSnakePosition():
    global snakeX,snakeY
    snakeX=4
    snakeY=4

def startGame():
    manageGameOver()
    setJoystickDirection()
    changeSnakeDirection()
    manageSnakeOutOfBounds()
    manageEatenFood()
    manageSnakeTailCoordinates()
    drawSnake()
    sleep(spd)

def manageGameOver():
    global isGameOver
    for i in range(1, snakeSize-1):
        if tailX[i] == snakeX and tailY[i] == snakeY:
            isGameOver=True
    
def setJoystickDirection():
    xValue = xAxis.read_u16()
    yValue = yAxis.read_u16()
    global direction
    if xValue <= 900:
        direction="left"
    elif xValue >= 60000:
        direction="right"
    elif yValue <= 600:
        direction="up"
    elif yValue >= 60000:
        direction="down"
    print(direction)

def changeSnakeDirection():
    global snakeX, snakeY
    if direction == "left":
        snakeX=snakeX-1
    if direction == "right":
        snakeX=snakeX+1
    if direction == "up":
        snakeY=snakeY-1
    if direction == "down":
        snakeY=snakeY+1

def manageSnakeOutOfBounds():
    global snakeX, snakeY
    if snakeX >= screenWidth:
        snakeX=0
    elif snakeX < 0:
        snakeX=screenWidth-1
  
    if snakeY >= screenHeight:
        snakeY=0
    elif snakeY < 0:
        snakeY=screenHeight-1
  
def manageEatenFood():
    global snakeSize, eat
    if snakeX == foodX and snakeY == foodY:
        snakeSize=snakeSize+1
        setupFoodPosition()
        SpeedUp()
        eat=True
    else:
        eat=False
  
def manageSnakeTailCoordinates():
    tailX.insert(0,snakeX)
    tailY.insert(0,snakeY)
    tailIndex = len(tailX)-1
    if eat==False:
        tailX.pop(tailIndex)
        tailY.pop(tailIndex)
  
def drawSnake():
    for i in range(screenHeight):
        for j in range(screenWidth):
            if i == foodY and j == foodX:
                showLed(foodX, foodY, 1)
            else:
                isShown=False
                for idx, item in enumerate(tailX):
                    if tailX[idx]==j and tailY[idx]==i:
                        showLed(tailX[idx], tailY[idx], 1)
                        isShown=True
                if isShown==False:
                    showLed(j, i, 0)

def SpeedUp():
    global spd
    spd -= 0.01
    if spd<0: spd=0

# setupLedBoard
display.brightness(1)   # ajustar brillo 1 a 15
display.fill(1)
display.show()
sleep(0.5)
display.fill(0)
display.show()
sleep(0.2)
setupFoodPosition()
initSnake()
c = 0

face_smile = [
    [1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 1, 1, 0, 0, 1],
    [1, 0, 0 ,1 ,1 ,0 ,0 ,1],
    [1 ,0 ,0 ,1 ,1 ,0 ,0 ,1],
    [1 ,1 ,1 ,1 ,1 ,1 ,1 ,1],
    [1 ,0 ,0 ,1 ,1 ,0 ,0 ,1],
    [1,0,0,0,0,0,0 ,1],
    [1 ,1,0,0,0,0,1 ,1]
]
face_sad = [
    [1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 1, 1, 0, 0, 1],
    [1, 0, 0 ,1 ,1 ,0 ,0 ,1],
    [1 ,0 ,0 ,1 ,1 ,0 ,0 ,1],
    [1 ,1 ,1 ,1 ,1 ,1 ,1 ,1],
    [1 ,1 ,1 ,1 ,1 ,1 ,1 ,1],
    [1,0,0,0,0,0,0 ,1],
    [1 ,1,1,1,1,1,1 ,1]
]
face_sad1 = [
    [1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 1, 1, 0, 0, 1],
    [1, 0, 0 ,1 ,1 ,0 ,0 ,1],
    [1 ,0 ,0 ,1 ,1 ,0 ,0 ,1],
    [1 ,1 ,1 ,1 ,1 ,1 ,1 ,1],
    [1 ,1 ,0 ,0 ,0 ,0 ,1 ,1],
    [1,0,1,1,1,1,0 ,1],
    [0 ,1,1,1,1,1,1 ,0]
]
face_cry = [
    [1, 1, 1, 1, 1, 1, 1, 1],
    [1, 0, 0, 1, 1, 0, 0, 1],
    [1, 0, 0 ,1 ,1 ,0 ,0 ,1],
    [1 ,1 ,1 ,1 ,1 ,1 ,1 ,1],
    [1 ,1 ,1 ,1 ,1 ,1 ,0 ,1],
    [1 ,1 ,1 ,1 ,1 ,1 ,0 ,1],
    [1,1,1,0,0,1,1 ,1],
    [1 ,1,0,1,1,0,1 ,1]
]    
while True:
    buttonValue = button.value()
    if (eat):
        c = c+1
        
    if buttonValue == 0:
        display.fill(0)
        display.text(str(c), 1, 0)
        display.show()
    
    if isGameOver == True:
        showGameOverScreen()
        sleep(1)
    else:
        startGame()

PingPong_Game

MicroPython
from machine import Pin, PWM, ADC , SPI
import utime
import max7219
import math
# define LED matrix pins
spi = SPI(0,sck=Pin(6),mosi=Pin(7))
CS_PIN = machine.Pin(5, machine.Pin.OUT)
xAxis = ADC(Pin(27))
yAxis = ADC(Pin(26))
button = Pin(22,Pin.IN, Pin.PULL_UP)
# initialize LED matrix
led_matrix = max7219.Matrix8x8(spi, CS_PIN, 1)
led_matrix.brightness(10)
player1_score = 0
player2_score = 0
ball_x = 3
ball_y = 3
ball_vx = 1
ball_vy = 1
paddle1_y = 2
paddle2_y = 2
def update_game():
    global ball_x, ball_y, ball_vx, ball_vy, player1_score, player2_score, paddle1_y, paddle2_y
    
    
    ball_x += ball_vx
    ball_y += ball_vy
    
    
    if ball_y == 0 or ball_y == 7:
        ball_vy = -ball_vy
        
    
    if ball_x == 0 and paddle1_y <= ball_y <= paddle1_y + 2:
        ball_vx = -ball_vx
        
     
    if ball_x == 7 and paddle2_y <= ball_y <= paddle2_y + 2:
        ball_vx = -ball_vx
        
    
    if ball_x == -1:
        player2_score += 1
        ball_x = 3
        ball_y = 3
        

    if ball_x == 8:
        player1_score += 1
        ball_x = 3
        ball_y = 3
        
    
    if button.value() == 0:
        led_matrix.pixel(ball_x, ball_y, 0)


def draw_game():
    global ball_x, ball_y, player1_score, player2_score, paddle1_y, paddle2_y
    
    
    led_matrix.fill(0)
    
    
    led_matrix.pixel(ball_x, ball_y, 1)
    
    
    for i in range(paddle1_y, paddle1_y + 3):
        led_matrix.pixel(0, i, 1)
        
    
    for i in range(paddle2_y, paddle2_y + 3):
        led_matrix.pixel(7, i, 1)
        
    led_matrix.show()

while True:
    xValue = xAxis.read_u16()
    yValue = yAxis.read_u16()
    paddle1_y = xValue //255
    paddle2_y = yValue //255
    update_game()
    draw_game()

    buttonValue = button.value()
    xStatus = "middle"
    yStatus = "middle"
    buttonStatus = "not pressed"
    if xValue <= 900:
        xStatus = "left"
    elif xValue >= 60000:
        xStatus = "right"
    if yValue <= 600:
        yStatus = "up"
    elif yValue >= 60000:
        yStatus = "down"
    if buttonValue == 0:
        
        print(player1_score)
        print(player2_score)
        if(player1_score > player2_score):
            led_matrix.fill(0)
            led_matrix.text('A', 1, 0)
            led_matrix.show()
        elif(player1_score < player2_score):
            led_matrix.fill(0)
            led_matrix.text('B', 1, 0)
            led_matrix.show()
        elif(player1_score == player2_score):
            led_matrix.fill(0)
            led_matrix.text('=', 1, 0)
            led_matrix.show()
        utime.sleep(1)
        
    print("X: " + xStatus + ", Y: " + yStatus + " -- button " + buttonStatus)
    utime.sleep(0.1)

The codes

Credits

Aula Jazmati

Aula Jazmati

49 projects • 193 followers
(PhD) in Electronic Engineering 2023 💡🕊️

Comments