一步步教你怎么用python写贪吃蛇游戏

系统 1948 0

目录
0 引言
1 环境
2 需求分析
3 代码实现
4 后记

0 引言

前几天,星球有人提到贪吃蛇,一下子就勾起了我的兴趣,毕竟在那个Nokia称霸的年代,这款游戏可是经典中的经典啊!而用Python(蛇)玩Snake(贪吃蛇),那再合适不过了

先通过下面这个效果图来感受下吧!
一步步教你怎么用python写贪吃蛇游戏_第1张图片

1 环境

操作系统:Windows

Python版本:3.7.3

2 需求分析

我们先来回顾下贪吃蛇中的游戏元素及游戏规则。

首先呢,需要有贪吃蛇、有食物;需要能控制贪吃蛇来上下移动获取食物;贪吃蛇在吃取食物后,自身长度增加,同时食物消失并随机生成新的食物;如果贪吃蛇触碰到四周墙壁或是触碰到自己身体时,则游戏结束。

游戏规则就是这么简单,接下来我们借助一个第三方库pygame来实现它。

Pygame是一个利用SDL库的游戏库, 是一组用来开发游戏软件的 Python 程序模块。

SDL(Simple DirectMedia Layer)是一个跨平台库,支持访问计算机多媒体硬件(声音、视频、输入等),SDL非常强大,但美中不足的是它是基于 C 语言的。

PyGame是 SDL 库的 Python 包装器(wrapper),Pygame 在SDL库的基础上提供了各种接口,从而使用用户能够使用python语言创建各种各样的游戏或多媒体程序。

它的安装方法很简单,如下:

pip install pygame

想要了解更多pygame功能的朋友也可以查阅官方的文档。

3 代码实现

首先导入我们要用到的模块,除了第三方库pygame外,我们还会用到一些Python内置的模块如sys、random、time等,一并导入即可。

            
              
                import
              
               pygame
              
                ,
              
               sys
              
                ,
              
               random
              
                ,
              
               time

              
                # 从pygame模块导入常用的函数和常量
              
              
                from
              
               pygame
              
                .
              
              
                locals
              
              
                import
              
              
                *
              
            
          

3.1 一些全局参数的初始化

接下来,我们需要声明一些全局参数。如初始化pygame、定义游戏窗口的大小、窗口的标题、定义全局的颜色变量等信息。

            
              
                # 初始化Pygame库
              
              
pygame
              
                .
              
              init
              
                (
              
              
                )
              
              
                # 初始化一个游戏界面窗口
              
              
DISPLAY 
              
                =
              
               pygame
              
                .
              
              display
              
                .
              
              set_mode
              
                (
              
              
                (
              
              
                640
              
              
                ,
              
              
                480
              
              
                )
              
              
                )
              
              
                # 设置游戏窗口的标题
              
              
pygame
              
                .
              
              display
              
                .
              
              set_caption
              
                (
              
              
                '人人都是Pythonista - Snake'
              
              
                )
              
              
                # 定义一个变量来控制游戏速度
              
              
FPSCLOCK 
              
                =
              
               pygame
              
                .
              
              time
              
                .
              
              Clock
              
                (
              
              
                )
              
              
                # 初始化游戏界面内使用的字体
              
              
BASICFONT 
              
                =
              
               pygame
              
                .
              
              font
              
                .
              
              SysFont
              
                (
              
              
                "SIMYOU.TTF"
              
              
                ,
              
              
                80
              
              
                )
              
              
                # 定义颜色变量
              
              
BLACK 
              
                =
              
               pygame
              
                .
              
              Color
              
                (
              
              
                0
              
              
                ,
              
              
                0
              
              
                ,
              
              
                0
              
              
                )
              
              
WHITE 
              
                =
              
               pygame
              
                .
              
              Color
              
                (
              
              
                255
              
              
                ,
              
              
                255
              
              
                ,
              
              
                255
              
              
                )
              
              
RED 
              
                =
              
               pygame
              
                .
              
              Color
              
                (
              
              
                255
              
              
                ,
              
              
                0
              
              
                ,
              
              
                0
              
              
                )
              
              
GREY 
              
                =
              
               pygame
              
                .
              
              Color
              
                (
              
              
                150
              
              
                ,
              
              
                150
              
              
                ,
              
              
                150
              
              
                )
              
            
          

3.2 初始化贪吃蛇及食物

游戏中需要有贪吃蛇及食物,我们给定一个初始值。我们将整个界面看成许多20*20的小方块,每个小方块代表一个标准小格子,贪吃蛇的长度就可以用几个标准小格子表示。我们将贪吃蛇身体用列表的形式存储,方便之后的删减。
‘’‘初始化贪吃蛇及食物’’’

            
              
                # 贪吃蛇的的初始位置
              
              
