webwinkelkeur logo

4.7 avg.

5150+ reviews
webwinkelkeur logoView all

5150+ reviews

5150+ reviews

Order by 16:00 for same day shipping

14 days return

GB

EN

Individual

Business

Raspberry Pi project: Pong with rotary encoder

Beginner
25 Min
114,85

Building and wiring

Wiring the Raspberry Pi is simple.

The HDMI cable goes into the HDMI port of the display and into that of the Raspberry Pi . Then the power goes into the micro USB and the keyboard and mouse into the USB ports.

Connect the rotary knob as shown in the diagram below.

Now that you have everything connected you can start programming your own pong game.

Programming

Now that you are going to start programming your pong project, first open the Thonny Python IDE.

There you write the code that is below and when you have written that down you save the project. Make sure you do that with a name that you can easily find again because: "you don't want to lose your code!"

Now that your code is ready you can open it and start playing pong, what is your high score?

import pygame, sys
from pygame.locals import *

# Source code Pong
# https://www.raspberrypiportugal.pt/jogo-atari-pong-python-pygame/
# Toevoeging Rotary encoder 
# Elektronicavoorjou.nl

from RPi import GPIO
clk = 17
dt = 18

GPIO.setmode(GPIO.BCM)
GPIO.setup(clk, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(dt, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

clkLastState = GPIO.input(clk)

FPS = 200
WINDOWWIDTH = 800
WINDOWHEIGHT = 600
LINETHICKNESS = 12
PADDLESIZE = 50
PADDLEOFFSET = 20
counter = int(WINDOWHEIGHT/2)

BLACK     = (0  ,0  ,0  )
WHITE     = (255,255,255)

def drawArena():
    DISPLAYSURF.fill((0,0,0))
    pygame.draw.rect(DISPLAYSURF, WHITE, ((0,0),(WINDOWWIDTH,WINDOWHEIGHT)), LINETHICKNESS*2)
    pygame.draw.line(DISPLAYSURF, WHITE, ((int(WINDOWWIDTH/2)),0),((int(WINDOWWIDTH/2)),WINDOWHEIGHT), (int(LINETHICKNESS/4)))

def drawPaddle(paddle):
    if paddle.bottom > WINDOWHEIGHT - LINETHICKNESS:
        paddle.bottom = WINDOWHEIGHT - LINETHICKNESS
    elif paddle.top < LINETHICKNESS:
        paddle.top = LINETHICKNESS
    pygame.draw.rect(DISPLAYSURF, WHITE, paddle)

def drawBall(ball):
    pygame.draw.rect(DISPLAYSURF, WHITE, ball)

def moveBall(ball, ballDirX, ballDirY):
    ball.x += ballDirX
    ball.y += ballDirY
    return ball

def checkEdgeCollision(ball, ballDirX, ballDirY):
    if ball.top == (LINETHICKNESS) or ball.bottom == (WINDOWHEIGHT - LINETHICKNESS):
        ballDirY = ballDirY * -1
    if ball.left == (LINETHICKNESS) or ball.right == (WINDOWWIDTH - LINETHICKNESS):
        ballDirX = ballDirX * -1
    return ballDirX, ballDirY
    
def checkHitBall(ball, paddle1, paddle2, ballDirX):
    if ballDirX == -1 and paddle1.right == ball.left and paddle1.top < ball.top and paddle1.bottom > ball.bottom:
        return -1
    elif ballDirX == 1 and paddle2.left == ball.right and paddle2.top < ball.top and paddle2.bottom > ball.bottom:
        return -1
    else: return 1

def checkPointScored(paddle1, ball, score, ballDirX):
    
    if ball.left == LINETHICKNESS: 
        return 0
   
    elif ballDirX == -1 and paddle1.right == ball.left and paddle1.top < ball.top and paddle1.bottom > ball.bottom:
        score += 1
        return score
   
    elif ball.right == WINDOWWIDTH - LINETHICKNESS:
        score += 5
        return score
    
    else: return score

def artificialIntelligence(ball, ballDirX, paddle2):
    if ballDirX == -1:
        if paddle2.centery < (WINDOWHEIGHT/2):
            paddle2.y += 1
        elif paddle2.centery > (WINDOWHEIGHT/2):
            paddle2.y -= 1
   
    elif ballDirX == 1:
        if paddle2.centery < ball.centery:
            paddle2.y += 1
        else:
            paddle2.y -=1
    return paddle2
def displayScore(score):
    resultSurf = BASICFONT.render('Score = %s' %(score), True, WHITE)
    resultRect = resultSurf.get_rect()
    resultRect.topleft = (WINDOWWIDTH - 150, 25)
    DISPLAYSURF.blit(resultSurf, resultRect)
def main():
    pygame.init()
    global DISPLAYSURF
    global BASICFONT, BASICFONTSIZE
    BASICFONTSIZE = 20
    BASICFONT = pygame.font.Font('freesansbold.ttf', BASICFONTSIZE)

    FPSCLOCK = pygame.time.Clock()
    DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT)) 
    pygame.display.set_caption('Pong')
    ballX = WINDOWWIDTH/2 - LINETHICKNESS/2
    ballY = WINDOWHEIGHT/2 - LINETHICKNESS/2
    playerOnePosition = (WINDOWHEIGHT - PADDLESIZE) /2
    playerTwoPosition = (WINDOWHEIGHT - PADDLESIZE) /2
    score = 0

    ballDirX = -1 
    ballDirY = -1  

    paddle1 = pygame.Rect(PADDLEOFFSET,playerOnePosition, LINETHICKNESS,PADDLESIZE)
    paddle2 = pygame.Rect(WINDOWWIDTH - PADDLEOFFSET - LINETHICKNESS, playerTwoPosition, LINETHICKNESS,PADDLESIZE)
    ball = pygame.Rect(ballX, ballY, LINETHICKNESS, LINETHICKNESS)

    drawArena()
    drawPaddle(paddle1)
    drawPaddle(paddle2)
    drawBall(ball)
    pygame.mouse.set_visible(0) 
    while True: 
        for event in pygame.event.get():
            if event.type == QUIT:
                GPIO.cleanup()
                pygame.quit()
                sys.exit()
    
        global clkLastState
        global counter
        clkState = GPIO.input(clk)
        dtState = GPIO.input(dt)
        if clkState != clkLastState:
                if dtState != clkState:
                        counter += 10
                        if counter > WINDOWHEIGHT:
                            counter = WINDOWHEIGHT
                else:
                        counter -= 10
                        if counter < 1:
                            counter = 1
                paddle1.y = counter
        clkLastState = clkState

        drawArena()
        drawPaddle(paddle1)
        drawPaddle(paddle2)
        drawBall(ball)

        ball = moveBall(ball, ballDirX, ballDirY)
        ballDirX, ballDirY = checkEdgeCollision(ball, ballDirX, ballDirY)
        score = checkPointScored(paddle1, ball, score, ballDirX)
        ballDirX = ballDirX * checkHitBall(ball, paddle1, paddle2, ballDirX)
        paddle2 = artificialIntelligence (ball, ballDirX, paddle2)

        displayScore(score)

        pygame.display.update()
        FPSCLOCK.tick(FPS)

if __name__=='__main__':
    main()