# Snakey (A Nibbles Clone) # http://inventwithpython.com/blog # By Al Sweigart al@inventwithpython.com # Creative Commons BY-NC-SA license # 158 lines of code import random import time import pygame import sys from pygame.locals import * FPS = 15 WINDOWWIDTH = 640 WINDOWHEIGHT = 480 CELLSIZE = 20 CELLWIDTH = int(WINDOWWIDTH / CELLSIZE) CELLHEIGHT = int(WINDOWHEIGHT / CELLSIZE) WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) GREEN = (0, 255, 0) DARKGREEN = (0, 155, 0) DARKGRAY = (40, 40, 40) BGCOLOR = BLACK UP = 1 DOWN = 2 LEFT = 3 RIGHT = 4 def main(): global MAINCLOCK, MAINSURF, BASICFONT pygame.init() MAINCLOCK = pygame.time.Clock() MAINSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT)) BASICFONT = pygame.font.Font('freesansbold.ttf', 18) pygame.display.set_caption('Snakey') showStartScreen() while True: gameLoop() showGameOverScreen() def showStartScreen(): titleFont = pygame.font.Font('freesansbold.ttf', 100) titleSurf1 = titleFont.render('Snakey!', True, WHITE, DARKGREEN) titleSurf2 = titleFont.render('Snakey!', True, GREEN) pressKeySurf = BASICFONT.render('Press a key to start.', True, DARKGRAY) pressKeyRect = pressKeySurf.get_rect() pressKeyRect.topleft = (WINDOWWIDTH - 200, WINDOWHEIGHT - 30) degrees1 = 0 degrees2 = 0 while True: MAINSURF.fill(BGCOLOR) rotatedSurf1 = pygame.transform.rotate(titleSurf1, degrees1) rotatedRect1 = rotatedSurf1.get_rect() rotatedRect.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2) MAINSURF.blit(rotatedSurf1, rotatedRect1) rotatedSurf2 = pygame.transform.rotate(titleSurf2, degrees2) rotatedRect2 = rotatedSurf2.get_rect() rotatedRect2.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2) MAINSURF.blit(rotatedSurf2, rotatedRect2) MAINSURF.blit(pressKeySurf, pressKeyRect) if checkForKeyPress(): return pygame.display.update() MAINCLOCK.tick(FPS) degrees1 += 3 degrees2 += 7 if degrees1 > 360: degrees1 -= 360 if degrees2 > 360: degrees2 -= 360 def checkForKeyPress(): for event in pygame.event.get(QUIT): terminate() for event in pygame.event.get(KEYUP): if event.key == K_ESCAPE: terminate() return event.key def terminate(): pygame.quit() sys.exit() def gameLoop(): startx = random.randint(5, CELLWIDTH - 6) starty = random.randint(5, CELLHEIGHT - 6) snakeCoords = [(startx, starty), (startx-1, starty)] direction = RIGHT apple = (random.randint(0, CELLWIDTH - 1), random.randint(0, CELLHEIGHT - 1)) while True: # get player input for event in pygame.event.get(): if event.type == QUIT: terminate() elif event.type == KEYDOWN: if (event.key == K_LEFT or event.key == K_a) and direction != RIGHT: direction = LEFT if (event.key == K_RIGHT or event.key == K_d) and direction != LEFT: direction = RIGHT if (event.key == K_UP or event.key == K_w) and direction != DOWN: direction = UP if (event.key == K_DOWN or event.key == K_s) and direction != UP: direction = DOWN if event.key == K_ESCAPE: terminate() # check if the snake has hit itself or the edge if snakeCoords[0][0] == -1 or snakeCoords[0][0] == CELLWIDTH or snakeCoords[0][1] == -1 or snakeCoords[0][1] == CELLHEIGHT: return for snakeBody in snakeCoords[1:]: if (snakeCoords[0][0], snakeCoords[0][1]) == snakeBody: return if snakeCoords[0][0] == apple[0] and snakeCoords[0][1] == apple[1]: apple = (random.randint(0, CELLWIDTH - 1), random.randint(0, CELLHEIGHT - 1)) else: snakeCoords.pop() # move the snake if direction == UP: snakeCoords.insert(0, (snakeCoords[0][0], snakeCoords[0][1] - 1)) elif direction == DOWN: snakeCoords.insert(0, (snakeCoords[0][0], snakeCoords[0][1] + 1)) elif direction == LEFT: snakeCoords.insert(0, (snakeCoords[0][0] - 1, snakeCoords[0][1])) elif direction == RIGHT: snakeCoords.insert(0, (snakeCoords[0][0] + 1, snakeCoords[0][1])) MAINSURF.fill(BGCOLOR) drawSnake(snakeCoords) drawApple(apple) drawScore(len(snakeCoords)) pygame.display.update() MAINCLOCK.tick(FPS) def showGameOverScreen(): gameOverFont = pygame.font.Font('freesansbold.ttf', 150) gameSurf = gameOverFont.render('Game', True, WHITE) overSurf = gameOverFont.render('Over', True, WHITE) gameRect = gameSurf.get_rect() overRect = overSurf.get_rect() gameRect.midtop = (WINDOWWIDTH / 2, 10) overRect.midtop = (WINDOWWIDTH / 2, gameRect.height + 10 + 25) MAINSURF.blit(gameSurf, gameRect) MAINSURF.blit(overSurf, overRect) pygame.display.update() time.sleep(0.5) checkForKeyPress() # clear out any key presses in the event queue made up to this point while True: if checkForKeyPress(): return def drawScore(score): scoreSurf = BASICFONT.render('Score: %s' % (score), True, WHITE) scoreRect = scoreSurf.get_rect() scoreRect.topleft = (WINDOWWIDTH - 80, 10) MAINSURF.blit(scoreSurf, scoreRect) """The drawScore() function simply displays the score""" def drawSnake(snakeCoords): for coord in snakeCoords: x = coord[0] * CELLSIZE y = coord[1] * CELLSIZE coordRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE) pygame.draw.rect(MAINSURF, GREEN, coordRect) def drawApple(coord): x = coord[0] * CELLSIZE y = coord[1] * CELLSIZE appleRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE) pygame.draw.rect(MAINSURF, RED, appleRect) if __name__ == '__main__': main()