snake_Head 
              
                =
              
              
                [
              
              
                100
              
              
                ,
              
              
                100
              
              
                ]
              
              
                # 初始化贪吃蛇的长度 (注:这里以20*20为一个标准小格子)
              
              
snake_Body 
              
                =
              
              
                [
              
              
                [
              
              
                80
              
              
                ,
              
              
                100
              
              
                ]
              
              
                ,
              
              
                [
              
              
                60
              
              
                ,
              
              
                100
              
              
                ]
              
              
                ,
              
              
                [
              
              
                40
              
              
                ,
              
              
                100
              
              
                ]
              
              
                ]
              
              
                # 指定蛇初始前进的方向,向右
              
              
direction 
              
                =
              
              
                "right"
              
              
                # 给定第一枚食物的位置
              
              
food_Position 
              
                =
              
              
                [
              
              
                300
              
              
                ,
              
              
                300
              
              
                ]
              
              
                # 食物标记:0代表食物已被吃掉;1代表未被吃掉。
              
              
food_flag 
              
                =
              
              
                1
              
            
          

3.3 实现贪吃蛇的上下左右移动

我们需要控制贪吃蛇的上下左右的移动,这里通过监听键盘输入来实现。利用键盘中的上下左右键或WASD键来控制贪吃蛇的运动。

            
              
                # 检测按键等Pygame事件
              
              
                for
              
               event 
              
                in
              
               pygame
              
                .
              
              event
              
                .
              
              get
              
                (
              
              
                )
              
              
                :
              
              
                if
              
               event
              
                .
              
              
                type
              
              
                ==
              
               QUIT
              
                :
              
              
                # 接收到退出事件后,退出程序
              
              
        pygame
              
                .
              
              quit
              
                (
              
              
                )
              
              
        sys
              
                .
              
              exit
              
                (
              
              
                )
              
              
                # 判断键盘事件,用 方向键 或 wsad 来表示上下左右
              
              
                elif
              
               event
              
                .
              
              
                type
              
              
                ==
              
               KEYDOWN
              
                :
              
              
                if
              
              
                (
              
              event
              
                .
              
              key 
              
                ==
              
               K_UP 
              
                or
              
               event
              
                .
              
              key 
              
                ==
              
               K_w
              
                )
              
              
                and
              
               direction 
              
                !=
              
               DOWN
              
                :
              
              
            direction 
              
                =
              
               UP
        
              
                if
              
              
                (
              
              event
              
                .
              
              key 
              
                ==
              
               K_DOWN 
              
                or
              
               event
              
                .
              
              key 
              
                ==
              
               K_s
              
                )
              
              
                and
              
               direction 
              
                !=
              
               UP
              
                :
              
              
            direction 
              
                =
              
               DOWN
        
              
                if
              
              
                (
              
              event
              
                .
              
              key 
              
                ==
              
               K_LEFT 
              
                or
              
               event
              
                .
              
              key 
              
                ==
              
               K_a
              
                )
              
              
                and
              
               direction 
              
                !=
              
               RIGHT
              
                :
              
              
            direction 
              
                =
              
               LEFT
        
              
                if
              
              
                (
              
              event
              
                .
              
              key 
              
                ==
              
               K_RIGHT 
              
                or
              
               event
              
                .
              
              key 
              
                ==
              
               K_d
              
                )
              
              
                and
              
               direction 
              
                !=
              
               LEFT
              
                :
              
              
            direction 
              
                =
              
               RIGHT

            
          

接下来就是将蛇前进方向按照键盘的输入进行转弯操作,并将蛇的头部当前的位置加入到蛇身的列表中。

            
              
                # 根据键盘的输入,改变蛇的头部,进行转弯操作
              
              
                if
              
               direction 
              
                ==
              
               LEFT
              
                :
              
              
    snake_Head
              
                [
              
              
                0
              
              
                ]
              
              
                -=
              
              
                20
              
              
                if
              
               direction 
              
                ==
              
               RIGHT
              
                :
              
              
    snake_Head
              
                [
              
              
                0
              
              
                ]
              
              
                +=
              
              
                20
              
              
                if
              
               direction 
              
                ==
              
               UP
              
                :
              
              
    snake_Head
              
                [
              
              
                1
              
              
                ]
              
              
                -=
              
              
                20
              
              
                if
              
               direction 
              
                ==
              
               DOWN
              
                :
              
              
    snake_Head
              
                [
              
              
                1
              
              
                ]
              
              
                +=
              
              
                20
              
              
                # 将蛇的头部当前的位置加入到蛇身的列表中
              
              
