pygame 做游戏之第四天
这篇主要是介绍了一个贪吃蛇的游戏制作过程,通过“上下左右”四个键控制贪吃蛇来进行移动,注释基本解释很清楚,有不懂的留言即可。
# **********************************************
# @Time : 2019/11/12 下午6:54
# @Author : Sam
# @File : game3.py
# @Software: PyCharm
# **********************************************
import pygame,sys,random
from pygame.locals import *
# 可以理解为贪吃蛇的移动速度
FPS = 5
# 游戏窗口的宽度
WINDOWWIDTH = 400
# 游戏窗口的高度
WINDOWHEIGHT = 400
# 游戏界面中每个格子尺寸
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.'
# 水平方向的格子数
X_NUM = int(WINDOWWIDTH/CELLSIZE)
# 垂直方向的格子数
Y_NUM = 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 showGameOverScreen():
# **********************************************
# @Description: 当游戏终止时的显示"game over",并在 2s 之后通过按任意键重新开始游戏
# @Time : 2019/11/13 上午11:25
# @Author : Sam
# @Name : showGameOverScreen
# **********************************************
gameoverFont = pygame.font.Font("/Users/wys/Desktop/fs_GB2312.ttf",60)
gameoverSurf = gameoverFont.render("game over",True,WHITE)
gameoverRect = gameoverSurf.get_rect()
gameoverRect.center = (int(WINDOWWIDTH/2),int(WINDOWHEIGHT/2))
DISPLAYSURF.blit(gameoverSurf,gameoverRect)
pygame.display.update()
pygame.time.wait(2000)
while True:
drawGird()
surf = BASICFONT.render("please press a key to continue", True, WHITE)
rect = surf.get_rect()
rect.center = ((WINDOWWIDTH / 2)+50, (WINDOWHEIGHT / 2)+50)
DISPLAYSURF.blit(surf, rect)
for event in pygame.event.get():
if event.type == KEYUP:
return
elif event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
FPSCLOCK.tick(FPS)
def main():
# **********************************************
# @Description: 游戏的主要入口,程序从这里开始执行,定义了游戏从开始到运行,再到游戏结束的顺序
# @Time : 2019/11/13 上午11:26
# @Author : Sam
# @Name : main
# **********************************************
global FPSCLOCK,DISPLAYSURF,BASICFONT
pygame.init()
FPSCLOCK = pygame.time.Clock()
DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH,WINDOWHEIGHT))
pygame.display.set_caption("game")
BASICFONT = pygame.font.Font("/Users/wys/Desktop/fs_GB2312.ttf",18)
showStart()
while True:
runGame()
showGameOverScreen()
def showStart():
# **********************************************
# @Description: 游戏开始时候界面显示"wormy!"的字样的动画效果,同时字体颜色会变化四次,如果关闭窗口则会终止程序
# @Time : 2019/11/13 上午11:27
# @Author : Sam
# @Name : showStart
# **********************************************
titleFont = pygame.font.Font("/Users/wys/Desktop/fs_GB2312.ttf",100)
titleSurf1 = titleFont.render("wormy!",True,WHITE)
titleSurf2 = titleFont.render("wormy!", True, GREEN)
for i in range(4):
titleSurf1,titleSurf2 = titleSurf2,titleSurf1
r = titleSurf1.get_rect()
r.center = (WINDOWWIDTH/2,WINDOWHEIGHT/2)
DISPLAYSURF.blit(titleSurf1,r)
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pygame.display.update()
pygame.time.wait(500)
def getRandomLocation():
# **********************************************
# @Description: 在窗口上获取一个随机的位置
# @Time : 2019/11/13 上午11:30
# @Author : Sam
# @Name : getRandomLocation
# **********************************************
return {'x':random.randint(0,X_NUM-1),'y':random.randint(0,Y_NUM-1)}
def drawGird():
# **********************************************
# @Description: 将游戏的背景网络状线条绘制出来
# @Time : 2019/11/13 上午11:30
# @Author : Sam
# @Name : drawGird
# **********************************************
for x in range(0,WINDOWWIDTH,CELLSIZE):
pygame.draw.line(DISPLAYSURF,DARKGRAY,(x,0),(x,WINDOWHEIGHT))
for y in range(0,WINDOWHEIGHT,CELLSIZE):
pygame.draw.line(DISPLAYSURF,DARKGREEN,(0,y),(WINDOWWIDTH,y))
def drawWorm(wormCoords):
# **********************************************
# @Description: 绘制贪吃蛇的样子
# @Time : 2019/11/13 上午11:31
# @Author : Sam
# @Name : drawWorm
# **********************************************
for coord in wormCoords:
x = coord['x'] * CELLSIZE
y = coord['y'] * CELLSIZE
wormSegmentR = pygame.Rect(x,y,CELLSIZE,CELLSIZE)
pygame.draw.rect(DISPLAYSURF, DARKGREEN, wormSegmentR)
def drawApple(coord):
# **********************************************
# @Description: 绘制处于某个位置的苹果
# @Time : 2019/11/13 上午11:31
# @Author : Sam
# @Name : drawApple
# **********************************************
x = coord['x'] * CELLSIZE
y = coord['y'] * CELLSIZE
appleRect = pygame.Rect(x,y,CELLSIZE,CELLSIZE)
pygame.draw.rect(DISPLAYSURF,RED,appleRect)
def drawScore(score):
# **********************************************
# @Description: 绘制在窗口显示的分数
# @Time : 2019/11/13 上午11:31
# @Author : Sam
# @Name : drawScore
# **********************************************
scoreSurf = BASICFONT.render("Score:%s"%(score),True,WHITE)
scoreRect = scoreSurf.get_rect()
scoreRect.topleft = (WINDOWWIDTH - 120 ,10)
DISPLAYSURF.blit(scoreSurf,scoreRect)
def runGame():
# **********************************************
# @Description: 定义了游戏的主要操作以及变化效果
# @Time : 2019/11/13 上午11:32
# @Author : Sam
# @Name : runGame
# **********************************************
# 随机定一个贪吃蛇在画面的出事位置
startx = random.randint(5, X_NUM - 6)
starty = random.randint(5, Y_NUM - 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:
pygame.quit()
sys.exit()
# 分别定义了操控"上下左右"四个方向的按键所产生的变化
elif event.type == KEYDOWN:
if event.key == K_LEFT and direction != RIGHT:
direction = LEFT
elif event.key == K_RIGHT and direction != LEFT:
direction = RIGHT
elif event.key == K_UP and direction != DOWN:
direction = UP
elif event.key == K_DOWN and direction != UP:
direction = DOWN
elif event.key == K_ESCAPE:
pygame.quit()
sys.exit()
# 如果贪吃蛇碰到窗口边缘则终止游戏
if wormCoords[HEAD]['x'] == -1 or wormCoords[HEAD]['x'] == X_NUM or wormCoords[HEAD]['y'] == '-1' or wormCoords[HEAD]['y'] == Y_NUM:
return
# 如果贪吃蛇自己的头碰到身子则终止游戏
for wormBody in wormCoords[1:]:
if wormBody['x'] == wormCoords[HEAD]['x'] and wormBody['y'] == wormCoords[HEAD]['y']:
return
# 如果贪吃蛇的头碰到苹果的位置
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 == RIGHT:
newHead = {'x':wormCoords[HEAD]['x']+1,'y':wormCoords[HEAD]['y']}
elif direction == LEFT:
newHead = {'x':wormCoords[HEAD]['x']-1,'y':wormCoords[HEAD]['y']}
# 移动时候,每帧把新的头插入到贪吃蛇的第一个索引的位置
wormCoords.insert(0,newHead)
DISPLAYSURF.fill(BGCOLOR)
# 画背景格子
drawGird()
# 画贪吃蛇
drawWorm(wormCoords)
# 画苹果
drawApple(apple)
# 画分数
drawScore(len(wormCoords)-3)
# 更新画面
pygame.display.update()
# 设置帧数
FPSCLOCK.tick(FPS)
if __name__ == '__main__':
main()
效果图如下: