import pygame #pip install pygame
import sys #pip install sys
import random #pip install random
import time #pip install time
# game initialization
errors = pygame.init()
if errors[1] > 0:
print('(!) Got {0} errors during initializing pygame \
exiting...'.format(errors[1]))
sys.exit(-1)
else:
print('(+) pygame successfully initialized.')
# game screen
width = 750 #Screen width
height = 495 #Screen Height
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Snake game')
# colors
red = pygame.Color(255, 0, 0) # game over
grey_blue = pygame.Color(77, 126, 118) # snake body
green = pygame.Color(12, 182, 128) # player score
white = pygame.Color(237, 226, 202) # game background
brown = pygame.Color(109, 50, 4) # food
# FPS controller
fps_controller = pygame.time.Clock()
# game variables
start_x = 300
start_y = 150
step = 15 # block width is 10
body_length = 3
head = [start_x, start_y] # snake start position [x, y]
# initialize snake body, index 0 contains the snake head
body = [[start_x - i * step, start_y] for i in range(body_length)]
score = 0
level = 1
foodPos = [random.randrange(2, width / step - 1) * step, \
random.randrange(2, height / step - 1) * step] # don't put food at the border of the screen
foodSpawn = True
direction = 'RIGHT'
next = direction # new direction after user hits keyboard
def draw_game_menu():
count = 3
font = pygame.font.SysFont('ds-digital', 60)
while True:
screen.fill(white)
start_surface = font.render('Start in {0} seconds.'.format(count), True, green)
start_rect = start_surface.get_rect()
start_rect.midtop = (width / 2, 80)
screen.blit(start_surface, start_rect)
esc_surface = font.render('''Press Esc to exit during game.''', True, green)
esc_rect = esc_surface.get_rect()
esc_rect.midtop = (width / 2, 150)
screen.blit(esc_surface, esc_rect)
pause_surface = font.render('''Press Space to pause the game.''', True, green)
pause_rect = pause_surface.get_rect()
pause_rect.midtop = (width / 2, 220)
screen.blit(pause_surface, pause_rect)
pygame.display.flip() # update the game screen
time.sleep(1)
fps_controller.tick()
count -= 1
if count == 0: break
def draw_game_pause():
font = pygame.font.SysFont('ds-digital', 18)
while True:
pause_surface = font.render('Press Space to continue.', True, green)
pause_rect = pause_surface.get_rect()
pause_rect.midtop = (width / 2, 150)
screen.blit(pause_surface, pause_rect)
pygame.display.flip()
fps_controller.tick()
for move in pygame.event.get():
if move.type == pygame.KEYDOWN:
if move.key == pygame.K_SPACE: return
def show_score(game_over=False):
font = pygame.font.SysFont('ds-digital', 18)
score_surface = font.render('Score: {0}'.format(score), True, green)
score_rect = score_surface.get_rect()
if game_over == False:
score_rect.midtop = (75, 10)
else:
score_rect.midtop = (width / 2, 130)
screen.blit(score_surface, score_rect)
# game over function
def draw_game_over():
font = pygame.font.SysFont('ds-digital', 24)
surface = font.render('Game Over !', True, red)
GO_rect = surface.get_rect()
GO_rect.midtop = (width/2, 60)
screen.blit(surface, GO_rect)
show_score(game_over=True)
pygame.display.flip() # update the game screen
time.sleep(4)
pygame.quit() # quit the game
sys.exit() # exit the console
def get_food(foodPos, body):
for block in body:
if block[0] == foodPos[0] and block[1] == foodPos[1]:
return True
return False
# game start menu
draw_game_menu()
# main logic of the game
while True:
for move in pygame.event.get():
if move.type == pygame.KEYDOWN: # if user press any button
if move.key == pygame.K_RIGHT or move.key == ord('d'):
next = 'RIGHT'
elif move.key == pygame.K_LEFT or move.key == ord('a'):
next = 'LEFT'
elif move.key == pygame.K_UP or move.key == ord('w'):
next = 'UP'
elif move.key == pygame.K_DOWN or move.key == ord('s'):
next = 'DOWN'
elif move.key == pygame.K_ESCAPE: # if user choose to quit the game
pygame.event.post(pygame.event.Event(pygame.QUIT))
elif move.key == pygame.K_SPACE:
draw_game_pause()
if move.type == pygame.QUIT:
pygame.quit()
sys.exit()
# move snake head
if direction == 'RIGHT':
head[0] += step
elif direction == 'LEFT':
head[0] -= step
elif direction == 'DOWN':
head[1] += step
elif direction == 'UP':
head[1] -= step
# validation of direction
if next == 'RIGHT' and direction != 'LEFT':
direction = 'RIGHT'
elif next == 'LEFT' and direction != 'RIGHT':
direction = 'LEFT'
elif next == 'DOWN' and direction != 'UP':
direction = 'DOWN'
elif next == 'UP' and direction != 'DOWN':
direction = 'UP'
# move snake body mechanism
# insert a new block at the beginning of the body
body.insert(0, list(head))
if head[0] == foodPos[0] and head[1] == foodPos[1]:
foodSpawn = False
score += 1
else:
body.pop()
while foodSpawn == False:
foodPos = [random.randrange(2, width / step - 1) * step,
random.randrange(2, height / step - 1) * step]
if get_food(foodPos, body) == True:
foodSpawn = False
else:
foodSpawn = True
# fill game background
screen.fill(white)
# draw snake body
for pos in body:
pygame.draw.rect(screen, grey_blue, pygame.Rect(pos[0], pos[1], step, step))
# draw food
pygame.draw.rect(screen, brown, pygame.Rect(foodPos[0], foodPos[1], step, step))
# check if snake hits the border
if (head[0] > width - step) or (head[0] < 0) or \
(head[1] > height - step) or (head[1] < 0):
draw_game_over()
# check if snake hits itself
for block in body[1:]:
if head[0] == block[0] and head[1] == block[1]:
draw_game_over()
level = score//5 + 1
if level > 3:
level = 3
show_score(game_over=False)
pygame.display.flip()
if level == 1:
fps_controller.tick(8)
elif level == 2:
fps_controller.tick(10)
elif level == 3:
fps_controller.tick(12)
#--------------------------------End Of Code--------------------------------#