snake_Body
              
                .
              
              insert
              
                (
              
              
                0
              
              
                ,
              
              
                list
              
              
                (
              
              snake_Head
              
                )
              
              
                )
              
            
          

3.4 判断是否吃到食物

如果蛇头与食物的位置重合,则判定吃到食物,将食物数量清零;而没吃到食物的话,蛇身就会跟着蛇头运动,蛇身的最后一节将被踢出列表。

            
              
                # 判断是否吃掉食物
              
              
                if
              
               snake_Head
              
                [
              
              
                0
              
              
                ]
              
              
                ==
              
              food_Position
              
                [
              
              
                0
              
              
                ]
              
              
                and
              
               snake_Head
              
                [
              
              
                1
              
              
                ]
              
              
                ==
              
              food_Position
              
                [
              
              
                1
              
              
                ]
              
              
                :
              
              
    food_flag 
              
                =
              
              
                0
              
              
                else
              
              
                :
              
              
    snake_Body
              
                .
              
              pop
              
                (
              
              
                )
              
            
          

3.5 重新生成食物

当游戏界面中的食物数量为0时,需要重新生成食物。利用random函数来生成随机位置

            
              
                # 生成新的食物
              
              
                if
              
               food_flag 
              
                ==
              
              
                0
              
              
                :
              
              
                # 随机生成x, y
              
              
    x 
              
                =
              
               random
              
                .
              
              randrange
              
                (
              
              
                1
              
              
                ,
              
              
                32
              
              
                )
              
              
    y 
              
                =
              
               random
              
                .
              
              randrange
              
                (
              
              
                1
              
              
                ,
              
              
                24
              
              
                )
              
              
    food_Position 
              
                =
              
              
                [
              
              
                int
              
              
                (
              
              x
              
                *
              
              
                20
              
              
                )
              
              
                ,
              
              
                int
              
              
                (
              
              y
              
                *
              
              
                20
              
              
                )
              
              
                ]
              
              
    food_flag 
              
                =
              
              
                1
              
            
          

3.6 绘制贪吃蛇、食物、分数等信息

定义贪吃蛇的绘制函数

            
              
                # 绘制贪吃蛇
              
              
                def
              
              
                drawSnake
              
              
                (
              
              snake_Body
              
                )
              
              
                :
              
              
                for
              
               i 
              
                in
              
               snake_Body
              
                :
              
              
        pygame
              
                .
              
              draw
              
                .
              
              rect
              
                (
              
              DISPLAY
              
                ,
              
               WHITE
              
                ,
              
               Rect
              
                (
              
              i
              
                [
              
              
                0
              
              
                ]
              
              
                ,
              
               i
              
                [
              
              
                1
              
              
                ]
              
              
                ,
              
              
                20
              
              
                ,
              
              
                20
              
              
                )
              
              
                )
              
              

定义食物的绘制函数

              
                # 绘制食物的位置
              
              
                def
              
              
                drawFood
              
              
                (
              
              food_Position
              
                )
              
              
                :
              
              
    pygame
              
                .
              
              draw
              
                .
              
              rect
              
                (
              
              DISPLAY
              
                ,
              
               RED
              
                ,
              
               Rect
              
                (
              
              food_Position
              
                [
              
              
                0
              
              
                ]
              
              
                ,
              
               food_Position
              
                [
              
              
                1
              
              
                ]
              
              
                ,
              
              
                20
              
              
                ,
              
              
                20
              
              
                )
              
              
                )
              
              

定义分数的绘制函数

              
                # 打印出当前得分
              
              
                def
              
              
                drawScore
              
              
                (
              
              score
              
                )
              
              
                :
              
              
                # 设置分数的显示颜色
              
              
    score_Surf 
              
                =
              
               BASICFONT
              
                .
              
              render
              
                (
              
              
                '%s'
              
              
                %
              
              
                (
              
              score
              
                )
              
              
                ,
              
              
                True
              
              
                ,
              
               GREY
              
                )
              
              
                # 设置分数的位置
              
              
    score_Rect 
              
                =
              
               score_Surf
              
                .
              
              get_rect
              
                (
              
              
                )
              
              
    score_Rect
              
                .
              
              midtop 
              
                =
              
              
                (
              
              
                320
              
              
                ,
              
              
                240
              
              
                )
              
              
                # 绑定以上设置到句柄
              
              
    DISPLAY
              
                .
              
              blit
              
                (
              
              score_Surf
              
                ,
              
               score_Rect
              
                )
              
            
          

