当前位置 博文首页 > 一条IT:【python实战】用pygame做个贪吃蛇游戏

    一条IT:【python实战】用pygame做个贪吃蛇游戏

    作者:[db:作者] 时间:2021-08-13 12:47

    嗨,大家好,我是一条。

    告诉大家一个好消息,一条IT访问量突破20w,达到申请博客专家的条件。感谢大家的支持,一条会创作更多的优质内容。

    为了让更多的人看到一条的分享,一条准备报名原力计划,报名条件是粉丝数超过2000

    所以一条现在非常需要大家的关注,如果觉得一条写的还可以,就点个关注再走吧!

    等粉丝数达到2000时,一条给大家在微信准备一个抽奖,奖品暂定键盘和手环二选一,关注微信公众号就可以参与。


    ?

    今天一条整体的工作比较轻松,对公司的一些流程也比较熟悉了,所以给大家也准备个比较轻松的东西。

    用pygame带大家用半小时做一款童年游戏——贪吃蛇

    先看下成品:视频传送门

    话不多说,我们开干!冲冲冲!

    ?一、pygame预热

    有些同学可能还不太了解pygame,所以先简单介绍一下,会的同学可以跳过这一部分。

    pygame是基于python编写的图形化编程库,可以使程序运行在各种平台。同时学习起来也非常简单,我们直接上案例。

    1.安装pygame

    pygame库的安装非常简单,基本不会出问题

    pip install pygame
    
    import pygame
    #中文字符
    import pygame.freetype

    2.基础案例

    简单介绍一下pygame的几个用法,直接跟着代码和注释操作一下,简单了解就可以。

    • 初始化一个窗口,并设置其属性
    import pygame
    
    # 初始化pygame
    pygame.init()
    # 创建pygame显示层
    screen=pygame.display.set_mode((1000,600))
    pygame.display.set_caption("贪吃蛇")
    • 将窗口定格住
    import pygame
    
    # 初始化pygame
    pygame.init()
    # 创建pygame显示层
    screen=pygame.display.set_mode((1000,600))
    # 设置窗口的标题
    pygame.display.set_caption("贪吃蛇")
    while True:
        # 绘制绿色
        screen.fill((0,255,0))
        # 更新画面
        pygame.display.update()
    • 增加退出按钮
    import pygame
    import sys
    # 初始化pygame
    pygame.init()
    # 创建pygame显示层
    screen=pygame.display.set_mode((1000,600))
    # 设置窗口的标题
    pygame.display.set_caption("贪吃蛇")
    while True:
        # 绘制绿色
        screen.fill((0,255,0))
        # 监听事件:键盘 鼠标 窗口退出事件
        for event in pygame.event.get():
            # 退出
            if event.type ==256:
                pygame.QUIT
                sys.exit()
        # 更新画面
        pygame.display.update()
    • 绘制一个图形
    import pygame
    import sys
    # 初始化pygame
    pygame.init()
    # 创建pygame显示层
    screen=pygame.display.set_mode((1000,600))
    # 设置窗口的标题
    pygame.display.set_caption("贪吃蛇")
    while True:
        # 绘制绿色
        screen.fill((0,255,0))
        #绘制矩形
        b = pygame.draw.rect(screen, (255, 255, 255), [20, 20, 20, 20], 0)
        # 监听事件:键盘 鼠标 窗口退出事件
        for event in pygame.event.get():
            # 退出
            if event.type ==256:
                pygame.QUIT
                sys.exit()
        # 更新画面
        pygame.display.update()
    • 让图形动起来,其实就相当于动画片,每一帧变换一下方块绘制的位置,连起来看就是动画
    import pygame
    import sys
    # 初始化pygame
    pygame.init()
    # 创建pygame显示层
    screen=pygame.display.set_mode((1000,600))
    # 设置窗口的标题
    pygame.display.set_caption("贪吃蛇")
    # 获取帧率控制器
    clock=pygame.time.Clock()
    
    x, y = 0, 0  # 方块的起点
    width, height = 20, 20  # 方块的宽,高
    while True:
        # 绘制绿色
        screen.fill((0,255,0))
        # 画方块
        a = pygame.draw.rect(screen, (255, 0, 0), (x, y, width, height))
        # 改变位置
        x+=2
        y+=3
        # 监听事件:键盘 鼠标 窗口退出事件
        for event in pygame.event.get():
            # 退出
            if event.type ==256:
                pygame.QUIT
                sys.exit()
        # 更新画面
        pygame.display.update()
        # 设置速度
        clock.tick(15)

    这样,一个简单的动画就做好了,如果要做成贪吃蛇,还需要加上逻辑判断和事件处理。

    那我们就正式开始做游戏。

    二、正式开干

    基于以上的了解,我们思考一下实现这个游戏的思路

    1. 首先需要一个窗口,将蛇和食物画在这个窗口上,即正方形块
    2. 通过变换位置让蛇动起来
    3. 让蛇可以上下左右转弯
    4. 在蛇和食物的位置重合时,让蛇吃点食物,同时蛇增长,分数增加(核心部分)
    5. 刷新食物的位置
    6. 死亡判定
    7. 扩展:增加暂停,增加重新开始,增加背景音乐,打包成exe文件

    万事俱备,只欠东风。开始吧

    1.画蛇和食物

    • 初始化蛇头,蛇身,得分的位置坐标,蛇的前进方向,食物是否被吃,游戏是否结束
    #位置信息
    head=[100,0]
    snake=[
        [100,0],[80,0],[60,0]
    ]
    food=[500,300]
    socer=0
    iseat=False
    isover=False
    goahead="R"
    
    
    • 绘制以上信息
    import pygame
    import sys
    from pygame.locals import *
    import pygame.freetype
    import random
    import time
    
    pygame.init()
    
    screen=pygame.display.set_mode((1000,600))
    pygame.display.set_caption("snake")
    
    clock = pygame.time.Clock()
    while True:
        screen.fill((0, 0, 0))
        f1 = pygame.freetype.SysFont("fangsong", 24)
        f1rect = f1.render_to(screen, (860,20), "得分:"+str(socer), fgcolor=(225,225,225))
        for i in snake:
            pygame.draw.rect(screen, (255, 0, 0), (i[0],i[1], 20, 20))
        pygame.draw.rect(screen, (164, 167, 220), (food[0],food[1] , 20, 20))
        pygame.display.update()
        clock.tick(15)

    2.让蛇动起来

    动起来的核心就是把整条蛇看作一个列表,因为蛇的长度是不变的,只是位置的坐标的变化,所以增加一个头元素,删除一个尾元素,蛇就前进了一步。

    #最初的前进方向
    goahead="R"
    
     # 各个移动方向的坐标的改变
        if(goahead == "R"):
            head[0]+=20
        elif(goahead=="L"):
            head[0]-=20
        elif(goahead=="U"):
            head[1]-=20
        elif(goahead=="D"):
            head[1]+=20
    snake.insert(0, list(head))
    snake.pop()

    3.蛇转弯

    转弯其实是对键盘按键的就监听和行进方向的改变。如果目前是向右,那么按上键,行进方向改为上,下键改为下。以此类推。

    # 监听事件:键盘 鼠标 窗口退出事件
        for event in pygame.event.get():
            # 退出
            if event.type == QUIT:
                pygame.QUIT
                sys.exit()
            # 键盘按下
            if event.type==pygame.KEYDOWN:
                # 转向
                if event.key == pygame.K_LEFT:
                    if (goahead=="D" or goahead=="U"):
                        goahead="L"
                elif event.key == pygame.K_RIGHT:
                    if (goahead=="D" or goahead=="U"):
                        goahead="R"
                elif event.key == pygame.K_UP:
                    if (goahead=="L" or goahead=="R"):
                        goahead="U"
                elif event.key == pygame.K_DOWN:
                    if (goahead=="L" or goahead=="R"):
                        goahead="D"

    4.蛇吃食物

    这里只需判断食物的坐标和蛇头的坐标是否重合,因为一定是蛇头先吃到食物,如果存在,蛇吃到了食物长大一个长度,即尾元素不需要删除,同时得分增加,食物的坐标清空。

        snake.insert(0, list(head))
        # 验证食物是否被吃
        if(food==head):
            iseat=True
            socer+=5
        # 抛出上一个位置
        elif(goahead!="T"):
            snake.pop()

    5.刷新食物

    如果食物被吃掉,那要随机生成食物的坐标,同时要保证一下两点:

    • 新的坐标和旧的不重合
    • 新的坐标不能生成在蛇身内
    # 食物随机出现
        # 随机在重复位置
        if(iseat==True):
            while True:
                insnake=True
                food[0]=random.randint(1,42)*20
                food[1]=random.randint(1,28)*20
                for i in snake:
                    if(food==i):
                        insnake=False
                if(insnake):
                    break
            iseat=False

    6.死亡判定

    • 第一种死亡情况:自杀式 即蛇头的坐标出现在蛇身内
    # 自杀
        for i in snake[1:]:
            if(head==i):
                isover=True
    • 第一种死亡情况:撞墙式,也可以设置成无边界,则此死亡方式不存在。
     # 无边界
        # if(head[0]>1000):
        #     head[0]=0
        # if (head[0] <0):
        #     head[0] = 1000
        # if (head[1] > 600):
        #     head[1] = 0
        # if (head[1] < 0):
        #     head[1] = 600
    
        # 撞墙
        if(head[0]>1000 or head[0]<0 or head[1]>600 or head[1]<0):
            isover=True
    

    游戏结束的展示

    if(isover):
            f2=pygame.freetype.SysFont("arial",72)
            f2.render_to(screen,(350,150),"Game Over",fgcolor=(150,150,150))
            # 更新当前画面
            pygame.display.update()
            time.sleep(5)
            pygame.quit()
            sys.exit()

    三、打完收工

    最后在教大家如何打包成exe

    1.安装pyinstaller

    pip install pyinstaller

    2.打包

    #pyinstaller -F -w  filepath+filename
    pyinstaller -F -w  ./main.py

    ?

    到此,我们简单的贪吃蛇游戏就做完了,上面提到的扩展功能一条已全部完成,即视频展示的样子。

    此处就不再讲解,需要的同学【点赞,关注,收藏】后私信一条领取源码。

    ?


    我是一条,一个在互联网摸爬滚打的程序员。

    微信搜【一条IT】关注我。第一时间获取文章推送。

    道阻且长,行则将至。大家的?【点赞,收藏,关注】?就是一条创作的最大动力,我们下期见!

    注:关于本篇博客有任何问题和建议,欢迎大家留言!

    ?

    ?

    ?

    ?

    cs