首页 > 编程笔记 > Python笔记

Python实例:贪吃蛇游戏

相信对读者来说,贪吃蛇游戏已经不新鲜了,这一经典的益智游戏早已风靡世界多年。

典型的贪吃蛇游戏的主界面如图 1 所示。

贪吃蛇小游戏的主界面
图 1:贪吃蛇小游戏的主界面

其游戏规则是:玩家使用上下左右键控制绿色的“蛇”在窗口中游走并吃掉(触碰)红色的“苹果”来得分,每吃一个“苹果”,“蛇”也将变长一些。如果“蛇头”碰到了窗口的四壁,或是与自身相撞,游戏结束。整个界面由若干方格构成,“蛇”游走的过程实际上是在不同的方格中连续绘制和擦除“蛇”的图形的过程。

根据游戏规则整理出的游戏流程如图 2 所示。

贪吃蛇小游戏的游戏流程
图 2:贪吃蛇小游戏的游戏流程

根据流程图,与 2048 小游戏类似,贪吃蛇游戏程序大致也可分为三个部分:
  1. 程序初始化;
  2. 判断用户输入;
  3. 进入游戏主循环。

其中第三部分可以继续细分为以下三个部分:
  1. 判断操作并处理;
  2. 判断是否吃到“苹果”;
  3. 重新开始或退出。

为了游戏界面效果美观,同样使用了 pygame 模块。首先来看程序初始化,这里主要完成以下工作:导入所需模块,初始化窗口界面,初始化各种组件和变量。代码如下:
#“蛇”移动的速度,数值越大速度越快
Snakespeed = 10
#窗口宽度和高度
Window_Width = 800
Window_Height = 500
#每个格子的宽度和高度
Cell_Size = 20

assert Window_Width % Cell_Size == 0, "窗口宽度必须是格子宽度的整数倍"
assert Window_Height % Cell_Size ==0, "窗口高度必须是格子高度的整数倍"
Cell W = int(Window Width / Cell_Size) # Cell Width
Cell_H = int(Window_Height / Cell_Size)  # Celle Height

#定义游戏用到的颜色值
White = (255, 255, 255)
Black = (0, 0, 0)
Red = (255, 0, 0)
Green = (0, 255, 0)
DARKGreen = (0, 155, 0)
DARKGRAY = (40, 40, 40)
YELLOW = (255, 255, 0)
Red_DARK = (150, 0, 0)
BLUE = (0, 0, 255)
BLUE_DARK = (0, 0, 150)
BGCOLOR = Black

#定义游戏用到的控制键
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'

HEAD = 0
#定义游戏字体
FONTNAME = "SimHei"

判断用户输入是通过执行 showStartScreen( ) 函数实现的,其代码如下:
def showStartScreen():
    while True:
        drawPressKeyMsg()

    if checkForKeyPress ():
        pygame.event.get()
        return
    pygame.display.update()

def drawPressKeyMsg():
    pressKey Surf = BASICFONT.render('按任意键开始游戏', True, White)
    pressKeyRect = pressKeySurf.get_rect()
    pressKeyRect.topleft = (Window_Width - 200, Window_Height - 30)
    DISPLAYSURF.blit(pressKeySurf, pressKeyRect)

可见,贪吃蛇也是通过无限循环实现的,依然使用了事件机制获取用户输入,当用户按下任意键时跳出循环,向下执行。

游戏主循环是通过 runGame( ) 函数实现的,其代码如下:
def runGame():
#随机选取“蛇”的起始位置
    startx = random.randint(5, Cell_W - 6)
    starty = random.randint(5, Cell_H - 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(): # event handling loop
            if event.type == QUIT:
                terminate()
            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:
                    terminate()

    #检测“蛇”是否撞到自身或窗口边缘
    if wormCoords[HEAD] ['x'] == -1 or wormCoords [HEAD] ['x'] == Cell_W or wormCoords[HEAD] ['y'] == -1 or wormCoords[HEAD] ['y'] == Cell_H:
        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)
    drawGrid()
    drawWorm(wormCoords)
    drawApple(apple)
    drawScore(len(wormCoords) - 3)
    pygame.display.update()
    SnakespeedCLOCK.tick(Snakespeed)

当“蛇”撞到自身或窗口边缘时,游戏结束,此时将执行 showGameOverScreen( ) 函数,其代码如下:
def showGameOverScreen():
    gameOverFont = pygame.font.SysFont(FONTNAME, 100)
    gameSurf = gameOverFont.render('游戏', True, White)
    overSurf = gameOverFont.render('结束', True, White)
    gameRect = gameSurf.get_rect()
    overRect = overSurf.get_rect()
    gameRect.midtop = (Window_Width / 2, 80)
    overRect.midtop = (Window_Width / 2, gameRect.height + 50 + 25)
    DISPLAYSURF.blit(gameSurf, gameRect)
    DISPLAYSURF.blit (overSur, 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
至此,小游戏贪吃蛇的主要内容和关键代码介绍完毕。

所有教程

优秀文章