I've been getting into Python, so I decided to make a Snake game leveraging Pygame. This is only the source code, but if you want to see how to set up the environment, you can check out instructions on getting Python/Pygame up and running in Eclipse here.
The Fruit Module:
The Snake Module
The Main module
The Fruit Module:
Code:
'''
Created on 2013-11-08
@author: Smitty
A class to store the fruit information.
'''
class Fruit:
def __init__(self):
import random
#assigns a random X and Y to the fruit that is divisible by 10 so it aligns with the snake
self.x = random.randrange(0, 300, 10)
self.y = random.randrange(0, 300, 10)
self.colour = (255, 0, 0)
Code:
'''
Created on 2013-11-07
@author: Smitty
The snake module holds an "enum" for the direction, and the snake-relevant functions
'''
#directions the snake can get. Python doesn't seem to have enums so I made a class
class Direction:
LEFT = 1
RIGHT = 2
UP = 3
DOWN = 4
#just a basic class to hold the X and Y coord for a block of the snake
class SnakeBlock:
def __init__(self, x, y):
self.x = x
self.y = y
class Snake:
def Move(self):
#loop through each block backwards and set its x and y coordinate to the previous
#block in the sequence
for i in range(len(self.blocks), 1, -1):
self.blocks[i-1].x = self.blocks[i-2].x
self.blocks[i-1].y = self.blocks[i-2].y
if(self.direction == Direction.LEFT):
self.blocks[0].x -= 10
if(self.blocks[0].x < 0):
self.Kill()
elif(self.direction == Direction.RIGHT):
self.blocks[0].x += 10
if(self.blocks[0].x >= self.maxx):
self.Kill()
elif(self.direction == Direction.UP):
self.blocks[0].y -= 10
if(self.blocks[0].y < 0):
self.Kill()
elif(self.direction == Direction.DOWN):
self.blocks[0].y += 10
if(self.blocks[0].y >= self.maxy):
self.Kill()
for i in range(1, len(self.blocks)):
if(self.blocks[0].x == self.blocks[i].x and self.blocks[0].y == self.blocks[i].y):
self.Kill()
#it's game over, man!
def Kill(self):
self.alive = False
def AddBlock(self):
self.blocks.append(SnakeBlock(self.blocks[len(self.blocks) - 1].x, self.blocks[len(self.blocks) - 1].y))
#300 x 300 screen means 900 blocks. If the user gets to 899 blocks, they've won
if(len(self.blocks) >= 899):
self.winner = True
def __init__(self, maxx, maxy):
self.direction = Direction.RIGHT
self.blocks = [SnakeBlock(50, 50)]
self.alive = True
self.winner = False
self.maxx = maxx
self.maxy = maxy
Code:
'''
Created on 2013-11-07
@author: Smitty
'''
import pygame
from snake import Snake
from snake import Direction
from fruit import *
from pygame.locals import QUIT
from pygame.locals import KEYDOWN
from pygame.locals import K_LEFT
from pygame.locals import K_RIGHT
from pygame.locals import K_UP
from pygame.locals import K_DOWN
from pygame.locals import K_ESCAPE
from pygame.locals import K_RETURN
from pygame.locals import K_KP_ENTER
class Game:
#initialize the game.
#Load pygame and set up the game screen
def Initialize(self):
pygame.init()
self.screen = pygame.display.set_mode((300, 300))
pygame.display.set_caption('Smitty-Snake')
pygame.mouse.set_visible(0)
self.Blackout()
#fills the entire screen with a black background
def Blackout(self):
background = pygame.Surface(self.screen.get_size())
background = background.convert()
background.fill((0, 0, 0))
self.screen.blit(background, (0, 0))
def DrawSnake(self, snake):
pygame.time.delay(100) #the speed of the snake
#draw each block of the snake to the screen
for i in range(0, len(snake.blocks)):
pygame.draw.rect(self.screen, (255, 255, 255), (snake.blocks[i].x, snake.blocks[i].y, 9, 9), 0)
pygame.draw.rect(self.screen, (50, 50, 50), (snake.blocks[i].x, snake.blocks[i].y, 10, 10), 1)
def DrawFruit(self, fruit):
pygame.draw.rect(self.screen, fruit.colour, (fruit.x, fruit.y, 9, 9), 0)
pygame.draw.rect(self.screen, (50, 50, 50), (fruit.x, fruit.y, 10, 10), 1)
def Run(self):
#the bounds for the game. If the snake exceeds them, game over!
snake = Snake(300, 300)
fruit = Fruit()
while snake.alive and not snake.winner:
#required to draw to the screen.
#Update after everything has been blitted!
pygame.display.update()
for event in pygame.event.get():
if event.type == QUIT:
return
elif event.type == KEYDOWN and event.key == K_LEFT and snake.direction != Direction.RIGHT:
snake.direction = Direction.LEFT
elif event.type == KEYDOWN and event.key == K_RIGHT and snake.direction != Direction.LEFT:
snake.direction = Direction.RIGHT
elif event.type == KEYDOWN and event.key == K_UP and snake.direction != Direction.DOWN:
snake.direction = Direction.UP
elif event.type == KEYDOWN and event.key == K_DOWN and snake.direction != Direction.UP:
snake.direction = Direction.DOWN
#grab the position of the last block before we move it
removeX = snake.blocks[len(snake.blocks)-1].x
removeY = snake.blocks[len(snake.blocks)-1].y
snake.Move()
#draw black over the last block so the snake doesn't just keep extending
pygame.draw.rect(self.screen, (0, 0, 0), (removeX, removeY, 10, 10), 0)
self.DrawFruit(fruit)
self.DrawSnake(snake)
#hey, we got a fruit!
if(snake.blocks[0].x == fruit.x and snake.blocks[0].y == fruit.y):
snake.AddBlock()
fruit = Fruit()
#once the game ends, display the final screen
snakeGame.Menu(len(snake.blocks), snake.winner)
def Menu(self, score, winner):
self.Blackout()
gameoverFont = pygame.font.SysFont("arial", 24)
continueFont = pygame.font.SysFont("arial", 15)
if(winner):
gameoverLabel = gameoverFont.render("You Win!", 1, (255,255,255))
self.screen.blit(gameoverLabel, (95, 90))
else:
gameoverLabel = gameoverFont.render("Game Over!", 1, (255,255,255))
self.screen.blit(gameoverLabel, (95, 90))
scoreLabel = gameoverFont.render("Score: " + str(score), 1, (34, 139, 34))
self.screen.blit(scoreLabel, (105, 120))
continueLabel = continueFont.render("Press enter to play again or escape to exit.", 1 , (255,255,255))
self.screen.blit(continueLabel, (35, 150))
#again, update the screen because we're done drawing
pygame.display.update()
while 1:
for event in pygame.event.get():
if event.type == QUIT:
return
elif event.type == KEYDOWN and event.key == K_ESCAPE:
return
elif event.type == KEYDOWN and (event.key == K_RETURN or event.key == K_KP_ENTER):
self.Blackout()
snakeGame.Run()
return
snakeGame = Game()
snakeGame.Initialize()
snakeGame.Run()