Artigos

O jogo de Atari PONG com Python e Pygame

Corriam os primeiros anos da década de 70 quando Atari colocou à venda uma consola chamada Atari Pong, esta consola não tinha ranhuras para cartuchos e apenas tinha um jogo instalado (PONG), criado por Nolan Bushnell no ano de 1972, que imitava o jogo Table tennis do sistema Magnavox Odyssey. O sistema Atari PONG ficou muito popular rapidamente e conseguiu vender mais de 55.000 unidades, o que não é nada mau.

 

Consola Atari Pong
Consola Atari Pong

 

O funcionamento do jogo PONG é muito simples, o jogador controla uma pá que se move verticalmente no lado esquerdo do ecrã e pode competir contra outro jogador ou contra a própria máquina que controlaria a segunda pá situada no lado direito. Ambos os jogadores devem fazer com que a bola ressalte contra a sua pá e tentar que o oponente falhe ao devolver marcando assim um ponto. O jogador que mais pontos tiver quando acabar o jogo, ganha. Resumindo, tenta simular uma partida de ténis de mesa (Ping-Pong), daí o seu nome.

 

PONG
PONG

Como quase em todos os casos de êxito, não tardaram em aparecer clones e variantes como TeleMatch, inclusive inseriram cópias do jogo em modelos de alguns televisores da época.

Hoje em dia, podemos jogar o PONG no nosso PC graças a emuladores como STELLA, um emulador não é mais um software que permite executar jogos de consolas noutras plataformas (como um PC ou um telemóvel) simulando a arquitetura de hardware e software própria de outra plataforma. Existem emuladores para quase todas as consolas (NES, SNES, MegaDrive, PlayStation, XBOX…).

Neste tutorial, não vai aprender a instalar emuladores de consolas no seu Raspberry Pi porque tenho pensado em escrever outro tutorial sobre o tema mas vai aprender a programar a sua própria versão de PONG com Python e Pygame. Como já sabe PyGame é um conjunto de livrarias que nos permite escrever jogos para o nosso Raspberry, usando linguagem de programação Python.

Navegando na Internet, encontrei este código-fonte de um clone de PONG, o qual é bastante interessante.

 

import pygame, sys
from pygame.locals import *

# Number of frames per second
# Change this value to speed up or slow down your game
FPS = 200

#Global Variables to be used through our program

WINDOWWIDTH = 400
WINDOWHEIGHT = 300
LINETHICKNESS = 10
PADDLESIZE = 50
PADDLEOFFSET = 20

# Set up the colours
BLACK     = (0  ,0  ,0  )
WHITE     = (255,255,255)

#Draws the arena the game will be played in. 
def drawArena():
    DISPLAYSURF.fill((0,0,0))
    #Draw outline of arena
    pygame.draw.rect(DISPLAYSURF, WHITE, ((0,0),(WINDOWWIDTH,WINDOWHEIGHT)), LINETHICKNESS*2)
    #Draw centre line
    pygame.draw.line(DISPLAYSURF, WHITE, ((WINDOWWIDTH/2),0),((WINDOWWIDTH/2),WINDOWHEIGHT), (LINETHICKNESS/4))


#Draws the paddle
def drawPaddle(paddle):
    #Stops paddle moving too low
    if paddle.bottom > WINDOWHEIGHT - LINETHICKNESS:
        paddle.bottom = WINDOWHEIGHT - LINETHICKNESS
    #Stops paddle moving too high
    elif paddle.top < LINETHICKNESS:
        paddle.top = LINETHICKNESS
    #Draws paddle
    pygame.draw.rect(DISPLAYSURF, WHITE, paddle)


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

#moves the ball returns new position
def moveBall(ball, ballDirX, ballDirY):
    ball.x += ballDirX
    ball.y += ballDirY
    return ball

#Checks for a collision with a wall, and 'bounces' ball off it.
#Returns new direction
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

