Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Wormy (a Nibbles clone)
- # By Al Sweigart al@inventwithpython.com
- # http://inventwithpython.com/pygame
- # Released under a "Simplified BSD" license
- import random
- import pygame
- import sys
- import time
- from pygame.locals import *
- FPS = 15
- WINDOWWIDTH = 640
- WINDOWHEIGHT = 480
- CELLSIZE = 20
- assert WINDOWWIDTH % CELLSIZE == 0, "Window width must be a multiple of cell size."
- assert WINDOWHEIGHT % CELLSIZE == 0, "Window height must be a multiple of cell size."
- CELLWIDTH = int(WINDOWWIDTH / CELLSIZE)
- CELLHEIGHT = int(WINDOWHEIGHT / CELLSIZE)
- TIMEOUT = 5
- SECOND_WORM_TIMEOUT = 5 # should be 45
- # R G B
- WHITE = (255, 255, 255)
- BLACK = (0, 0, 0)
- RED = (255, 0, 0)
- GREEN = (0, 255, 0)
- DARKGREEN = (0, 155, 0)
- DARKGRAY = (40, 40, 40)
- BLUE = (0, 0, 255)
- DARKBLUE = (0, 0, 155)
- BGCOLOR = BLACK
- RED_DARK = (196, 0, 0)
- RED_FLASH = (255, 75, 75)
- UP = 'up'
- DOWN = 'down'
- LEFT = 'left'
- RIGHT = 'right'
- HEAD = 0 # syntactic sugar: index of the worm's head
- def main():
- global FPSCLOCK, DISPLAYSURF, BASICFONT, TIMEOUT
- pygame.init()
- FPSCLOCK = pygame.time.Clock()
- DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))
- BASICFONT = pygame.font.Font('freesansbold.ttf', 18)
- pygame.display.set_caption('Wormy')
- showStartScreen()
- while True:
- runGame()
- showGameOverScreen()
- def runGame():
- # Set a random start point.
- startx = random.randint(5, CELLWIDTH - 6)
- starty = random.randint(5, CELLHEIGHT - 6)
- wormCoords = [{'x': startx, 'y': starty},
- {'x': startx - 1, 'y': starty},
- {'x': startx - 2, 'y': starty}]
- direction = RIGHT
- # Start the apple in a random place.
- apple = getRandomLocation()
- score = 0
- timeFrame = time.time()
- secondWormTimeFrom = time.time()
- secondWormInitialised = False
- wormCoordsSecond = []
- secondWormTimeout = 1
- flashyApples = []
- while True: # main game loop
- for event in pygame.event.get(): # event handling loop
- if event.type == QUIT:
- terminate()
- elif event.type == KEYDOWN:
- if (event.key == K_LEFT or event.key == K_a) and direction != RIGHT:
- direction = LEFT
- elif (event.key == K_RIGHT or event.key == K_d) and direction != LEFT:
- direction = RIGHT
- elif (event.key == K_UP or event.key == K_w) and direction != DOWN:
- direction = UP
- elif (event.key == K_DOWN or event.key == K_s) and direction != UP:
- direction = DOWN
- elif event.key == K_ESCAPE:
- terminate()
- if secondWormInitialised:
- directionSecond = getDirectionSecondWorm(oldDirection=directionSecond)
- if not secondWormInitialised and secondWormTimeFrom + SECOND_WORM_TIMEOUT <= time.time():
- # set random start point for the second worm
- startxSecond = random.randint(5, CELLWIDTH - 6)
- startySecond = random.randint(5, CELLHEIGHT - 6)
- wormCoordsSecond = [{'x': startxSecond, 'y': startySecond},
- {'x': startxSecond - 1, 'y': startySecond},
- {'x': startxSecond - 2, 'y': startySecond}]
- directionSecond = getDirectionSecondWorm()
- secondWormInitialised = True
- # check if the worm has hit itself or the edge
- if wormCoords[HEAD]['x'] == -1 or wormCoords[HEAD]['x'] == CELLWIDTH or wormCoords[HEAD]['y'] == -1 or \
- wormCoords[HEAD]['y'] == CELLHEIGHT:
- return # game over
- for wormBody in wormCoords[1:]:
- if wormBody['x'] == wormCoords[HEAD]['x'] and wormBody['y'] == wormCoords[HEAD]['y']:
- return # game over
- # check if worm has eaten an apply
- if wormCoords[HEAD]['x'] == apple['x'] and wormCoords[HEAD]['y'] == apple['y']:
- score += 1
- # don't remove worm's tail segment
- apple = getRandomLocation() # set a new apple somewhere
- else:
- del wormCoords[-1] # remove worm's tail segment
- if checkFlashyApple(wormCoords, flashyApples):
- score += 2
- # move the worm by adding a segment in the direction it is moving
- newHead = {}
- if direction == UP:
- newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] - 1}
- elif direction == DOWN:
- newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] + 1}
- elif direction == LEFT:
- newHead = {'x': wormCoords[HEAD]['x'] - 1, 'y': wormCoords[HEAD]['y']}
- elif direction == RIGHT:
- newHead = {'x': wormCoords[HEAD]['x'] + 1, 'y': wormCoords[HEAD]['y']}
- wormCoords.insert(0, newHead)
- if timeFrame + TIMEOUT <= time.time():
- flashyApples = getFlashyApples()
- timeFrame = time.time()
- if secondWormInitialised:
- availableDirections = [LEFT, RIGHT, UP, DOWN]
- changeDirection = False
- if wormCoordsSecond[HEAD]['x'] <= 0:
- availableDirections.pop(availableDirections.index(LEFT))
- changeDirection = True
- if wormCoordsSecond[HEAD]['x'] >= CELLWIDTH - 1:
- availableDirections.pop(availableDirections.index(RIGHT))
- changeDirection = True
- if wormCoordsSecond[HEAD]['y'] <= 0:
- availableDirections.pop(availableDirections.index(UP))
- changeDirection = True
- if wormCoordsSecond[HEAD]['y'] >= CELLHEIGHT - 1:
- availableDirections.pop(availableDirections.index(DOWN))
- changeDirection = True
- if changeDirection:
- directionSecond = getDirectionSecondWorm(availableDirections)
- runSecondWorm(wormCoordsSecond, directionSecond)
- drawGame(wormCoords, apple, flashyApples, score, wormCoordsSecond)
- FPSCLOCK.tick(FPS)
- def getDirectionSecondWorm(possibleDirections=[UP, RIGHT, DOWN, LEFT], oldDirection=''):
- # if oldDirection == UP and DOWN in possibleDirections:
- # possibleDirections.pop(possibleDirections.index(DOWN))
- #
- # if oldDirection == DOWN and UP in possibleDirections:
- # possibleDirections.pop(possibleDirections.index(UP))
- #
- # if oldDirection == LEFT and RIGHT in possibleDirections:
- # possibleDirections.pop(possibleDirections.index(RIGHT))
- #
- # if oldDirection == RIGHT and LEFT in possibleDirections:
- # possibleDirections.pop(possibleDirections.index(LEFT))
- return possibleDirections[random.randrange(len(possibleDirections))]
- def runSecondWorm(wormCoords=[], direction=''):
- newHead = {}
- if direction == UP:
- newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] - 1}
- elif direction == DOWN:
- newHead = {'x': wormCoords[HEAD]['x'], 'y': wormCoords[HEAD]['y'] + 1}
- elif direction == LEFT:
- newHead = {'x': wormCoords[HEAD]['x'] - 1, 'y': wormCoords[HEAD]['y']}
- elif direction == RIGHT:
- newHead = {'x': wormCoords[HEAD]['x'] + 1, 'y': wormCoords[HEAD]['y']}
- wormCoords.insert(0, newHead)
- del wormCoords[-1]
- def drawGame(wormCoords, apple, flashyApples=[], score=0, wormCoordsSecond=[]):
- DISPLAYSURF.fill(BGCOLOR)
- drawGrid()
- drawWorm(wormCoords)
- drawSecondWorm(wormCoordsSecond)
- drawApple(apple)
- drawScore(score)
- drawFlashyApples(flashyApples)
- pygame.display.update()
- def drawPressKeyMsg():
- pressKeySurf = BASICFONT.render('Press a key to play.', True, DARKGRAY)
- pressKeyRect = pressKeySurf.get_rect()
- pressKeyRect.topleft = (WINDOWWIDTH - 200, WINDOWHEIGHT - 30)
- DISPLAYSURF.blit(pressKeySurf, pressKeyRect)
- def checkForKeyPress():
- if len(pygame.event.get(QUIT)) > 0:
- terminate()
- keyUpEvents = pygame.event.get(KEYUP)
- if len(keyUpEvents) == 0:
- return None
- if keyUpEvents[0].key == K_ESCAPE:
- terminate()
- return keyUpEvents[0].key
- def showStartScreen():
- titleFont = pygame.font.Font('freesansbold.ttf', 100)
- titleSurf1 = titleFont.render('Wormy!', True, WHITE, DARKGREEN)
- titleSurf2 = titleFont.render('Wormy!', True, GREEN)
- degrees1 = 0
- degrees2 = 0
- while True:
- DISPLAYSURF.fill(BGCOLOR)
- rotatedSurf1 = pygame.transform.rotate(titleSurf1, degrees1)
- rotatedRect1 = rotatedSurf1.get_rect()
- rotatedRect1.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2)
- DISPLAYSURF.blit(rotatedSurf1, rotatedRect1)
- rotatedSurf2 = pygame.transform.rotate(titleSurf2, degrees2)
- rotatedRect2 = rotatedSurf2.get_rect()
- rotatedRect2.center = (WINDOWWIDTH / 2, WINDOWHEIGHT / 2)
- DISPLAYSURF.blit(rotatedSurf2, rotatedRect2)
- drawPressKeyMsg()
- if checkForKeyPress():
- pygame.event.get() # clear event queue
- return
- pygame.display.update()
- FPSCLOCK.tick(FPS)
- degrees1 += 3 # rotate by 3 degrees each frame
- degrees2 += 7 # rotate by 7 degrees each frame
- def terminate():
- pygame.quit()
- sys.exit()
- def getRandomLocation():
- return {'x': random.randint(0, CELLWIDTH - 1), 'y': random.randint(0, CELLHEIGHT - 1)}
- def getFlashyApples():
- flashyApples = []
- for i in range(3):
- flashyApples.append({
- 'x': random.randint(0, CELLWIDTH - 1),
- 'y': random.randint(0, CELLHEIGHT - 1)
- })
- return flashyApples
- def checkFlashyApple(snake=[], apples=[]):
- for apple in apples:
- if snake[HEAD]['x'] == apple['x'] and snake[HEAD]['y'] == apple['y']:
- apples.pop(apples.index(apple))
- return True
- 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)
- DISPLAYSURF.blit(gameSurf, gameRect)
- DISPLAYSURF.blit(overSurf, overRect)
- drawPressKeyMsg()
- pygame.display.update()
- pygame.time.wait(500)
- checkForKeyPress() # clear out any key presses in the event queue
- while True:
- if checkForKeyPress():
- pygame.event.get() # clear event queue
- return
- def drawScore(score):
- scoreSurf = BASICFONT.render('Score: %s' % (score), True, WHITE)
- scoreRect = scoreSurf.get_rect()
- scoreRect.topleft = (WINDOWWIDTH - 120, 10)
- DISPLAYSURF.blit(scoreSurf, scoreRect)
- def drawWorm(wormCoords):
- for coord in wormCoords:
- x = coord['x'] * CELLSIZE
- y = coord['y'] * CELLSIZE
- wormSegmentRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
- pygame.draw.rect(DISPLAYSURF, DARKGREEN, wormSegmentRect)
- wormInnerSegmentRect = pygame.Rect(x + 4, y + 4, CELLSIZE - 8, CELLSIZE - 8)
- pygame.draw.rect(DISPLAYSURF, GREEN, wormInnerSegmentRect)
- def drawSecondWorm(wormCoords):
- for coord in wormCoords:
- x = coord['x'] * CELLSIZE
- y = coord['y'] * CELLSIZE
- wormSegmentRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
- pygame.draw.rect(DISPLAYSURF, DARKBLUE, wormSegmentRect)
- wormInnerSegmentRect = pygame.Rect(x + 4, y + 4, CELLSIZE - 8, CELLSIZE - 8)
- pygame.draw.rect(DISPLAYSURF, BLUE, wormInnerSegmentRect)
- def drawApple(coord):
- x = coord['x'] * CELLSIZE
- y = coord['y'] * CELLSIZE
- appleRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
- pygame.draw.rect(DISPLAYSURF, RED, appleRect)
- def drawFlashyApples(coords):
- for coord in coords:
- x = coord['x'] * CELLSIZE
- y = coord['y'] * CELLSIZE
- flashyAppleRect = pygame.Rect(x, y, CELLSIZE, CELLSIZE)
- if int(time.time() * 10 % 10) % 2 == 0:
- color = RED_DARK
- else:
- color = RED_FLASH
- pygame.draw.rect(DISPLAYSURF, color, flashyAppleRect)
- def drawGrid():
- for x in range(0, WINDOWWIDTH, CELLSIZE): # draw vertical lines
- pygame.draw.line(DISPLAYSURF, DARKGRAY, (x, 0), (x, WINDOWHEIGHT))
- for y in range(0, WINDOWHEIGHT, CELLSIZE): # draw horizontal lines
- pygame.draw.line(DISPLAYSURF, DARKGRAY, (0, y), (WINDOWWIDTH, y))
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement