社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

100 行 Python代码,轻松实现贪吃蛇小游戏

编程派 • 6 年前 • 679 次点击  

大家小时候都玩过贪吃蛇吧?小编小时候可喜欢拿爸妈的手机玩了,厉害着呢!今天,小编就来用100行代码实现一个简易版的贪吃蛇。


在网上,贪吃蛇教程蛮多的,但要安装蛮多库的,而且也不够清晰,今天的代码比较短,而且理解起来或者说你更改起来要简单一些。


最终会实现效果如下:



基本准备


首先,我们需要安装pygame库,小编通过pip install pygame,很快就安装好了。在完成贪吃蛇小游戏的时候,我们需要知道整个游戏分为四部分:


  1. 游戏显示:游戏界面、结束界面

  2. 贪吃蛇:头部、身体、食物判断、死亡判断

  3. 树莓:随机生成

  4. 按键控制:上、下、左、右


游戏显示


首先,我们来初始化pygame,定义颜色、游戏界面的窗口大小、标题和图标等。

1# 初始化pygame
2pygame.init()
3fpsClock = pygame.time.Clock()
4# 创建pygame显示层
5playSurface = pygame.display.set_mode((600,460))#窗口大小
6pygame.display.set_caption('Snake Game')#窗口名称
7# 定义颜色变量
8redColour = pygame.Color(255,0,0)
9blackColour = pygame.Color(0,0,0)
10whiteColour = pygame.Color(255,255 ,255)
11greyColour = pygame.Color(150,150,150)


游戏结束界面,我们会显示“Game Over!”和该局游戏所得分数,相关代码如下:

1# 定义gameOver函数
2def gameOver(playSurface,score):
3    gameOverFont = pygame.font.SysFont('arial.ttf',54#游戏结束字体和大小
4    gameOverSurf = gameOverFont.render('Game Over!'True, greyColour) #游戏结束内容显示
5    gameOverRect = gameOverSurf.get_rect()
6    gameOverRect.midtop = (30010#显示位置
7    playSurface.blit(gameOverSurf, gameOverRect)
8    scoreFont = pygame.font.SysFont('arial.ttf',54#得分情况显示
9    scoreSurf = scoreFont.render('Score:'+str(score), True, greyColour)
10    scoreRect = scoreSurf.get_rect()
11    scoreRect.midtop = (30050)
12    playSurface.blit(scoreSurf, scoreRect)
13    pygame.display.flip() #刷新显示界面
14    time.sleep(5 #休眠五秒钟自动退出界面
15    pygame.quit()
16    sys.exit()


贪吃蛇和树莓


我们需要将整个界面看成许多20*20的小方块,每个方块代表一个单位,蛇的长度用单位来表示,同时我们采用列表的形式存储蛇的身体。同时,我们都知道,树莓的位置是随机的。所以,我们需要让树莓出现的位置是游戏界面中的随机位置,同时,每吃到一颗树莓,就需要重新生成一颗新的树莓,并且得分加1。


相关初始化设置如下:

1snakePosition = [100,100#贪吃蛇 蛇头的位置
2snakeSegments = [[100,100]] #贪吃蛇 蛇的身体,初始为一个单位
3raspberryPosition = [300,300#树莓的初始位置
4raspberrySpawned = 1 #树莓的个数为1
5direction = 'right' #初始方向为右
6changeDirection = direction
7score = 0 #初始得分


如何控制贪吃蛇的运动轨迹呢,那么就需要按键控制了。我们通过键盘的↑↓←→和WSAD来控制,如果想直接退出游戏,则可以通过Esc键。这里需要强调的是,贪吃蛇里面是不能反方向运动,因此,我们需要进一步的增加限制条件:


1# 检测例如按键等pygame事件
2for event in pygame.event.get():
3    if event.type == QUIT:
4         pygame.quit()
5        sys.exit()
6    elif event.type == KEYDOWN:
7        # 判断键盘事件
8        if event.key == K_RIGHT or event.key == ord('d'):
9            changeDirection = 'right'
10        if event.key == K_LEFT or event.key == ord('a'):
11            changeDirection = 'left'
12        if event.key == K_UP or event.key == ord('w'):
13            changeDirection = 'up'
14        if event.key == K_DOWN or event.key == ord('s'):
15            changeDirection = 'down'
16        if event.key == K_ESCAPE:
17            pygame.event.post(pygame.event.Event(QUIT))
18# 判断是否输入了反方向
19if changeDirection == 'right' and not direction == 'left':
20    direction = changeDirection
21 if changeDirection == 'left' and not direction == 'right':
22    direction = changeDirection
23if changeDirection == 'up' and not direction == 'down':
24    direction = changeDirection
25if changeDirection == 'down' and not direction == 'up':
26    direction = changeDirection


方向设置好了,那么贪吃蛇蛇身变换怎么做啊?很简单,我们只需要根据方向变换一下坐标即可。


1# 根据方向移动蛇头的坐标
2if direction == 'right':
3    snakePosition[0] += 20
4if direction == 'left':
5    snakePosition[0] -= 20
6if direction == 'up':
7    snakePosition[1] -= 20
8if direction == 'down':
9    snakePosition[1] += 20
10# 增加蛇的长度
11snakeSegments.insert(0,list(snakePosition))


贪吃蛇游戏里面最重要的就是食物判断和死亡判断。


首先是食物判断,我们通过键盘按键来决定贪吃蛇的走向,以便它能吃到树莓。如何判断贪吃蛇有没有吃到树莓呢?很简单,如果贪吃蛇蛇头的位置和树莓的位置重合了,也就是相同,那么贪吃蛇就吃到树莓了,否则没有。同时,一旦发生了树莓被吃的情况,立刻重新随机生成一个新的树莓。


相关代码如下:

1# 判断是否吃掉了树莓
2if snakePosition[0] == raspberryPosition[0and snakePosition[1] == raspberryPosition[1]:
3    raspberrySpawned = 0
4 else:
5    snakeSegments.pop() #若没有吃掉树莓,需将最后一单位的蛇身提出列表,此处和蛇身移动时位置变换有关
6# 如果吃掉树莓,则重新生成树莓
7if raspberrySpawned == 0:
8    x = random.randrange(1,30#和游戏界面大小相关
9    y = random.randrange(1,23)
10    raspberryPosition = [int(x*20),int(y*20)]
11    raspberrySpawned = 1
12    score += 1


死亡判断则分为两类情况,一是触碰到了游戏界面的边界,二是贪吃蛇触碰到了自己的身体。一旦发生死亡,则触发gameover。


1# 判断是否死亡
2if snakePosition[0] > 600 or snakePosition[0] 0
#若超过左右边界,触发gameover
3    gameOver(playSurface,score)
4if snakePosition[1] > 460 or snakePosition[1] 0: #若超过上下边界,触发gameover
5    gameOver(playSurface,score)
6for snakeBody in snakeSegments[1:]: #若触碰到自己的身体,触发gameover
7    if snakePosition[0] == snakeBody[0and snakePosition[1] == snakeBody[1]:
8        gameOver(playSurface,score)


贪吃蛇运动和吃掉树莓的过程中,游戏界面需要不断更新。同时,我们设置了游戏速度。


1# 绘制pygame显示层
2playSurface.fill(blackColour) #蛇身为白色
3 for position in snakeSegments:
4    pygame.draw.rect(playSurface,whiteColour,Rect(position[0],position[1],20,20))
5    pygame.draw.rect(playSurface,redColour,Rect(raspberryPosition[0], raspberryPosition[1],20,20))
6
7# 刷新pygame显示层
8pygame.display.flip()
9# 控制游戏速度
10fpsClock.tick(5)


至此,我们就能完成一个贪吃蛇小游戏了。赶紧去实验一下吧!


完整的代码如下:


 1import pygame,sys,time,random
 2from pygame.locals import *
 3# 定义颜色变量
 4redColour = pygame.Color(255,0,0)
 5blackColour = pygame.Color(0,0,0)
 6whiteColour = pygame.Color(255,255,255)
 7 greyColour = pygame.Color(150,150,150)
 8def gameOver(playSurface,score):
 9    gameOverFont = pygame.font.SysFont('arial.ttf',54)
10    gameOverSurf = gameOverFont.render('Game Over!'True, greyColour)
11    gameOverRect = gameOverSurf.get_rect()
12    gameOverRect.midtop = (30010)
13    playSurface.blit(gameOverSurf, gameOverRect)
14    scoreFont = pygame.font.SysFont('arial.ttf',54)
15    scoreSurf = scoreFont.render('Score:'+str(score), True, greyColour)
16    scoreRect = scoreSurf.get_rect()
17    scoreRect.midtop = (30050)
18    playSurface.blit(scoreSurf, scoreRect)
19    pygame.display.flip()
20    time.sleep(5)
21    pygame.quit()
22    sys.exit()
23def main():
24    # 初始化pygame
25    pygame.init()
26     fpsClock = pygame.time.Clock()
27    # 创建pygame显示层
28    playSurface = pygame.display.set_mode((600,460))
29    pygame.display.set_caption('Snake Game')
30    # 初始化变量
31    snakePosition = [100,100#贪吃蛇 蛇头的位置
32    snakeSegments = [[100,100]] #贪吃蛇 蛇的身体,初始为一个单位
33    raspberryPosition = [300,300#树莓的初始位置
34    raspberrySpawned = 1 #树莓的个数为1
35    direction = 'right' #初始方向为右
36    changeDirection = direction
37    score = 0 #初始得分
38    while True:
39        # 检测例如按键等pygame事件
40        for event in pygame.event.get():
41            if event.type == QUIT:
42                pygame.quit()
43                sys.exit()
44            elif event.type == KEYDOWN:
45                # 判断键盘事件
46                if event.key == K_RIGHT or event.key == ord('d'):
47                    changeDirection = 'right'
48                if event.key == K_LEFT or event.key == ord('a'):
49                    changeDirection = 'left'
50                if event.key == K_UP or event.key == ord('w'):
51                    changeDirection = 'up'
52                if event.key == K_DOWN or event.key == ord('s'):
53                    changeDirection = 'down'
54                if event.key == K_ESCAPE:
55                    pygame.event.post(pygame.event.Event(QUIT))
56        # 判断是否输入了反方向
57        if changeDirection == 'right' and not direction == 'left':
58            direction = changeDirection
59        if  changeDirection == 'left' and not direction == 'right':
60            direction = changeDirection
61        if changeDirection == 'up' and not direction == 'down':
62            direction = changeDirection
63        if changeDirection == 'down' and not direction == 'up':
64            direction = changeDirection
65        # 根据方向移动蛇头的坐标
66        if direction == 'right':
67            snakePosition[0] += 20
68        if direction == 'left':
69            snakePosition[0] -= 20
70        if direction == 'up':
71            snakePosition[1] -= 20
72        if direction == 'down':
73            snakePosition[1] += 20
74        # 增加蛇的长度
75        snakeSegments.insert(0,list(snakePosition))
76        # 判断是否吃掉了树莓
77        if snakePosition[0] == raspberryPosition[0and snakePosition[1] == raspberryPosition[1]:
78            raspberrySpawned = 0
79        else:
80            snakeSegments.pop()
81        # 如果吃掉树莓,则重新生成树莓
82        if raspberrySpawned == 0:
83            x = random.randrange(1,30)
84            y = random.randrange(1,23)
85            raspberryPosition = [int(x*20),int(y*20)]
86            raspberrySpawned = 1
87            score += 1
88        # 绘制pygame显示层
89        playSurface.fill(blackColour)
90        for position in snakeSegments:
91             pygame.draw.rect(playSurface,whiteColour,Rect(position[0],position[1],20,20))
92            pygame.draw.rect(playSurface,redColour,Rect(raspberryPosition[0], raspberryPosition[1],20,20))
93        # 刷新pygame显示层
94        pygame.display.flip()
95        # 判断是否死亡
96        if snakePosition[0] > 600 or snakePosition[0] 0
:
97            gameOver(playSurface,score)
98        if snakePosition[1] > 460 or snakePosition[1] 0:
99            gameOver(playSurface,score)
100        for snakeBody in snakeSegments[1:]:
101            if snakePosition[0] == snakeBody[0and snakePosition[1] == snakeBody[1]:
102                gameOver(playSurface,score)
103        # 控制游戏速度
104        fpsClock.tick(5)
105
106if __name__ == "__main__":
107    main()


本文经授权转载自公众号”经管人学数据分析“,如需转载请联系原作者。


-- End --


昨天推文里介绍的米乔腰垫,提供的二维码只能购买一代基础款,无法买到二代气动款,这是我推送之前的失误,在这跟大家道个歉。如果对二代感兴趣的,可以扫描下方的二维码购买。


昨天推文里的留言送礼活动依然有效,截止到本周五中午12点。


贴合透气,保护腰椎,办公驾车两相宜

MINICUTE人体工程学靠垫

二代升级气动款
哪怕只用一年,每天不到7毛钱,舒服8小时哦,真的超级划算

更多介绍,可点击下图查看。

Google 都在用的人体工学腰垫,有什么久坐不累的秘密?


印度小伙写了套深度学习教程,Github上星标已经5000+

上百个数据文件合并,只能手动复制粘贴?教你一招十秒搞定!

一个提升图像识别准确率的精妙技巧

一文读懂:从 Python 打包到 CLI 工具

如何使用 Python 进行时间序列预测?

美亚Kindle排名第一的Python 3入门书,火遍了整个编程圈

十分钟搭建私有 Jupyter Notebook 服务器

使用 Python 制作属于自己的 PDF 电子书

12步轻松搞定Python装饰器

200 行代码实现 2048 游戏

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/29561
 
679 次点击