#Checks is the ball has hit a paddle, and 'bounces' ball off it.     
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

#Checks to see if a point has been scored returns new score
def checkPointScored(paddle1, ball, score, ballDirX):
    #reset points if left wall is hit
    if ball.left == LINETHICKNESS: 
        return 0
    #1 point for hitting the ball
    elif ballDirX == -1 and paddle1.right == ball.left and paddle1.top < ball.top and paddle1.bottom > ball.bottom:
        score += 1
        return score
    #5 points for beating the other paddle
    elif ball.right == WINDOWWIDTH - LINETHICKNESS:
        score += 5
        return score
    #if no points scored, return score unchanged
    else: return score

#Artificial Intelligence of computer player 
def artificialIntelligence(ball, ballDirX, paddle2):
    #If ball is moving away from paddle, center bat
    if ballDirX == -1:
        if paddle2.centery < (WINDOWHEIGHT/2): paddle2.y += 1 elif paddle2.centery > (WINDOWHEIGHT/2):
            paddle2.y -= 1
    #if ball moving towards bat, track its movement. 
    elif ballDirX == 1:
        if paddle2.centery < ball.centery:
            paddle2.y += 1
        else:
            paddle2.y -=1
    return paddle2

#Displays the current score on the screen
def displayScore(score):
    resultSurf = BASICFONT.render('Score = %s' %(score), True, WHITE)
    resultRect = resultSurf.get_rect()
    resultRect.topleft = (WINDOWWIDTH - 150, 25)
    DISPLAYSURF.blit(resultSurf, resultRect)

#Main function
def main():
    pygame.init()
    global DISPLAYSURF
    ##Font information
    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')

    #Initiate variable and set starting positions
    #any future changes made within rectangles
    ballX = WINDOWWIDTH/2 - LINETHICKNESS/2
    ballY = WINDOWHEIGHT/2 - LINETHICKNESS/2
    playerOnePosition = (WINDOWHEIGHT - PADDLESIZE) /2
    playerTwoPosition = (WINDOWHEIGHT - PADDLESIZE) /2
    score = 0

    #Keeps track of ball direction
    ballDirX = -1 ## -1 = left 1 = right
    ballDirY = -1 ## -1 = up 1 = down

    #Creates Rectangles for ball and paddles.
    paddle1 = pygame.Rect(PADDLEOFFSET,playerOnePosition, LINETHICKNESS,PADDLESIZE)
    paddle2 = pygame.Rect(WINDOWWIDTH - PADDLEOFFSET - LINETHICKNESS, playerTwoPosition, LINETHICKNESS,PADDLESIZE)
    ball = pygame.Rect(ballX, ballY, LINETHICKNESS, LINETHICKNESS)

    #Draws the starting position of the Arena
    drawArena()
    drawPaddle(paddle1)
    drawPaddle(paddle2)
    drawBall(ball)

    pygame.mouse.set_visible(0) # make cursor invisible

    while True: #main game loop
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            # mouse movement commands
            elif event.type == MOUSEMOTION:
                mousex, mousey = event.pos
                paddle1.y = mousey

        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()

 

Para jogar, apenas tem que copiar e pegar no código-fonte de um arquivo chamado pong.py no diretório ‘home/pi‘ do seu Raspberry e a seguir executa estes comandos no terminal:

 

cd /home/pi
sudo pytyhon pong.py

 

Assim ficará o jogo a correr no Raspberry Pi, eu liguei-o um mini ecrã TFT.

 

Gostaram deste artigo ? Deixem o vosso comentário no formulário a baixo.

Não se esqueçam de fazer like na nossa página no facebook.

Todos os produtos utilizados neste artigo podem ser encontrados na loja de componentes eletrónicos ElectroFun.

Comments

comments

Deixar uma resposta

Este site utiliza o Akismet para reduzir spam. Fica a saber como são processados os dados dos comentários.