pygame 做游戏之第四天

493 阅读4分钟

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()

效果图如下: