教你一步步利用python实现贪吃蛇游戏


Posted in Python onJune 27, 2019

0 引言

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

先通过下面这个效果图来感受下吧!

教你一步步利用python实现贪吃蛇游戏

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 相关文章推荐
Python编写简单的HTML页面合并脚本
Jul 11 Python
python中的字典使用分享
Jul 31 Python
Python读取MRI并显示为灰度图像实例代码
Jan 03 Python
Pandas 对Dataframe结构排序的实现方法
Apr 10 Python
解决python报错MemoryError的问题
Jun 26 Python
Django中日期处理注意事项与自定义时间格式转换详解
Aug 06 Python
Python操作MySQL数据库的两种方式实例分析【pymysql和pandas】
Mar 18 Python
pandas通过字典生成dataframe的方法步骤
Jul 23 Python
Python列表的切片实例讲解
Aug 20 Python
pytorch实现onehot编码转为普通label标签
Jan 02 Python
在jupyter notebook 添加 conda 环境的操作详解
Apr 10 Python
python实现xlwt xlrd 指定条件给excel行添加颜色
Jul 14 Python
Python中遍历列表的方法总结
Jun 27 #Python
Python 把序列转换为元组的函数tuple方法
Jun 27 #Python
Python使用numpy模块实现矩阵和列表的连接操作方法
Jun 26 #Python
Python 实现交换矩阵的行示例
Jun 26 #Python
对numpy下的轴交换transpose和swapaxes的示例解读
Jun 26 #Python
Python用Try语句捕获异常的实例方法
Jun 26 #Python
python调用自定义函数的实例操作
Jun 26 #Python
You might like
初学CAKEPHP 基础教程
2009/11/02 PHP
php selectradio和checkbox默认选择的实现方法详解
2013/06/29 PHP
深入解析PHP 5.3.x 的strtotime() 时区设定 警告信息修复
2013/08/05 PHP
PHP 反射(Reflection)使用实例
2015/05/12 PHP
PHP开发APP端微信支付功能
2017/02/17 PHP
PHP+MySQL实现输入页码跳转到指定页面功能示例
2018/06/01 PHP
PHP7创建COOKIE和销毁COOKIE的实例方法
2020/02/03 PHP
JQuery 初体验(建议学习jquery)
2009/04/25 Javascript
Jquery实现简单的动画效果代码
2012/03/18 Javascript
node.js正则表达式获取网页中所有链接的代码实例
2014/06/03 Javascript
JavaScript字符串对象toLowerCase方法入门实例(用于把字母转换为小写)
2014/10/17 Javascript
Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
jQuery中$.click()无效问题分析
2015/01/29 Javascript
JS实现网页标题随机显示名人名言的方法
2015/11/03 Javascript
CSS或者JS实现鼠标悬停显示另一元素
2016/01/22 Javascript
JS操作COOKIE实现备忘记录的方法
2016/04/01 Javascript
在Vuex使用dispatch和commit来调用mutations的区别详解
2018/09/18 Javascript
vue车牌号校验和银行校验实战
2019/01/23 Javascript
解决VUE 在IE下出现ReferenceError: Promise未定义的问题
2020/11/07 Javascript
[59:44]2018DOTA2亚洲邀请赛 3.31 小组赛 B组 paiN vs iG
2018/03/31 DOTA
[09:47]2018DOTA2亚洲邀请赛4.5SOLO赛 No[o]ne vs Sumail
2018/04/06 DOTA
python+selenium实现自动化百度搜索关键词
2019/06/03 Python
python获取响应某个字段值的3种实现方法
2020/04/30 Python
Python用K-means聚类算法进行客户分群的实现
2020/08/23 Python
SEPHORA新西兰官方网站:购买化妆品和护肤品
2016/12/02 全球购物
美国手工艺品市场的领导者:Annie’s
2019/04/04 全球购物
Laura官网:加拿大女性的顶级时尚目的地
2019/09/20 全球购物
公司端午节活动方案
2014/02/04 职场文书
2014年公司庆元旦活动方案
2014/03/05 职场文书
党员评议表自我评价范文
2014/10/20 职场文书
个人欠款协议书范本2014
2014/11/02 职场文书
给老婆的保证书
2015/01/16 职场文书
vue基于Teleport实现Modal组件
2021/05/31 Vue.js
pytorch 两个GPU同时训练的解决方案
2021/06/01 Python
实例讲解Python中sys.argv[]的用法
2021/06/03 Python
HTML中实现音乐或视频自动播放案例详解
2022/05/30 HTML / CSS