首先,一开始先上个程序运行的结果图
********************************核心模块********************************
核心的模块分为三个部分:1、显示游戏模块;2、游戏运行模块;3、游戏结束模块。
一、显示游戏模块
1、先设置游戏窗口的大小,我设置为640*480的窗口大小,然后设置每一个单元格的大小(必须得能够被640*480整除)
2、绘制游戏开始的界面,等待事件的输入
3、显示游戏开始画面的函数showStartScreen
def showStartScreen():
DISPLAYSURF.fill(BGCOLOR)
titleFont = pygame.font.SysFont('PAPYRUS.ttf',100)
titleSurf = titleFont.render('Wormy!',True,GREEN)
titleRect = titleSurf.get_rect()
titleRect.center = (windowWidth/2,windowHeight/2)
DISPLAYSURF.blit(titleSurf,titleRect)
drawPressKeyMsg()
pygame.display.update()
while True:
if checkForKeyPress():
pygame.event.get()
return
①填充背景颜色
②设置游戏开始是显示在窗口上的文字
③设置文字在窗口上边的位置,titleSurf.get_rect(),创建一个矩形对象,she设置了矩形对象的属性值Center在320,240
④DisplaySurf.blit()将对象显示出来,调用pygame.display.update()让显示窗口对象显示在屏幕上
⑤在窗口上边显示提示信息,用到了方法drawPressKeyMsg()
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)
方法逻辑类似上边
⑥获取按键事件进入到游戏界面,里边的检查按键对象的方法checkFOrKeyPress()
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
二、游戏开始模块
1、显示游戏运行的主函数runGame()
详细注释中有说明逻辑过程
def runGame():
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
apple = getRandomLocation() # 随机设置苹果的位置,占一个单元格
while True: # 游戏主循环体
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
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 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 # 碰到自己游戏结束
if wormCoords[HEAD]['x'] == apple['x'] and wormCoords[HEAD]['y'] == apple['y']:
apple = getRandomLocation()
else:
del wormCoords[-1]
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)
DISPLAYSURF.fill(BGCOLOR)
drawWorm(wormCoords) # 将蛇绘制出来
drawApple(apple) # 绘制苹果
drawScore(len(wormCoords)-3) #绘制分数
pygame.display.update()
FPSCLOCK.tick(FPS) #设置动画每一秒的帧数
三、游戏结束模块
1、游戏结束模块的主要方法是showGameOverScreen()
def showGameOverScreen():
gameOverFont = pygame.font.SysFont('PAPYRUS.ttf',50)
gameSurf = gameOverFont.render('Game',True,WHITE)
overSurf = gameOverFont.render('Over',True,WHITE)
gameRect = gameSurf.get_rect()
overRect = gameSurf.get_rect()
gameRect.midtop = (windowWidth/2,windowHeight/2-gameRect.height-10)
overRect.midtop = (windowWidth/2,windowWidth/2)
DISPLAYSURF.blit(gameSurf,gameRect)
DISPLAYSURF.blit(overSurf,overRect)
drawPressKeyMsg()
pygame.display.update()
pygame.display.update()
pygame.time.wait(500)
checkForKeyPress()
while True:
if checkForKeyPress():
pygame.event.get()
return
①方法逻辑与显示游戏开始界面类似,先设置窗口显示文字的样式和位置和提示信息
②获取按键事件,按任意按键进入下一次游戏
四、运行的主要方法
游戏运行和三个模块的主要方法放在了main()方法里边,在main()方法中设置了一个死循环,在游戏运行画面和结束画面中,没有退出按键事件的时候,将循环进行游戏
全部代码显示如下:
import random,sys,time,pygame
from pygame.locals import *
FPS = 5
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)
# 定义几个常用的颜色
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 = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
# 贪吃蛇的头
HEAD = 0
def main():
global FPSCLOCK,DISPLAYSURF,BASICFONT
pygame.init()
FPSCLOCK = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((windowWidth, windowHeight))
BASICFONT = pygame.font.SysFont('PAPYRUS.ttf', 18)
pygame.display.set_caption('Wormy')
showStartScreen() # 显示游戏开始的画面
while True:
runGame() # 运行游戏
showGameOverScreen() # 显示游戏结束画面
def runGame():
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
apple = getRandomLocation() # 随机设置苹果的位置,占一个单元格
while True: # 游戏主循环体
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
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 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 # 碰到自己游戏结束
if wormCoords[HEAD]['x'] == apple['x'] and wormCoords[HEAD]['y'] == apple['y']:
apple = getRandomLocation()
else:
del wormCoords[-1]
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)
DISPLAYSURF.fill(BGCOLOR)
drawWorm(wormCoords) # 将蛇绘制出来
drawApple(apple) # 绘制苹果
drawScore(len(wormCoords)-3) #绘制分数
pygame.display.update()
FPSCLOCK.tick(FPS) #设置动画每一秒的帧数
# 绘制提示消息
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():
DISPLAYSURF.fill(BGCOLOR)
titleFont = pygame.font.SysFont('PAPYRUS.ttf',100)
titleSurf = titleFont.render('Wormy!',True,GREEN)
titleRect = titleSurf.get_rect()
titleRect.center = (windowWidth/2,windowHeight/2)
DISPLAYSURF.blit(titleSurf,titleRect)
drawPressKeyMsg()
pygame.display.update()
while True:
if checkForKeyPress():
pygame.event.get()
return
# 退出
def terminate():
pygame.quit()
sys.exit()
# 随机生成一个坐标位置
def getRandomLocation():
return {'x':random.randint(0,cellWidth-1),'y':random.randint(0,cellHeight-1)}
#显示游戏结束的画面
def showGameOverScreen():
gameOverFont = pygame.font.SysFont('PAPYRUS.ttf',50)
gameSurf = gameOverFont.render('Game',True,WHITE)
overSurf = gameOverFont.render('Over',True,WHITE)
gameRect = gameSurf.get_rect()
overRect = gameSurf.get_rect()
gameRect.midtop = (windowWidth/2,windowHeight/2-gameRect.height-10)
overRect.midtop = (windowWidth/2,windowWidth/2)
DISPLAYSURF.blit(gameSurf,gameRect)
DISPLAYSURF.blit(overSurf,overRect)
drawPressKeyMsg()
pygame.display.update()
pygame.display.update()
pygame.time.wait(500)
checkForKeyPress()
while True:
if checkForKeyPress():
pygame.event.get()
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)
# 根据wormCoords数组绘制贪吃蛇
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)
# 根据 coord 绘制 apple
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 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()