Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pyqt_snake
Snake in PyQt
==========

simple snake game coded in python, using PyQt
Simple snake game coded in python, using PyQt.

![screen shot of game over](screenshot_pyqt_snake.png)
`pyqt_snake_raspberry.py` instead is the same code but support 8/10/12/16 pin of Raspberry Pi to move the snake.

![screenshot of game over](screenshot_pyqt_snake.png)
174 changes: 102 additions & 72 deletions pyqt_snake.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,55 @@
#!/usr/bin/python
import sys, time
import thread
#!/usr/bin/python3
import sys
from random import randrange
from PyQt5 import QtWidgets, QtCore, QtGui

from PyQt4 import QtGui, QtCore

class Snake(QtGui.QWidget):
# Initialize a new Qt Widget
class Snake(QtWidgets.QWidget):
def __init__(self):
# Inherit the features of QWidget class
super(Snake, self).__init__()
# Print the window
self.initUI()

def initUI(self):
self.highscore = 0
self.newGame()
self.setStyleSheet("QWidget { background: #A9F5D0 }")
# Define the window background in hexadecimal
self.setStyleSheet("QWidget { background: #A9F5D0 }")
self.setFixedSize(300, 300)
self.setWindowTitle('Snake')
self.show()

# The custom timer repaint all the objects in the window
# defined in newGame method
def timerEvent(self, event):
if event.timerId() == self.timer.timerId():
self.direction(self.lastKeyPress)
self.repaint()
else:
QtWidgets.QFrame.timerEvent(self, event)

# Executed at every milliseconds of the timer
def paintEvent(self, event):
qp = QtGui.QPainter()
qp.begin(self)
# Print the score board
self.scoreBoard(qp)
# Put the food
self.placeFood(qp)
# Draw the snake
self.drawSnake(qp)
# Print an updated score
self.scoreText(event, qp)
# If game is over
if self.isOver:
self.gameOver(event, qp)
qp.end()

# Executed when there is a key press
def keyPressEvent(self, e):
if not self.isPaused:
#print "inflection point: ", self.x, " ", self.y
# To avoid that the snake go backwards, we check the previous button
if e.key() == QtCore.Qt.Key_Up and self.lastKeyPress != 'UP' and self.lastKeyPress != 'DOWN':
self.direction("UP")
self.lastKeyPress = 'UP'
Expand All @@ -44,128 +62,140 @@ def keyPressEvent(self, e):
elif e.key() == QtCore.Qt.Key_Right and self.lastKeyPress != 'RIGHT' and self.lastKeyPress != 'LEFT':
self.direction("RIGHT")
self.lastKeyPress = 'RIGHT'
# Take a break!
elif e.key() == QtCore.Qt.Key_P:
self.pause()
# The game is paused let's start
elif e.key() == QtCore.Qt.Key_P:
self.start()
elif e.key() == QtCore.Qt.Key_Space:
self.newGame()
elif e.key() == QtCore.Qt.Key_Escape:
self.close()

# Define the various variables
def newGame(self):
# Default score
self.score = 0
# Initial snake position
self.x = 12;
self.y = 36;
self.snakeArray = [[self.x, self.y], [self.x-12, self.y], [self.x-24, self.y]]
# Define a first fake key press
self.lastKeyPress = 'RIGHT'
self.timer = QtCore.QBasicTimer()
self.snakeArray = [[self.x, self.y], [self.x-12, self.y], [self.x-24, self.y]]
# Initial fake position for food
self.foodx = 0
self.foody = 0
# Status of the game
self.isPaused = False
self.isOver = False
self.FoodPlaced = False
# The timer is executed every 100ms
self.speed = 100
self.start()

def pause(self):
self.isPaused = True
self.timer.stop()
self.update()

def start(self):
self.isPaused = False
# Set the timer
self.timer.start(self.speed, self)
# Let's do a repaint of the window
self.update()

def pause(self):
self.isPaused = True
# We stop the time progressing
self.timer.stop()
# Let's do a repaint of the window
self.update()

def direction(self, dir):
if (dir == "DOWN" and self.checkStatus(self.x, self.y+12)):
self.y += 12
self.repaint()
self.snakeArray.insert(0 ,[self.x, self.y])
elif (dir == "UP" and self.checkStatus(self.x, self.y-12)):
self.y -= 12
self.repaint()
self.snakeArray.insert(0 ,[self.x, self.y])
elif (dir == "RIGHT" and self.checkStatus(self.x+12, self.y)):
self.x += 12
self.repaint()
self.snakeArray.insert(0 ,[self.x, self.y])
elif (dir == "LEFT" and self.checkStatus(self.x-12, self.y)):
self.x -= 12
self.repaint()
self.snakeArray.insert(0 ,[self.x, self.y])
def scoreBoard(self, qp):
qp.setPen(QtCore.Qt.NoPen)
qp.setBrush(QtGui.QColor(25, 80, 0, 160))
qp.drawRect(0, 0, 300, 24)

