python贪吃蛇_python贪吃蛇
# 一、先展示python贪吃蛇效果
![python snake](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/py_snake/py_snake.gif)
## 二、操作说明
|按键|功能|
|:---:|:---:|
|UP|向上移动|
|DOWN|向下移动|
|LEFT|向左移动|
|RIGHT|向右移动|
|空格|暂停/继续|
|F1|加速|
|F2|减速|
|F3|开启/关闭无敌模式|
|ESC|退出游戏|
## 三、游戏说明
本教程使用python实现了一个简易的贪吃蛇游戏,为了让更多人能体会到python给我们带来的方便和乐趣,本教程源代码包含了详细的注释,同时也采用了更简单和易于理解的方式来实现贪吃蛇游戏.
游戏开始时,会生成 一个 ***位置随机长度为5的蛇*** (蛇头红色,蛇身绿色),一个 ***位置随机的食物*** (红色),和一堵 ***位置随机的长度最大为5的墙*** (黑色).
游戏运行过程中,可以通过 ***方向键*** 控制蛇移动来吃掉食物,每吃掉一个食物蛇身长度加1,每吃掉 ***10*** 个食物游戏速度加快一个等级,并且增加一堵位置随机长度最大为5的墙,以增加游戏难度.
蛇移动过程中咬到自身或撞到墙就会死亡,游戏自动退出.当然,也可以开启 ***无敌模式*** ,让小蛇尽情的畅游.
## 四、源码详解
本游戏的源码共分为三个模块: ***game模块*** , ***window模块*** , ***snake模块***.
### 1、window模块
本模块用于实现游戏界面的绘制和窗口事件的检测.
本模块提供了 ***clear(清屏)*** , ***update(刷新)*** , ***rect(画矩形)*** , ***circle(画圆)*** , ***event(事件检测)*** 等接口.
本模块的功能主要使用pygame模块实现,是对pygame的进一步封装.
#### **clear**
用指定颜色填充背景,并且绘制游戏地图方格,游戏地图是一个由横向40个方格,纵向20个方格组成的方阵
```py
'''
用背景色填充屏幕(清屏)
'''
def clear(self):
color = self._color_sub(self.COLOR_WHITE, self.gw_bgcol)
self._game_window.fill(self.gw_bgcol)
for x in range(self.maxx()+1):
pygame.draw.line(self._game_window, color, (x*self.pnt_size, 0), (x*self.pnt_size, self.gw_height), 1)
for y in range(self.maxy()+1):
pygame.draw.line(self._game_window, color, (0, y * self.pnt_size), (self.gw_width, y*self.pnt_size), 1)
```
#### **update**
pygame的update,刷新屏幕
```py
'''
刷新屏幕
'''
def update(self):
pygame.display.update()
```
#### **rect**
往地图上的指定位置的小方格中画一个矩形,这里使用的坐标不是屏幕坐标,而是小方格在地图中的坐标( *_rect是对pygame的draw.rect的封装,使用的是屏幕坐标* )
```py
'''
在屏幕指定位置画一个正方形(相对坐标)
Parameters
:param x: 正方形左上角的x坐标
:param y: 正方形左上角的y坐标
:param color: 圆形填充颜色
'''
def rect(self, x, y, *color):
pntcol = self.pnt_col
if len(color) != 0:
pntcol = color[0]
if x < 0 or x > self.maxx() or y < 0 or y > self.maxy():
return
self._rect(x*self.pnt_size, y*self.pnt_size, pntcol)
```
#### **circle**
往地图上的指定位置的小方格中画一个圆形,这里使用的坐标不是屏幕坐标,而是小方格在地图中的坐标( *_circle是对pygame的draw.circle的封装,使用的是屏幕坐标* )
```py
'''
在屏幕指定位置画一个圆形(相对坐标)
Parameters
:param x: 圆形外接正方形左上角的x坐标
:param y: 圆形外接正方形左上角的y坐标
:param color: 圆形填充颜色
'''
def circle(self, x, y, *color):
pntcol = self.pnt_col
if len(color) != 0:
pntcol = color[0]
if x < 0 or x > self.maxx() or y < 0 or y > self.maxy():
return
x = x*self.pnt_size
y = y*self.pnt_size
self._circle(x, y, x+self.pnt_size, y+self.pnt_size, pntcol)
```
#### **event**
检按键按下的事件,是对pygame的event的封装,把按键按下的状态封装成事件
```py
'''
屏幕事件
'''
def event(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
return self.EVENT_QUIT
elif event.type == pygame.KEYDOWN: # KEYUP:
if event.key == pygame.K_LEFT or event.key == pygame.K_a:
return self.EVENT_KLEFT
elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
return self.EVENT_KRIGHT
elif event.key == pygame.K_UP or event.key == pygame.K_w:
return self.EVENT_KUP
elif event.key == pygame.K_DOWN or event.key == pygame.K_s:
return self.EVENT_KDOWN
elif event.key == pygame.K_SPACE:
return self.EVENT_STOP
elif event.key == pygame.K_F1:
return self.EVENT_ADD
elif event.key == pygame.K_F2:
return self.EVENT_SUB
elif event.key == pygame.K_ESCAPE:
return self.EVENT_QUIT
elif event.key == pygame.K_F3:
return self.EVENT_KING
return self.EVENT_NONE
```
### 2、snake模块
本模块使用最简单的方法实现了贪吃蛇原理, 包含贪吃蛇的初始化,贪吃蛇的移动和碰撞检测,食物的生成,强的生成,贪吃蛇地图,贪吃蛇的绘制等.
#### **\_\_init\_\_**
贪吃蛇模块的初始化,创建了用于保存贪吃蛇蛇身,贪吃蛇地图的 ***list*** ,以及其他要用到的变量.
```py
def __init__(self, s_len=5, s_width=40, s_height=20): # (640/20 - 1, 480/20 -1)
self.s_width = s_width
self.s_height = s_height
self.s_life = self.SNAKE_LIFE
self._dir = self.DIR_RIGHT
self.s_king = False # 无敌模式
self.s_list = [] # 保存贪吃蛇蛇身坐标(s_list[0]保存食物,s_list[1]保存蛇头,其他保存蛇身)
self.s_wall = [] # 保存墙的坐标
self._create_wall() # 创建一堵墙, 强的位置随机, 方向随机, 长度最大为5
self.s_map = self._map_create(self.BODY_NONE) # 保存贪吃蛇地图,所有的游戏元素都要填充到地图中,然后统一绘制到屏幕上
# create a food, food = list[0]
_s_food = self._create_body() # 创建一个随机的坐标,标记为食物
self.s_list.append(_s_food)
# creat a head, head = list[1]
self._s_head = self._create_body() # 创建一个随机的坐标,标记为蛇头
self.s_list.append(self._s_head)
# create body and add body to list
for _ in range(s_len-1): # 蛇身的坐标通过蛇头的坐标和蛇的方向计算得来
self._s_head = (self._s_head[0]-1, self._s_head[1])
self.s_list.append(self._s_head)
# print(self.s_list)
self.s_score = 0 # len(self.s_list) # 游戏得分,吃一个食物得一分
```
#### **draw** 和 **show**
draw用于把所有的游戏元素:食物,蛇头,蛇身,墙按照其坐标填充到地图中, 地图是一个二维的 ***list***, 形如 ***s_map[x][y]***
show用于把贪吃蛇地图绘制到屏幕上,并刷新屏幕,这样贪吃蛇就显示出来了.show需要使用一个window对象来进行屏幕操作
```py
'''
绘制食物和蛇(把地图绘制到屏幕上)
:param pen: window对象
'''
def show(self, pen):
pen.clear()
self.draw()
for x in range(self.s_width):
for y in range(self.s_height):
if self.s_map[x][y] != self.BODY_NONE:
if self.s_map[x][y] == self.BODY_FOOD:
pen.circle(x, y, pen.COLOR_BLUE) # draw food
if self.s_map[x][y] == self.BODY_HEAD:
pen.rect(x, y, pen.COLOR_RED) # draw head
if self.s_map[x][y] == self.BODY_SNAKE:
pen.rect(x, y, pen.COLOR_GREEN) # draw snake
if self.s_map[x][y] == self.BODY_WALL:
pen.rect(x, y, pen.COLOR_BLACK) # draw snake
pen.update()
'''
把蛇和食物放在地图中
'''
def draw(self):
x = 0
y = 0
self._map_init(self.s_map, self.BODY_NONE)
if len(self.s_list) != 0:
x = self.s_list[0][0]
y = self.s_list[0][1]
if x >= 0 and x < self.s_width and y >= 0 and y < self.s_height:
self.s_map[x][y] = self.BODY_FOOD # draw food
x = self.s_list[1][0]
y = self.s_list[1][1]
if x >= 0 and x < self.s_width and y >= 0 and y < self.s_height:
self.s_map[x][y] = self.BODY_HEAD # draw head
for s in range(2, len(self.s_list)): # draw snake
x = self.s_list[s][0]
y = self.s_list[s][1]
if x >= 0 and x < self.s_width and y >= 0 and y < self.s_height:
self.s_map[x][y] = self.BODY_SNAKE
if len(self.s_wall) != 0:
for w in self.s_wall:
x = w[0]
y = w[1]
if x >= 0 and x < self.s_width and y >= 0 and y < self.s_height:
self.s_map[x][y] = self.BODY_WALL
```
#### **move**
用于贪吃蛇的移动,移动过程中会进行碰撞检测,如果撞到食物,则吃掉食物并产生一个新的食物,同时蛇身长度增加,游戏得分增加.如果撞到自己,或撞到墙,则蛇死亡. 没调用一个move,贪吃蛇移动一步,一般把move和show放到一个单独的线程中不断运行.
```py
'''
移动蛇
:param dir: 蛇移动方向
'''
def move(self, dir=DIR_RIGHT):
if self._check_dir(self._dir, dir):
self._dir = dir
head = self.s_list[1] # save head
last = self.s_list[-1] # save tail
# move the snake body fowward(copy list[n-1] to list[n])
for idx in range(len(self.s_list)-1, 1, -1):
self.s_list[idx] = self.s_list[idx-1]
head_t = self._add_xy(head, self._dir) # new head
# check snake head(cross wall)
if head_t[0] < 0:
head_t[0] = self.s_width - 1
elif head_t[0] > self.s_width - 1:
head_t[0] = 0
if head_t[1] < 0:
head_t[1] = self.s_height - 1
elif head_t[1] > self.s_height - 1:
head_t[1] = 0
chk, bd = self._check_body(head_t) # check the head
# if bd != self.BODY_NONE:
# print(chk, bd)
if chk == True and bd != self.BODY_NONE:
if bd == self.BODY_HEAD or bd == self.BODY_SNAKE or bd == self.BODY_WALL: # eat yourself or wall
if self.s_king != True: # 无敌模式
self.s_life = self.SNAKE_DIE # die
return self.s_life
else: # eat food
self.s_list.append(last) # body growth
self.s_score = self.s_score + 1 # add score
if self.s_score % 10 == 0: # 每吃10个食物增加一面墙
self._create_wall()
food = self._create_body() # create food
if food == None: # no space to create food
self.s_life = self.SNAKE_WIN
return self.s_life
self.s_list[0] = food
self.s_list[1] = head_t # update head
if len(self.s_list) == ((self.s_width * self.s_height)):
self.s_life = self.SNAKE_WIN
return self.s_life
```
### 3、game模块
该模块创建一个window对象和一个snake对象, 然后在一个新线程中执行snake模块的move和show函数,实现贪吃蛇的不断移动和绘制.在主线程中,不断检测窗口事件,根据窗口事件类型改变蛇的状态.
#### **game_run**
用于在子线程中运行的线程函数
```py
'''
贪吃蛇运行线程
'''
def game_run(snake):
global dir
global stop
global speed
delay = 1.5
while True:
if stop != True:
life = snake.move(dir)
if life != snake.SNAKE_LIFE:
break # die, exit
snake.show(window)
delay = 1 - speed * 0.05
if delay < 0.05:
delay = 0.05
time.sleep(delay)
```
#### **main**
贪吃蛇游戏主函数
```py
if __name__ == "__main__":
snake, window = game_init()
# 创建新线程,在新线程中允许和绘制贪吃蛇
gt = threading.Thread(target=game_run, args=(snake,))
gt.start()
# 主线程用于检测按键事件
while True:
event = window.event()
if event != window.EVENT_NONE:
if event == window.EVENT_QUIT: # ESC退出
window.quit()
elif event == window.EVENT_KUP or \
event == window.EVENT_KDOWN or \
event == window.EVENT_KLEFT or \
event == window.EVENT_KRIGHT: # 方向键控制贪吃蛇移动
dir = event
elif event == window.EVENT_STOP:#空格键暂停和继续
if stop == False:
stop = True
else:
stop = False
#print(dir, snake.s_life)
elif event == window.EVENT_ADD: # F1速度加
speed = speed + 1
elif event == window.EVENT_SUB: # F2速度减
speed = speed - 1
elif event == window.EVENT_KING: # F3无敌模式
if snake.s_king == True:
snake.s_king = False
else:
snake.s_king = True
if snake.s_life != snake.SNAKE_LIFE: # 如果贪吃蛇死亡则退出游戏
window.quit()
if score != snake.s_score: # 每得10分速度增加一个等级
score = snake.s_score
if(score % 10 == 0):
speed = speed + 1
```
# 五、程序运行截图
![](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/py_snake/20180524014149.jpg)
![](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/py_snake/20180524014241.jpg)
![](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/py_snake/py_snake.gif)
## 六、项目内文件截图
![项目内文件截图](https://raw.githubusercontent.com/WHJWNAVY/myImage/master/py_snake/20180524014350.jpg)
python贪吃蛇_python贪吃蛇相关推荐
- 贪吃蛇python语言代码_Python贪吃蛇简单的代码
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 在自学Python的过程中在网上查询资料时发现了一些好玩的东西,python的游戏库模块,它可以自己弄一个小游戏来玩玩,然后我在网上找了一些游戏的代码,, ...
- 【python教程入门学习】Python实现自动玩贪吃蛇程序
这篇文章主要介绍了通过Python实现的简易的自动玩贪吃蛇游戏的小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学一学 实现效果 先看看效果 这比我手动的快多了,而且是单机的,自动玩没惹 ...
- python的ai写作_神奇,用Python写一个AI贪吃蛇,真的可以追着你跑的那种
语言选择 Life is short, use python! 所以,根本就没多想,直接上python. 最初版本 先让你的程序跑起来 一开始我的目标仅仅是让程序去控制贪吃蛇运动,让它去吃食物,仅此而 ...
- python50行小游戏_50行python代码实现的贪吃蛇小游戏
50行python代码实现的贪吃蛇小游戏 发布于 2014-09-01 21:26:24 | 1337 次阅读 | 评论: 1 | 来源: 网友投递 Python编程语言Python 是一种面向对象. ...
- python地牢贪吃蛇 —Roguelike贪吃蛇游戏游戏源码下载
Snague 是一款Roguelike类型的贪吃蛇小游戏.在保留贪吃蛇核心机制的基础上进丰富了游戏内容. 游戏中您不但可以挑战不同关卡, 还能够获得不同增强, 过五关斩六将, 打破高分记录, 成为最强 ...
- Python小游戏:贪吃蛇——turtle的使用
突然想把去年写的小游戏练习整合一下,写一个简单的教学文章吧. 该篇主要讲解利用python中turtle包制作小游戏,不涉及pygame的使用,仅用pycharm就可实现 0.理清游戏思路 要实现的效 ...
- Python使用pygame编写贪吃蛇小游戏
Python使用pygame编写贪吃蛇小游戏 代码如下: # -*- coding:utf-8 -*- """ 贪吃蛇 """ import ...
- #进击的贪吃蛇-----将贪吃蛇,飞机大战,坦克大战功能融合形成新的游戏
#进击的贪吃蛇-----将贪吃蛇,飞机大战,坦克大战功能融合形成新的游戏. 想必很多大一新生在刚学C语言时和我们遇到过同样的问题,就是如何去做第一个C语言大作业. 我们小组内部在讨论大作业时,并不打算 ...
- 贪吃蛇之智能蛇的实现
历经很长时间,在下终于把贪吃蛇人工控制的版本写好,虽然略显粗糙,但也为自己初步写好一个简单游戏高兴不已.近日,又尝试了智能蛇的实现. 智能蛇与人工蛇很相似,不同之处在于一个不需要手动输入字符,另一个则 ...
- 12行贪吃蛇html,贪吃蛇大作战无敌版
贪吃蛇大作战无敌版下载是一款贪吃蛇类手游,在贪吃蛇大作战无敌版下载游戏中蛇分两种,蛇越多身体越笨重,但伤害也就越高,小蛇虽然伤害不高,但身体非常灵活,可以非常轻快地躲避大蛇的攻击,还等什么赶快来下载游 ...
最新文章
- h5-16-SVG 与 HTML5 的 canvas 各自特点
- Cisco PT模拟实验(12) 路由器静态路由的配置
- 阿里巴巴对Java编程【注释规约】的规约
- 手机MODEM 开发(33)---SimCard 学习总结
- Git 历史记录内容对比
- Linux socket can例程C++版本
- F8-Nginx代理缓存负载均衡后端均衡
- 创建一个滚动的文本字幕。
- [Java] 固定队列的实现思路
- 中彩分析家 打字软件
- JavaCV入门教程目录(JavaCV从入门到实战,JavaCV指南手册,免费JavaCV教程)
- 罗技G500游戏鼠标
- mescroll下拉刷新上拉加载
- 医院住院管理信息系统类图
- 计算机主板上常用的接口,电脑主板上接口怎么接 主板所有接口插线功能作用识别图解...
- es高亮搜索java_ES检索服务搜索结果高亮
- Java 并发编程:轻量级锁和偏向锁详解
- 详解Java 12新特性:switch表达式
- 传奇服务器怎么设置状态是开区还是合区,传奇私服开区合区教程全解
- 期刊论文发表能加分吗