文档章节

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

上海小胖
 上海小胖
发布于 06/27 07:00
字数 1987
阅读 50
收藏 4

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

0 引言

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

先通过下面这个效果图来感受下吧! 在这里插入图片描述

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专栏」后台回复关键字「贪吃蛇」获取本文全套完整代码!

© 著作权归作者所有

上海小胖
粉丝 10
博文 45
码字总数 56174
作品 0
杨浦
技术主管
私信 提问
【C/C++】10分钟教你用C++写一个贪吃蛇附带AI功能(附源代码详解和下载)

C++编写贪吃蛇小游戏快速入门 刚学完C++。一时兴起,就花几天时间手动做了个贪吃蛇,后来觉得不过瘾,于是又加入了AI功能。希望大家Enjoy It. 效果图示 AI模式演示 整体规划+原理 大体上可以...

短短的路走走停停
2018/07/29
0
0
菜鸟学Python,上半年文章大汇总

一晃大半年过去了,时间过的真快啊!上半年我一共发表了原创的文章有近45篇,其中有一些是粉丝投稿的!后台总有人留言说查找历史文章不方便,怎么办?为了方便大家阅读,我把上半年的原创文章...

菜鸟学python
2018/06/24
0
0
拿下斯坦福和剑桥双offer,00后的算法学习之路

董文馨,00后,精通英语,西班牙语。斯坦福大学计算机系和剑桥大学双Offer,秋季将进入斯坦福大学学习。 10岁开始在国外上学;12岁学Scratch; 13岁学HTML & CSS; 14岁开始学Python & Java...

AI科技大本营
03/12
0
0
在 Linux 终端中玩贪吃蛇

有了这个 20 世纪 70 年代的经典重制游戏,Python 将不再是你在 Linux 终端能发现的唯一的“蛇”。 欢迎回到 Linux 命令行玩具日历。如果这是你第一次访问该系列,你可能会问什么是命令行玩具...

作者: Jason Baker
01/12
0
0
Make Games with Python & Pygame (4)

从现在开始,就是具体游戏的制作了。作者是每章一个游戏,有些游戏我不是很感兴趣,只对其中有兴趣,所以就只讲这一些。 第一个游戏就是贪吃蛇游戏,说起这个游戏,这可能是我玩的最早的游戏...

NightCode
2015/04/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

马蜂窝 IM 系统架构的演化和升级

今天,越来越多的用户被马蜂窝持续积累的笔记、攻略、嗡嗡等优质的分享内容所吸引,在这里激发了去旅行的热情,同时也拉动了马蜂窝交易的增长。在帮助用户做出旅行决策、完成交易的过程中,I...

马蜂窝技术
27分钟前
2
0
C++学习笔记:C/C++中static关键词有用途

C语言中:static关键词有三种用途 1.静态局部变量 特点: 该变量在全局数据区分配内存(局部变量在栈区分配内存) 静态局部变量在程序执行到该对象的声明处时被首次初始化,以后不会再进行初...

StupidZhe
27分钟前
2
0
Mysql Group Replication关闭和启动所有的组成员的注意点

Mysql Group Replication关闭和启动所有的组成员的注意点 2018年05月17日 11:45:02 zuozhiji 阅读数 1772 由于的我mgr建立在虚拟机上面(即使是正式环境,如果计划内的停机或者断电都需要关闭...

rootliu
31分钟前
2
0
并发模式与 RPS 模式之争,性能压测领域的星球大战

本文是《如何做好性能压测》系列专题分享的第四期,该专题将从性能压测的设计、实现、执行、监控、问题定位和分析、应用场景等多个纬度对性能压测的全过程进行拆解,以帮助大家构建完整的性能...

阿里云官方博客
32分钟前
2
0
iTOP-4412开发板基于Linux-C测试程序的编译和运行

iTOP-4412 开发板可以运行的文件系统很多,在具体的文件系统上实现特定功能前,可 以使用 Linux-C 程序来测试硬件以及驱动。而且这些程序很容易移植到 Android、Qt/E 以及 最小文件系统上。 ...

书白
33分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部