def scoreText(self, event, qp):
qp.setPen(QtGui.QColor(255, 255, 255))
qp.setFont(QtGui.QFont('Decorative', 10))
qp.drawText(8, 17, "SCORE: " + str(self.score))
qp.drawText(195, 17, "HIGHSCORE: " + str(self.highscore))

def gameOver(self, event, qp):
self.highscore = max(self.highscore, self.score)
qp.setPen(QtGui.QColor(0, 34, 3))
qp.setFont(QtGui.QFont('Decorative', 10))
qp.drawText(event.rect(), QtCore.Qt.AlignCenter, "GAME OVER")
qp.setFont(QtGui.QFont('Decorative', 8))
qp.drawText(80, 170, "press space to play again")

def checkStatus(self, x, y):
if y > 288 or x > 288 or x < 0 or y < 24:
self.pause()
self.isPaused = True
self.isOver = True
return False
elif self.snakeArray[0] in self.snakeArray[1:len(self.snakeArray)]:
# Check of the position of the snake is at the borders
pos = y > 288 or x > 288 or x < 0 or y < 24
# If the snake touched the borders or the window is full
if pos or (self.snakeArray[0] in self.snakeArray[1:len(self.snakeArray)]):
self.pause()
self.isPaused = True
self.isOver = True
return False
# If the snake is at the same position of the food
elif self.y == self.foody and self.x == self.foodx:
self.FoodPlaced = False
self.score += 1
return True
elif self.score >= 573:
print "you win!"

# Remove the last piece of the snake
self.snakeArray.pop()

return True

#places the food when theres none on the board
def direction(self, dir):
# Change the direction of the snake
# Calculate the next pixel where will be
if (dir == "DOWN" and self.checkStatus(self.x, self.y+12)):
self.y += 12
elif (dir == "UP" and self.checkStatus(self.x, self.y-12)):
self.y -= 12
elif (dir == "RIGHT" and self.checkStatus(self.x+12, self.y)):
self.x += 12
elif (dir == "LEFT" and self.checkStatus(self.x-12, self.y)):
self.x -= 12
# Refresh the window
self.repaint()
# Save in memory the new snake position
self.snakeArray.insert(0 ,[self.x, self.y])

# Places the food when theres none on the board
def placeFood(self, qp):
if self.FoodPlaced == False:
self.foodx = randrange(24)*12
self.foody = randrange(2, 24)*12
# IF the new position is not where is the snake
if not [self.foodx, self.foody] in self.snakeArray:
self.FoodPlaced = True;
# Draw the food and set the color
qp.setBrush(QtGui.QColor(80, 180, 0, 160))
qp.drawRect(self.foodx, self.foody, 12, 12)

#draws each component of the snake
# Draws each piece of the snake
def drawSnake(self, qp):
qp.setPen(QtCore.Qt.NoPen)
# Draw the piece and set the color
qp.setBrush(QtGui.QColor(255, 80, 0, 255))
for i in self.snakeArray:
# For every piece position draw it
qp.drawRect(i[0], i[1], 12, 12)

#game thread
def timerEvent(self, event):
if event.timerId() == self.timer.timerId():
self.direction(self.lastKeyPress)
self.repaint()
else:
QtGui.QFrame.timerEvent(self, event)
def scoreBoard(self, qp):
# Design the board
qp.setPen(QtCore.Qt.NoPen)
qp.setBrush(QtGui.QColor(25, 80, 0, 160))
qp.drawRect(0, 0, 300, 24)

def scoreText(self, event, qp):
qp.setPen(QtGui.QColor(255, 255, 255))
qp.setFont(QtGui.QFont('Decorative', 10))
# The first 2 numers are the pixel position for the text
# We need to convert the score as string to print it
qp.drawText(8, 17, "SCORE: " + str(self.score))
qp.drawText(200, 17, "HIGHSCORE: " + str(self.highscore))

def gameOver(self, event, qp):
# Compare the actual score with the maximum and get it
self.highscore = max(self.highscore, self.score)
qp.setPen(QtGui.QColor(0, 34, 3))
qp.setFont(QtGui.QFont('Decorative', 10))
qp.drawText(event.rect(), QtCore.Qt.AlignCenter, "GAME OVER")
qp.setFont(QtGui.QFont('Decorative', 8))
qp.drawText(90, 170, "press space to play again")

# Classic way to execute a python class
def main():
app = QtGui.QApplication(sys.argv)
# Create a new QT app empty
app = QtWidgets.QApplication(sys.argv)
# Run on this app our class
ex = Snake()
# If the window is trying to getting closed kill the app
sys.exit(app.exec_())


if __name__ == '__main__':
main()
main()
Loading