• 如何用Pygame制作简单的贪吃蛇游戏


    本文首发于行者AI

    1.序言

    目前基本上软测会用到的工具或者第三方库都已经被写完,本着不要逮着一只羊进行薅羊毛原则,换个赛道,这次就使用pygame库写个简单的贪吃蛇吧,当做熟悉python练手也是不错的。

    2.安装与导入

    使用pip install pygame进入安装,安装成功后导入所需模块:

    import pygame,sys,random
    from pygame.locals import *
    

    其中sys为要在后续中使用它的退出程序机制所以在这里需要导入。

    3.定义后续需要的参数

    #初始化pygame库
    pygame.init()
    

    在用pygame时,初始化库是必须的,对应后面的退出代码,这两个是一对的。

    #初始化一个游戏界面
    DISPLAY=pygame.display.set_mode((800,800))
    #设置游戏窗口标题
    pygame.display.set_caption('贪吃蛇')
    

    在写完以上代码后,点击运行是会有一闪而过的界面,这是正常的,因为没有任何东西在运行。

    #定义一个变量控制游戏速度
    FPSCLOCK=pygame.time.Clock()
    
    #定义颜色
    BLACK=pygame.Color(0,0,0)
    WHITE=pygame.Color(255,255,255)
    RED=pygame.Color(255,0,0)
    
    # 定义蛇头初始位置
    snake_Head=[100,100]
    # 定义一个蛇初始长度,因为界面都是20*20所以长度都是减20
    snake_Body=[[80,100], [60,100]]
    # # 蛇初始方向
    direction="right"
    # 定义改变方向的变量,按键
    changeDirection = direction
    #定义初始食物位置
    food_Postion = [300,300]
    # 定义食物状态,0表示被吃,1表示没有被吃
    food_Total = 1
    

    以上都是在定义后续会用到的参数。

    4.绘制蛇与食物

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

    上面的pygame.draw.rect(DISPLAY,RED,Rect(food_Postion[0],food_Postion[1],20,20)) draw是pygame的绘制模块,rect中DISPLAY是在我们设置的游戏界面上绘制颜色、所绘制矩形的区域、矩形的宽度和高度。

    5.游戏规则与运行

    def gameover():
        #退出pygame
        pygame.quit()
        #退出程序
        sys.exit()
    

    这里设置的退出与上文中的pygame.init() 对应。

    game_flag=True
    while game_flag:
        #渲染底色
        DISPLAY.fill(BLACK)
        #画出贪吃蛇
        drawSnake(snake_Body)
        #画出食物位置
        drawFood(food_Postion)
    

    这里将背景设置成了黑色,与定义颜色中的设置对应,将蛇与食物的位置也与上文中对应 。

        #增加游戏速度
        game_speed=1+len(snake_Body)//3
        #刷新显示层,贪吃蛇与食物每次移动,都会刷新显示层
        pygame.display.flip()
        FPSCLOCK.tick(game_speed)
        for event in pygame.event.get():
            if event.type==QUIT:
                pygame.quit()
                sys.exit()
    

    这里规定了游戏的速度,与后续吃到食物后的移速增加。

            elif event.type == KEYDOWN:
                # 如果是右箭头或者是d,蛇向右移动
                if event.key == K_RIGHT or event.key == K_d:
                    changeDirection = 'right'
                # 如果是做箭头或者是a,蛇向左移动
                if event.key == K_LEFT or event.key == K_a:
                    changeDirection = 'left'
                if event.key == K_UP or event.key == K_w:
                    changeDirection = 'up'
                if event.key == K_DOWN or event.key == K_s:
                    changeDirection = 'down'
                # 点击esc,退出
                if event.key == KSCAN_ESCAPE:
                    pygame.event.post(pygame.event.Event(QUIT))
    
        # 确认方向,判断是否输入了反方向
        if changeDirection == 'right' and not direction == 'left':
            direction = changeDirection
        if changeDirection == 'left' and not direction == 'right':
            direction = changeDirection
        if changeDirection == 'up' and not direction == 'down':
            direction = changeDirection
        if changeDirection == 'down' and not direction == 'up':
            direction = changeDirection
    
        #根据方向移动蛇头
        if direction=='right':
            snake_Head[0]+=20
        if direction=='left':
            snake_Head[0]-=20
        if direction=='up':
            snake_Head[1]-=20
        if direction=='down':
            snake_Head[1]+=20
    

    注意这里引号里面的单词要与蛇初始方向的单词一致,不然在运行时会出问题
    if changeDirection == 'right' and not direction == 'left': 意思是可以使用“→”或者“D”进行右的移动,下面也是
    if changeDirection == 'right' and not direction == 'left':意思是如果在右行走的时候按“A”或者“←”是没有效果的,下面也是
    if direction=='right':snake_Head[0]+=20 意思是点击“→”或者“D”向右移动一格,因为格子是20*20的所以一格是20

         #增加蛇的长度
        snake_Body.insert(0,list(snake_Head))
         #判断是否吃到食物
        if snake_Head[0] == food_Postion[0] and snake_Head[1] == food_Postion[1]:
            food_Total = 0
        else:
            snake_Body.pop() 
    

    snake_Body.pop()意思是如果没有吃到就不再新增加食物,如果没有这句代码,会导致蛇没有吃到食物也在增加长度。

        if food_Total == 0:
            x = random.randrange(1, 32)
            y = random.randrange(1, 24)
            food_Postion = [int(x * 20), int(y * 20)]
            food_Total = 1
    

    这里的意思为如果食物被吃了,状态为0的话,就随机地点生成一个。

        if snake_Head[0] > 800 or snake_Head[0] < 0:
            gameover()
        elif snake_Head[0] > 800 or snake_Head[0] < 0:
            gameover()
            # 如果碰到自己
        for body in snake_Body[1:]:
            if snake_Head[0] == body[0] and snake_Head[1] == body[1]:
                gameover()
    

    if snake_Head[0] > 800 or snake_Head[0] < 0:意思为碰到边界游戏退出,800是全面设置的界面大小

    6.成品展示

    7.完整代码

    import pygame,sys,random
    from pygame.locals import *
    
    #初始化pygame库
    pygame.init()
    #初始化一个游戏界面
    DISPLAY=pygame.display.set_mode((800,800))
    #设置游戏窗口标题
    pygame.display.set_caption('贪吃蛇')
    
    #定义一个变量控制游戏速度
    FPSCLOCK=pygame.time.Clock()
    
    #定义颜色
    BLACK=pygame.Color(0,0,0)
    WHITE=pygame.Color(255,255,255)
    RED=pygame.Color(255,0,0)
    
    # 定义蛇头初始位置
    snake_Head=[100,100]
    # 定义一个蛇初始长度,因为界面都是20*20所以长度都是减20
    snake_Body=[[80,100], [60,100],[40,100]]
    # # 蛇初始方向
    direction="right"
    # 定义改变方向的变量,按键
    changeDirection = direction
    #定义初始食物位置
    food_Postion = [300,300]
    # 定义食物状态,0表示被吃,1表示没有被吃
    food_Total = 1
    
    #绘制贪吃蛇
    def drawSnake(snake_Body):
        for i in snake_Body:
            pygame.draw.rect(DISPLAY,WHITE,Rect(i[0],i[1],20,20))
    
    #绘制食物位置
    def drawFood(food_Postion):
        pygame.draw.rect(DISPLAY,RED,Rect(food_Postion[0],food_Postion[1],20,20))
    
    def gameover():
        #退出pygame
        pygame.quit()
        #退出程序
        sys.exit()
    
    
    game_flag=True
    while game_flag:
        #渲染底色
        DISPLAY.fill(BLACK)
        #画出贪吃蛇
        drawSnake(snake_Body)
        #画出食物位置
        drawFood(food_Postion)
        #增加游戏速度
        game_speed=1+len(snake_Body)//3
        #刷新显示层,贪吃蛇与食物每次移动,都会刷新显示层
        pygame.display.flip()
        FPSCLOCK.tick(game_speed)
        for event in pygame.event.get():
            if event.type==QUIT:
                pygame.quit()
                sys.exit()
    
            elif event.type == KEYDOWN:
                # 如果是右箭头或者是d,蛇向右移动
                if event.key == K_RIGHT or event.key == K_d:
                    changeDirection = 'right'
                # 如果是做箭头或者是a,蛇向左移动
                if event.key == K_LEFT or event.key == K_a:
                    changeDirection = 'left'
                if event.key == K_UP or event.key == K_w:
                    changeDirection = 'up'
                if event.key == K_DOWN or event.key == K_s:
                    changeDirection = 'down'
                # 点击esc,退出
                if event.key == KSCAN_ESCAPE:
                    pygame.event.post(pygame.event.Event(QUIT))
    
        # 确认方向,判断是否输入了反方向
        if changeDirection == 'right' and not direction == 'left':
            direction = changeDirection
        if changeDirection == 'left' and not direction == 'right':
            direction = changeDirection
        if changeDirection == 'up' and not direction == 'down':
            direction = changeDirection
        if changeDirection == 'down' and not direction == 'up':
            direction = changeDirection
    
        #根据方向移动蛇头
        if direction=='right':
            snake_Head[0]+=20
        if direction=='left':
            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))
        #判断是否吃到食物
        if snake_Head[0] == food_Postion[0] and snake_Head[1] == food_Postion[1]:
            food_Total = 0
        else:
            snake_Body.pop()
    
        if food_Total == 0:
            x = random.randrange(1, 32)
            y = random.randrange(1, 24)
            food_Postion = [int(x * 20), int(y * 20)]
            food_Total = 1
    
        if snake_Head[0] > 800 or snake_Head[0] < 0:
            gameover()
        elif snake_Head[0] > 800 or snake_Head[0] < 0:
            gameover()
            # 如果碰到自己
        for body in snake_Body[1:]:
            if snake_Head[0] == body[0] and snake_Head[1] == body[1]:
                gameover()
    

    我们是行者AI,我们在“AI+游戏”中不断前行。

    618期间产品套餐推出活动,前往公众号 【行者AI】,和我们一起探讨技术问题吧!

  • 相关阅读:
    Unity3D移动端海水的实时绘制
    NGUI 3.x 深度管理及渲染优化
    【入门】从学生到成熟:游戏模块设计起步之抽象思维 (转)
    正弦波近似 http://blog.csdn.net/ring0hx/article/details/44492415
    Stack 栈 ----Queue 队列
    ORM
    CBV&FBV
    Django路由系统
    CRM
    深浅拷贝
  • 原文地址:https://www.cnblogs.com/xingzheai/p/16363501.html
Copyright © 2020-2023  润新知