I created this simple snake game a while ago and I wanted to try running it and for some reason the window is not starting on my machine. I am sure the code was working before. I tried debugging for a while but can't seem to figure out why I am stuck on a black screen. It seems to detect a key pressed but nothing is displayed on the screen.
import pygame
from pygame.locals import *
import random
# Global Color Variables
RED = (255, 0, 0)
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
CYAN = (0,255, 255)
# Set the speed of the Snake --> lower = faster
timeDelaySpeed = 0
class App:
def __init__(self):
self._running = True
self._display_surf = None
self.size = self.weight, self.height = 600, 700
# create the boarder
self.boarder = self.generateBoard()
# Initial Snake array with 3 Snake Blocks starting at (50, 50) and going left
self.snake = [Snake(WHITE, 10, 10, 150, 260), Snake(WHITE, 10, 10, 140, 260), Snake(WHITE, 10, 10, 130, 260)]
def on_init(self):
pygame.init()
self._display_surf = pygame.display.set_mode(self.size, pygame.HWSURFACE | pygame.DOUBLEBUF)
self._display_surf.fill(BLACK)
self._running = True
# Create Score Board
self.score = 0
self.displayScore(self.score, 45)
# Create Initial Food
self.initFood = Food(RED, 10, 10)
self._display_surf.blit(self.initFood.image, self.initFood.rect)
# display the initial Snake array
for i in range(len(self.snake)):
self._display_surf.blit(self.snake[i].image, self.snake[i].rect)
# display the board
for i in range(len(self.boarder)):
self._display_surf.blit(self.boarder[i].image, self.boarder[i].rect)
pygame.display.update()
"""
Helper Method that will run the events that are clicked on by the user
"""
def on_event(self):
# Checks if Snake crashes with itself - LOSE
for i in range(1, len(self.snake)):
if pygame.sprite.collide_rect(self.snake[0], self.snake[1]):
self.spaceToRestartText(20)
self.gameRestart()
if pygame.sprite.collide_rect(self.snake[0], self.snake[i]):
self.spaceToRestartText(20)
self.gameRestart()
# Check if Snake hits the boarder - LOSE
for i in range(len(self.boarder)):
if pygame.sprite.collide_rect(self.snake[0], self.boarder[i]):
self.spaceToRestartText(20)
self.gameRestart()
# Checks if Snake eats Food
if pygame.sprite.collide_rect(self.snake[0], self.initFood):
self.eatFood()
# set the direction based of key that is pressed
for event in pygame.event.get():
if event.type == pygame.QUIT:
self._running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
# check for self collision before eating any food - weird collision method error fix
if self.move == 'right':
self.spaceToRestartText(20)
self.gameRestart()
break
self.move = 'left'
if event.key == pygame.K_RIGHT:
# check for self collision before eating any food
if self.move == 'left':
self.spaceToRestartText(20)
self.gameRestart()
break
self.move = 'right'
if event.key == pygame.K_UP:
# check for self collision before eating any food
if self.move == 'down':
self.spaceToRestartText(20)
self.gameRestart()
break
self.move = 'up'
if event.key == pygame.K_DOWN:
# check for self collision before eating any food
if self.move == 'up':
self.spaceToRestartText(20)
self.gameRestart()
break
self.move = 'down'
# if stored current direction is right
if self.move == 'right':
print("RIGHT")
# Reset the Board
self.boardReset()
# Store the current head of the snake
snakeHead = self.snake[0]
# remove the last block of the snake
self.snake.pop()
# create a new head for the snake that is shifted toward the right
newHead = snakeHead.moveRight()
# add the newly created head to the front of the list - make head
self.snake.insert(0, newHead)
# displays moved snake
for i in range(len(self.snake)):
self._display_surf.blit(self.snake[i].image, self.snake[i].rect)
pygame.display.update()
pygame.time.delay(timeDelaySpeed)
# if stored current direction is left
if self.move == 'left':
print("LEFT")
# Reset the Board
self.boardReset()
# Store the current head of the snake
snakeHead = self.snake[0]
# remove the last block of the snake
self.snake.pop()
# create a new head for the snake that is shifted toward the right
newHead = snakeHead.moveLeft()
# add the newly created head to the front of the list - make head
self.snake.insert(0, newHead)
# displays moved snake
for i in range(len(self.snake)):
self._display_surf.blit(self.snake[i].image, self.snake[i].rect)
pygame.display.update()
pygame.time.delay(timeDelaySpeed)
# if stored current direction is up
if self.move == 'up':
print("UP")
# Reset the Board
self.boardReset()
# Store the current head of the snake
snakeHead = self.snake[0]
# remove the last block of the snake
self.snake.pop()
# create a new head for the snake that is shifted toward the right
newHead = snakeHead.moveUp()
# add the newly created head to the front of the list - make head
self.snake.insert(0, newHead)
# displays moved snake
for i in range(len(self.snake)):
self._display_surf.blit(self.snake[i].image, self.snake[i].rect)
pygame.display.update()
pygame.time.delay(timeDelaySpeed)
# if stored current direction is down
if self.move == 'down':
print("DOWN")
# Reset the Board
self.boardReset()
# Store the current head of the snake
snakeHead = self.snake[0]
# remove the last block of the snake
self.snake.pop()
# create a new head for the snake that is shifted toward the right
newHead = snakeHead.moveDown()
# add the newly created head to the front of the list - make head
self.snake.insert(0, newHead)
# displays moved snake
for i in range(len(self.snake)):
self._display_surf.blit(self.snake[i].image, self.snake[i].rect)
pygame.display.update()
pygame.time.delay(timeDelaySpeed)
"""
Helper method that displays the current score on the screen.
"""
def displayScore(self, score, size):
font = pygame.font.SysFont("Comic Sans MS", size)
ScoreBoard = font.render("SCORE: {}".format(score), False, (WHITE))
self._display_surf.blit(ScoreBoard, [90, 100])
pygame.display.update()
"""
Helper method that will reset the screen:
Make screen Black
Add the current Food block
Add the current Score
"""
def boardReset(self):
# Erases the current screen
self._display_surf = pygame.display.set_mode(self.size, pygame.HWSURFACE | pygame.DOUBLEBUF)
self._display_surf.fill(BLACK)
# Create Score Board
self.displayScore(self.score, 45)
# Add Food
self._display_surf.blit(self.initFood.image, self.initFood.rect)
# Add Boarder
for i in range(len(self.boarder)):
self._display_surf.blit(self.boarder[i].image, self.boarder[i].rect)
"""
Eating food helper method
"""
def eatFood(self):
# Create a new Food at random location and display it
self.initFood = Food(RED, 10, 10)
self._display_surf.blit(self.initFood.image, self.initFood.rect)
# Create Score Board
self.score += 1
self.displayScore(self.score, 45)
# for i in range(len(self.snake)):
# self._display_surf.blit(self.snake[i].image, self.snake[i].rect)
#
# Store the last and second to last blocks of the snake
lastSnakeBlock = self.snake[-1]
secondToLastBlock = self.snake[-2]
# if the last two blocks are on the same horizontal line and the last block is to the left of the
# second to last block, add a block to the left side of the last block
if lastSnakeBlock.rect.y == secondToLastBlock.rect.y and lastSnakeBlock.rect.x < secondToLastBlock.rect.x:
newX = lastSnakeBlock.rect.x - 10
newSnakeBlock = Snake(lastSnakeBlock.color, lastSnakeBlock.width, lastSnakeBlock.height, newX,
lastSnakeBlock.rect.y)
self.snake.append(newSnakeBlock)
# if the last two blocks are on the same horizontal line and the last block is to the right of the
# second to last block, add a block to the right side of the last block
if lastSnakeBlock.rect.y == secondToLastBlock.rect.y and lastSnakeBlock.rect.x > secondToLastBlock.rect.x:
newX = lastSnakeBlock.rect.x + 10
newSnakeBlock = Snake(lastSnakeBlock.color, lastSnakeBlock.width, lastSnakeBlock.height, newX,
lastSnakeBlock.rect.y)
self.snake.append(newSnakeBlock)
# if the last two blocks are on the same vertical line and the last block is above the
# second to last block, add a block above the last block
if lastSnakeBlock.rect.x == secondToLastBlock.rect.x and lastSnakeBlock.rect.y < secondToLastBlock.rect.y:
newY = lastSnakeBlock.rect.y - 10
newSnakeBlock = Snake(lastSnakeBlock.color, lastSnakeBlock.width, lastSnakeBlock.height,
lastSnakeBlock.rect.x, newY)
self.snake.append(newSnakeBlock)
# if the last two blocks are on the same vertical line and the last block is below the
# second to last block, add a block below the last block
if lastSnakeBlock.rect.x == secondToLastBlock.rect.x and lastSnakeBlock.rect.y > secondToLastBlock.rect.y:
newY = lastSnakeBlock.rect.y + 10
newSnakeBlock = Snake(lastSnakeBlock.color, lastSnakeBlock.width, lastSnakeBlock.height,
lastSnakeBlock.rect.x, newY)
self.snake.append(newSnakeBlock)
for i in range(len(self.snake)):
self._display_surf.blit(self.snake[i].image, self.snake[i].rect)
"""
Takes the player back to initial start state
"""
def gameRestart(self):
# Erase the Board
self._display_surf = pygame.display.set_mode(self.size, pygame.HWSURFACE | pygame.DOUBLEBUF)
self._display_surf.fill(BLACK)
self._running = True
# Recreate the Snake
self.snake = [Snake(WHITE, 10, 10, 150, 260), Snake(WHITE, 10, 10, 140, 260), Snake(WHITE, 10, 10, 130, 260)]
# Create Score Board
self.score = 0
self.displayScore(self.score, 45)
# Create Initial Food
self.initFood = Food(RED, 10, 10)
self._display_surf.blit(self.initFood.image, self.initFood.rect)
# set current move to nothing
self.move = ''
# draw in the boarder
for i in range(len(self.boarder)):
self._display_surf.blit(self.boarder[i].image, self.boarder[i].rect)
# display the initial Snake array
for i in range(len(self.snake)):
self._display_surf.blit(self.snake[i].image, self.snake[i].rect)
pygame.display.update()
"""
Creates a List of Blocks that outline the Boarder of the snake game
"""
def generateBoard(self):
boardCorners = []
boardTop = []
boardSide1 = []
boardSide2 = []
boardBottom = []
# Makes (0,0) of board = (100, 210)
# top left corner
boardCorners.append(Snake(CYAN, 10, 10, 90, 200))
# top right corner
boardCorners.append(Snake(CYAN, 10, 10, 500, 200))
# bottom left corner
boardCorners.append(Snake(CYAN, 10, 10, 90, 610))
# bottom right corner
boardCorners.append(Snake(CYAN, 10, 10, 500, 610))
# top and bottom sides
topCoord = 100
for i in range(40):
boardTop.append(Snake(CYAN, 10, 10, topCoord, 200))
boardBottom.append(Snake(CYAN, 10, 10, topCoord, 610))
topCoord += 10
# sides of board
sideCoord = 210
for i in range(40):
boardSide1.append(Snake(CYAN, 10, 10, 90, sideCoord))
boardSide2.append(Snake(CYAN, 10, 10, 500, sideCoord))
sideCoord += 10
# combine all parts
allBoarder = boardCorners + boardTop + boardSide1 + boardSide2 + boardBottom
# return list of blocks
return allBoarder
"""
Allows player to restart a game by pressing space bar - displays losing screen
"""
def spaceToRestartText(self, size):
self._display_surf = pygame.display.set_mode(self.size, pygame.HWSURFACE | pygame.DOUBLEBUF)
self._display_surf.fill(BLACK)
self.youLoseText(50)
self.yourScoreText(25)
font = pygame.font.SysFont("Comic Sans MS", size)
text_surface = font.render("Press space bar to play again", True, WHITE)
text_rect = text_surface.get_rect(center=(self.weight / 2, self.height / 2))
self._display_surf.blit(text_surface, text_rect)
pygame.display.flip()
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
done = True
"""
Helper function that prints 'YOU LOSE!'
"""
def youLoseText(self, size):
font = pygame.font.SysFont("Comic Sans MS", size)
text_surface = font.render("YOU LOSE!", True, WHITE)
# Shift height up so no collision with space bar text
text_rect = text_surface.get_rect(center=(self.weight / 2, (self.height / 2) - 75))
self._display_surf.blit(text_surface, text_rect)
pygame.display.flip()
"""
Helper function that prints your score at loss
"""
def yourScoreText(self, size):
font = pygame.font.SysFont("Comic Sans MS", size)
text_surface = font.render("Your Score was: " + str(self.score), True, WHITE)
# Shift height up so no collision with space bar text
text_rect = text_surface.get_rect(center=(self.weight / 2, (self.height / 2) - 35))
self._display_surf.blit(text_surface, text_rect)
pygame.display.flip()
def on_loop(self):
pass
def on_render(self):
pass
def on_cleanup(self):
pygame.quit()
"""
Game Loop
"""
def on_execute(self):
if self.on_init() == False:
self._running = False
self.move = ''
while (self._running):
self.on_event()
self.on_loop()
self.on_render()
self.on_cleanup()
"""
Class to create a Food at a random coordinate
"""
class Food(pygame.sprite.Sprite):
def __init__(self, color, width, height):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Create an image of the block, and fill it with a color.
# This could also be an image loaded from the disk.
self.image = pygame.Surface([width, height])
self.image.fill(color)
# Fetch the rectangle object that has the dimensions of the image
# Update the position of this object by setting the values of rect.x and rect.y
self.rect = self.image.get_rect()
# set the position of the Food
# TODO: change values in randint to use the input width and height
randX = random.randint(10,49) * 10
randY = random.randint(21,60) * 10
self.rect.x = randX
self.rect.y = randY
class Snake(pygame.sprite.Sprite):
# TODO: Make Snake a chain of Blocks
def __init__(self, color, width, height, positionX, positionY):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Create an image of the block, and fill it with a color.
# This could also be an image loaded from the disk.
self.image = pygame.Surface([width, height])
self.image.fill(color)
# Fetch the rectangle object that has the dimensions of the image
# Update the position of this object by setting the values of rect.x and rect.y
self.rect = self.image.get_rect()
# set the position of the snake
self.rect.x = positionX
self.rect.y = positionY
# set the inputs the usable variables for later code
self.color = color
self.width = width
self.height = height
"""
Method the will change the direction of the Snake towards the left
"""
def moveLeft(self):
newX = self.rect.x - 10
return Snake(self.color, self.width, self.height, newX, self.rect.y)
"""
Method that will change the direction of the Snake toward the right
"""
def moveRight(self):
newX = self.rect.x + 10
return Snake(self.color, self.width, self.height, newX, self.rect.y)
"""
Method that will change the direction of the Snake to go upward
"""
def moveUp(self):
newY = self.rect.y - 10
return Snake(self.color, self.width, self.height, self.rect.x, newY)
"""
Method that will change the direction of the Snake to go downward
"""
def moveDown(self):
newY = self.rect.y + 10
return Snake(self.color, self.width, self.height, self.rect.x, newY)
if __name__ == "__main__":
theApp = App()
theApp.on_execute()
I can agree with the answers above. The only problem appears to be that you did not set the FPS i.e. clock.tick(fps) and the game is too fast so it is unplayable. 30 and under will do in my opinion. Please provide more details.