这些都定义好之后,我们需要在游戏主逻辑中调用它们,并刷新Pygame的显示层,贪吃蛇与食物的每一次移动,都会进行刷新显示层的操作来显示。最后我们可以设定一个速度值来合理控制游戏执行的速度。

            
              DISPLAY
              
                .
              
              fill
              
                (
              
              BLACK
              
                )
              
              
                # 画出贪吃蛇
              
              
drawSnake
              
                (
              
              snake_Body
              
                )
              
              
                # 画出食物的位置
              
              
drawFood
              
                (
              
              food_Position
              
                )
              
              
                # 打印出玩家的分数
              
              
drawScore
              
                (
              
              
                len
              
              
                (
              
              snake_Body
              
                )
              
              
                -
              
              
                3
              
              
                )
              
              
                # 刷新Pygame的显示层,贪吃蛇与食物的每一次移动,都会进行刷新显示层的操作来显示。
              
              
pygame
              
                .
              
              display
              
                .
              
              flip
              
                (
              
              
                )
              
              
                # 控制游戏速度
              
              
FPSCLOCK
              
                .
              
              tick
              
                (
              
              
                7
              
              
                )
              
            
          

3.7 定义游戏结束的画面并判断游戏是否结束

定义函数,用于展示游戏结束的画面并退出程序

            
              
                # 游戏结束并退出
              
              
                def
              
              
                GameOver
              
              
                (
              
              
                )
              
              
                :
              
              
                # 设置GameOver的显示颜色
              
              
    GameOver_Surf 
              
                =
              
               BASICFONT
              
                .
              
              render
              
                (
              
              
                'Game Over!'
              
              
                ,
              
              
                True
              
              
                ,
              
               GREY
              
                )
              
              
                # 设置GameOver的位置
              
              
    GameOver_Rect 
              
                =
              
               GameOver_Surf
              
                .
              
              get_rect
              
                (
              
              
                )
              
              
    GameOver_Rect
              
                .
              
              midtop 
              
                =
              
              
                (
              
              
                320
              
              
                ,
              
              
                10
              
              
                )
              
              
                # 绑定以上设置到句柄
              
              
    DISPLAY
              
                .
              
              blit
              
                (
              
              GameOver_Surf
              
                ,
              
               GameOver_Rect
              
                )
              
              

    pygame
              
                .
              
              display
              
                .
              
              flip
              
                (
              
              
                )
              
              
                # 等待3秒
              
              
    time
              
                .
              
              sleep
              
                (
              
              
                3
              
              
                )
              
              
                # 退出游戏
              
              
    pygame
              
                .
              
              quit
              
                (
              
              
                )
              
              
                # 退出程序
              
              
    sys
              
                .
              
              exit
              
                (
              
              
                )
              
            
          

在游戏主逻辑中加入判断,游戏是否结束

            
              
                '''游戏结束的判断'''
              
              
                # 贪吃蛇触碰到边界
              
              
                if
              
               snake_Head
              
                [
              
              
                0
              
              
                ]
              
              
                <
              
              
                0
              
              
                or
              
               snake_Head
              
                [
              
              
                0
              
              
                ]
              
              
                >
              
              
                620
              
              
                :
              
              
    GameOver
              
                (
              
              
                )
              
              
                if
              
               snake_Head
              
                [
              
              
                1
              
              
                ]
              
              
                <
              
              
                0
              
              
                or
              
               snake_Head
              
                [
              
              
                1
              
              
                ]
              
              
                >
              
              
                460
              
              
                :
              
              
    GameOver
              
                (
              
              
                )
              
              
                # 贪吃蛇触碰到自己
              
              
                for
              
               i 
              
                in
              
               snake_Body
              
                [
              
              
                1
              
              
                :
              
              
                ]
              
              
                :
              
              
                if
              
               snake_Head
              
                [
              
              
                0
              
              
                ]
              
              
                ==
              
              i
              
                [
              
              
                0
              
              
                ]
              
              
                and
              
               snake_Head
              
                [
              
              
                1
              
              
                ]
              
              
                ==
              
              i
              
                [
              
              
                1
              
              
                ]
              
              
                :
              
              
        GameOver
              
                (
              
              
                )
              
            
          

4 后记

本文利用Pygame模块实现了最简单的贪吃蛇版本。当然还有很多需要优化的地方,比如随机生成食物时如何避免出现在贪吃蛇的自身上、通过贪吃蛇的长度来自动控制游戏速度等等。更高级一点的有如何通过AI自动玩贪吃蛇、贪吃蛇的双人对战等,期待大家利用Python可以把贪吃蛇玩出一个新的高度!

公众号「 Python专栏 」后台回复关键字「 贪吃蛇 」获取本文全套完整代码!


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论