每个初学写代码的人可能都想在学习了一些基础知识后,希望能够写出一点拿得出手,秀的出来,但又在自己能力范围内的东西(没错,说的是我自己)。
![c94fc9849e5bc3efcd1a3f88fa2f34e1.png](https://i-blog.csdnimg.cn/blog_migrate/bddceda050d488dca1f7273306a7bbfe.jpeg)
本人是个在读大学生,python小白,就想完成个多年前“自己写出个游戏的梦想”,选择了好像不难的贪吃蛇。
写之前,因为有用C试写过贪吃蛇,所以有个大概方向与思路,但python和C毕竟还是有点区别的,所以先是查阅了很多现有的大佬写的贪吃蛇小游戏,牛吗?都很牛,但就是太牛了啊,牛到我这种小白真看不太懂,各种创建类,然后用什么pygame里面的某些我看不懂的又没有解释的变量,然后写出了华丽、灵活的小蛇在屏幕上乱舞,但我除了复制代码,我真看不懂啊!
万一我拿复制的代码装X的时候,别人问我这行的解释,我可咋办?
![32d1cd0ad091294c60fd28d17c1f5f06.png](https://i-blog.csdnimg.cn/blog_migrate/3828daf7b9a48bb9126647db282ba3df.jpeg)
所以这篇文章就教你怎么用python写出一个简易的,但五脏俱全的贪吃蛇小游戏。我保证每步不重复的步骤都有最白话的注释,说了这么多废话,我们开始一步步开始吧!
首先写贪吃蛇的基本思路:
1.安装python的pygame模块
2.设置游戏窗口信息
3.画出小蛇、画出蛇爱吃的食物
4.让小蛇能跟着方向键随意舞动,并且在我们不变方向键的时候它会朝着最后一次的方向一直移动
5.蛇该死的时候还是得死的,比如“咬蛇自尽”,“撞墙示冤”而死
6.运行,然后发个pyq,文案我都帮你想好了“古有图灵人工智能,今有新秀写蛇玩蛇,计算机革命,非我无能,实属无志”(忘记押韵了,sorry)
好了让我们正式开始!(好多废话,现在才开始)
第一步:安装pygame
首先去python的官网https://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame
![3ad429362034f29ef220b688acae5acc.png](https://i-blog.csdnimg.cn/blog_migrate/429d34e244f558ace8b2d7baccc658e8.jpeg)
选择适合你的python版本的pygame,比如我的python是3.7的,系统是win64位的就选择
![b354003583db3f1adaceef34c672315f.png](https://i-blog.csdnimg.cn/blog_migrate/d5d5da8d65d7de20c9be2cfdb66fc7a5.png)
然后把下载下来的文件放到全英文目录下(可以直接放C盘),然后在cmd里面进入C盘
![10f464203646885712538cd81ae1ab9d.png](https://i-blog.csdnimg.cn/blog_migrate/825f139b6cf7309ab08a084f017074d5.png)
然后输入pip install pygame-1.9.6-cp37-cp37m-win_amd64.whl(把install后面的一串改成你自己下载的文件的名字,然后回车就开始安装了)安装完后,可以在python里面输入import pygame如果没有报错,那就完成了万里长征的第一里了!
然后就可以在python里面使用pygame了
注意,在使用pygame之前一定要先输入
![af64a04079a7eafca03a26479c423521.png](https://i-blog.csdnimg.cn/blog_migrate/1d7c19c69bd6a31cd53476c819fed029.png)
我个人的理解是:初始化 pygame模块,确保pygame模块完整可用
第二步:设置游戏窗口信息
创建一个窗口
![6cf85a6d15640a254d7de919a82e959f.png](https://i-blog.csdnimg.cn/blog_migrate/9a928f331b49b5ae9778dda8e5bb68bc.png)
![ab544eb866e8b0a0a28fd59ada34eb51.png](https://i-blog.csdnimg.cn/blog_migrate/f16b0fbf8fad1705901739e4a86c5e1f.png)
设置窗口标题
![24024ad411a4d4d08d0eac6398510e53.png](https://i-blog.csdnimg.cn/blog_migrate/e1a6d774467aafad6036f3c36810c435.png)
汇总一下第二步
![e1e5ef80c095abbc3f2c4bfcc86f7238.png](https://i-blog.csdnimg.cn/blog_migrate/48075fac0bdd74156d6a45d50f7d2eaa.jpeg)
运行就会出现一个黑框啦!
![e1252a75cda6e83fcd8aad1bb9f514bc.png](https://i-blog.csdnimg.cn/blog_migrate/86770a08ea600d7f90683ed257d60a83.jpeg)
第三步:画出小蛇和食物
先有鸡还是先有蛋,先有蛇还是先有食物?这值得思考(个P)
3.1画蛇!
先给画布和蛇一个颜色,我喜欢Blue,就画一个小蓝蛇吧
![730239679239b1bc4106005e5da8553d.png](https://i-blog.csdnimg.cn/blog_migrate/3d77e1661cbc5e7e5b9b0394c99d3b16.png)
![3be332b133d0a7b40c549ecdf8f5d255.png](https://i-blog.csdnimg.cn/blog_migrate/0e7463506a3bf2145166d5759cdb2b51.png)
蛇是不是要有蛇头和蛇身?
![846f7c7d8cb703cd5c6e108745215b60.png](https://i-blog.csdnimg.cn/blog_migrate/0a0d57298a9c236c853b8c6bb389bcd5.png)
![bc234b633ba8ac72b794f0322d74ebd7.png](https://i-blog.csdnimg.cn/blog_migrate/c8d61f2d44fbd9a98e52c84e4d602b6c.png)
![9d5d6d677c1f2984847be72baf6125c6.png](https://i-blog.csdnimg.cn/blog_migrate/3e36a2d6b82cd9bcd0f866a1a06900f3.png)
食物只有一节,所以只要有一个坐标就行,但食物要是随机产生的
![b7292eae9d96a1193759525f4805613a.png](https://i-blog.csdnimg.cn/blog_migrate/c92822ea42045aa74315ccc28b5828e2.png)
汇总一下第三步:
![5bf660a1b5531eafd887fddc6ecc8dd7.png](https://i-blog.csdnimg.cn/blog_migrate/0208c1c4502c29205681508158b1e039.jpeg)
![de5887cfb5e8c2fc5ef1257531e1d1c7.png](https://i-blog.csdnimg.cn/blog_migrate/132b819619e67561c2c7e72226d953b1.png)
得到了小蓝蛇和食物(好刺激,如果只要图片的话,已经可以发pyq了!)
![4633c010fb7f58bef18fd1d21d6dafee.png](https://i-blog.csdnimg.cn/blog_migrate/4c769ea8b3c755fccb7d99ecc400f29b.png)
不能止步!我要玩蛇!
第四步:让蛇能跟着你的方向键动起来!动起来~
首先我们用1234分别表示上下左右
1-上 2-下 3-左 4-右
我们以“上”为例
不要把蛇的移动想得太复杂了,刚开始我想蛇的移动是整个蛇发生了位移,就要改变所有蛇身的坐标,这也太麻烦了吧!
其实仔细想一下,蛇在移动的时候,是不是其实只有蛇头和蛇尾发生了变化!
![ba14978244a7855d83f1eb9f3b876ac8.png](https://i-blog.csdnimg.cn/blog_migrate/2927d1828a9f2ff0b4b1547fdc3e753f.png)
当蛇往上移动的时候,新蛇头的位置就变成了旧蛇头上面的那一格!原有的蛇不发生变化,只是多出来一个新的蛇头取代了旧蛇头(旧蛇头变成了蛇身)
物理学家迈尔说过:能量是守恒的!
既然多出了个蛇头,相应的蛇尾只要删掉就完成了蛇的移动!
当然有小天才要问了“如果刚好我上移的时候吃到了食物怎么办?”
根据守恒,食物没了,就得长在蛇身上,那我们前面说的蛇头的变化还是照旧,只是蛇尾我们不用删掉,就完成了蛇的增长了!
并且食物被吃后要产生新的食物下次接着吃!
看下代码:
![f57c045103b517edcffbdfed70ddf75e.png](https://i-blog.csdnimg.cn/blog_migrate/0853b3cc8c08369c02aa17f38d7d0aa2.png)
其它移动方向同理:
![9b0347957612aae6c268cd3936ced789.png](https://i-blog.csdnimg.cn/blog_migrate/b4999fd7798c11ed0b76768d52ba3ca8.jpeg)
现在蛇各个方向移动的代码完成了,那么怎么让她和我们的方向键联系起来呢?
这里要用到pygame内置的“监听事件信息”
![98f8b217d9d2a7e002d320c1ae502b5c.png](https://i-blog.csdnimg.cn/blog_migrate/bba15384ff3667a7a3c28badd9ad7e43.png)
![e1aea6339c64e0a018dd1b08176223e4.png](https://i-blog.csdnimg.cn/blog_migrate/0b95abf88c6ac34dc1e3c37a2e496532.png)
同时要注意当我们想要改变小蓝蛇的移动方向时,如果原来移动方向是“上”,我们就不能让蛇往下移动,同理原左的时候不能变成向右。
![b83abd0ca68441ae9acdc78fde920e93.png](https://i-blog.csdnimg.cn/blog_migrate/aa4d78a8ec00a212b5c8616b098f675e.jpeg)
同时因为小蓝蛇一直在移动,所以画布需要一直刷新变化,需要控制一下刷新的频率
![db63ee1f4b905f9fa90fb9972f7787ba.png](https://i-blog.csdnimg.cn/blog_migrate/c27445bf53bbfd14c1c33af23a856662.png)
第五步:同时在移动的时候不能让蛇无所畏惧吧,该死的时候还是得死的
有两种死亡情况:
1.含冤撞墙而死
2.怀才不遇咬蛇自尽
![551e211feabdf8e6091d7845a726d76c.png](https://i-blog.csdnimg.cn/blog_migrate/9868ce70b18b3d201fe1d98b586b7682.jpeg)
![f25b68e89c72c8025b4b280c49522587.png](https://i-blog.csdnimg.cn/blog_migrate/54a6a1b7074c4188aad83f93f73da38b.png)
汇总一下目前代码:
![e49c13de99df47ea2fa50a6753356fa9.png](https://i-blog.csdnimg.cn/blog_migrate/fa779a93f21cd9ec16c5ca153c153e46.jpeg)
![e7ef4cc4654d1c755c65deacbf49a378.png](https://i-blog.csdnimg.cn/blog_migrate/839fc6a4c0fde648f6bc2cf2afa90fb8.jpeg)
![bf6cdd9521a980e6cd9fddb97fb36d9e.png](https://i-blog.csdnimg.cn/blog_migrate/14ea7ab0e9de318bdd98a1c4e3c9a126.jpeg)
![36095eb215cd9c4cdbc3d439e2084853.png](https://i-blog.csdnimg.cn/blog_migrate/5531f2bb0d5ea66470ccf861820c45a0.jpeg)
看下运行结果:
知乎视频www.zhihu.com可以看到现在的这条蛇就不再是一条普通的蛇了!
他会向各个方向冲锋尝试,有时也会一个方向不转弯,也会因为过于执拗撞墙而死,或者因为不谨慎跌入进自己挖的坑!
他现在是哲学蛇!
![50cc92936df3c3abe22f8cf441bd4cbc.png](https://i-blog.csdnimg.cn/blog_migrate/679d180fcde2b980a61ac5585340ed6f.jpeg)
当然我们也可以继续添加一些元素,让这个贪吃蛇看起来更完整。
附加1:添加游戏初始界面与结束界面
设置游戏开始界面包括图像、文字等(字体包可以百度一下自己电脑的的字体都放在哪里,我的是在C:WindowsFonts选择一个中文字体放进与py档同目录下即可)
通过监听按键信息,达成按任意键进入游戏的要求
![a9ea60fb7dfd795cd3c7ab798d66f6c3.png](https://i-blog.csdnimg.cn/blog_migrate/8bc47764bcf1ab17e9c3c88037f1369e.jpeg)
![5f75efdce93c232108ac45228c84fe3e.png](https://i-blog.csdnimg.cn/blog_migrate/14c001554a1cf45ca2c5c6fdd558efb1.png)
![1250f1b6e2fefe01503a6a89b2c77037.png](https://i-blog.csdnimg.cn/blog_migrate/c25510a7fa84dfcd3a4c36f87b05de46.jpeg)
![bc805c4c22fa9aec14920481d74e09be.png](https://i-blog.csdnimg.cn/blog_migrate/dfdcb4126bf8c058dd2c3c75f3aa7cf8.png)
初始界面:
![e6c9934f1f614f5a8516860bf6f4cf95.png](https://i-blog.csdnimg.cn/blog_migrate/146fa59c2a206658d67352664dd25370.jpeg)
结束界面:
![b5ef42f709d936eccfd13fa08c5575f9.png](https://i-blog.csdnimg.cn/blog_migrate/be31fd3b1d423fb5956bf6f450e2a19d.jpeg)
附加2:添加得分信息
得分情况可以在每次移动吃到食物后得分+1即可,比较简单,然后再用于与初始结束界面相同的绘制文字的方法绘制出来即可。
![b6f6ce0e6653abebb889b0c4e86384ce.png](https://i-blog.csdnimg.cn/blog_migrate/2b03da55514ed055cdd5f93f2b746c7c.jpeg)
![8444035f415b5de4878bb8f58fc56c8b.png](https://i-blog.csdnimg.cn/blog_migrate/3eb98f285bf5dd3ff36e9ca819181a24.png)
初始与结束界面图片:
![7f8caec712d80fbf4f8c625b9ae2ed77.png](https://i-blog.csdnimg.cn/blog_migrate/5a6019d6f1d9b57006025610d9a57832.jpeg)
![707fffe417e9dcf97f97425c9f51f876.png](https://i-blog.csdnimg.cn/blog_migrate/49db9711fa0fc63d8179cbc6be534cca.jpeg)
最终运行结果:
知乎视频www.zhihu.com本人纯属python小白,当最终看到这条骚动的小蓝蛇时,内心还是有点难以抑制的喜悦的,希望各位在自己尝试后也能有所收获!
同时贪吃蛇还有很多的元素可以添加,比如设置不同按钮选择进入“无敌模式”或者现在的会死亡的模式,结束时不直接退出,而是可以选择重新开始等,期待大家的进一步完善!
代码的冗余度,规范性等还有很大的问题,但确实已经用心啦,能力所限,还望各位包涵包涵,也期待各位对其中代码的改进,与对错误的批评指正。
我在梦中听见图灵说过“贪吃蛇都写出来了,LOL、魔兽等还会远吗?”
附上完整程序代码:
import pygame #载入pygame模块
import random #载入random模块
pygame.init() #初始化 pygame模块,确保pygame模块完整可用
#设置游戏窗口的基本信息
length = 600 #窗口长度
width = 600 #窗口宽度
score = 0 #初始成绩
window = pygame.display.set_mode((length,width)) #设置窗口的长度与宽度
pygame.display.set_caption('我想玩一下蛇') #设置窗口标题
blue=(0,0,255) #蓝色RGB
black=(0,0,0) #黑色RGB
Tiffanyblue=(129,216,209) #蒂芙尼蓝的RGB
Red=(255,0,0) #红色RGB
#给出蛇的坐标
head=[300,300]#蛇头的坐标
snake=[[300,300], [290,300], [280,300]]#蛇身体的三个矩形的坐标
#随机给出食物的坐标
food_rd=[random.randrange(1, 60) * 10, random.randrange(1, 60) * 10]
#游戏开始与游戏结束界面
#设置游戏开始界面
def start(window):
font = pygame.font.Font('simhei.ttf', 30) #设置字体与字号
prompt = font.render('按任意键开始玩蛇,按ESC可退出', 1 , Tiffanyblue) #设置文本内容和字体颜色
startimage = pygame.image.load('start.jpg') #加载图像
window.blit(prompt, (90, 400)) #绘制出字体
window.blit(startimage, (55, 50)) #绘制出加载的图像
pygame.display.update() #刷新
while True: #进行按键监听
for event in pygame.event.get(): #获取所有事件信息
if event.type == pygame.QUIT: #如果用户鼠标点击了窗口的X
pygame.quit() #终止程序
exit() #终止程序
elif event.type == pygame.KEYDOWN:#获取键盘按键信息
if event.key == pygame.K_ESCAPE: #终止程序
pygame.quit() #终止程序
else:
return 0 #结束初始界面,开始玩蛇
#设置游戏结束界面
def over(window):
font = pygame.font.Font('simhei.ttf', 25)
prompt = font.render('蛇都不会玩???自己按ESC或者点X退出吧', 1 , Tiffanyblue)
startimage = pygame.image.load('over.jpg')
window.blit(prompt, (70, 400))
window.blit(startimage, (50, 50))
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
exit()
#贪吃蛇死亡的两种情况
#含冤撞墙而死
def hit_wall(head):
if head[0] >= length or head[0]<0 or head[1] >= width or head[1] < 0: #如果蛇头坐标超出四周的界线
return 1 #撞墙发生
else:
return 0
#因怀才不遇咬蛇自尽
def hit_snake():
if snake[0] in snake[1:]: #如果蛇头坐标与身体中坐标重合
return 1 #咬蛇自尽发生
else:
return 0
#控制蛇的移动
def movesnake (direction):
global food_rd #声明全局变量(在函数中有赋值时使用)
global score
if direction == 1: #如果移动方向为上
head[1] = head[1] - 10 #Y轴坐标-10
snake.insert(0, list(head)) #插入新的头部坐标
if head != food_rd: #如果没有吃到食物
snake.pop(-1) #删去最后一个元素
else: #头部坐标等于食物坐标时即吃到食物,不删除末尾元素即完成增长
score = score + 1
food_rd = [random.randrange(1, 50) * 10, random.randrange(1, 50) * 10] #食物被吃后随机产生新食物
elif direction == 2:
head[1] = head[1] + 10
snake.insert(0, list(head))
if head != food_rd:
snake.pop(-1)
else:
score = score + 1
food_rd = [random.randrange(1, 60) * 10, random.randrange(1, 60) * 10]
elif direction == 3:
head[0] = head[0] - 10
snake.insert(0, list(head))
if head != food_rd:
snake.pop(-1)
else:
score = score + 1
food_rd = [random.randrange(1, 60) * 10, random.randrange(1, 60) * 10]
elif direction == 4:
head[0] = head[0] + 10
snake.insert(0, list(head))
if head != food_rd:
snake.pop(-1)
else:
score = score + 1
food_rd = [random.randrange(1, 60) * 10, random.randrange(1, 60) * 10]
#蛇在移动中该死的时候还是要死的
if hit_snake() or hit_wall(head): #如果蛇撞到自身或者撞到墙
over(window) #进入结束界面
speed = pygame.time.Clock() #创建时钟对象 (可以控制游戏循环频率)
direction = 4 #初始化移动方向为右
start(window) #进入初始界面
#主程序
while True:
for event in pygame.event.get():#获取所有事件信息
if event.type == pygame.QUIT: #如果用户鼠标点击了窗口的X
pygame.quit() #终止pygame程序
exit() #终止所有程序
if event.type == pygame.KEYDOWN: #获取键盘按键信息
if event.key == pygame.K_ESCAPE: #如果按键ESC
pygame.quit()
exit()
if direction != 2 and event.key == pygame.K_UP: #如果原始方向不是下,并且现在按键为上
direction = 1 #方向改变为上
elif direction != 1 and event.key == pygame.K_DOWN:
direction = 2
elif direction != 4 and event.key == pygame.K_LEFT:
direction = 3
elif direction != 3 and event.key == pygame.K_RIGHT:
direction = 4
movesnake(direction) #根据按键方向移动蛇
window.fill(black) #给窗口绘制黑色的画布
pygame.draw.rect(window,blue,pygame.Rect(food_rd[0],food_rd[1],10,10)) #画出食物
#画出小蓝蛇
for i in snake:
pygame.draw.rect(window, blue, pygame.Rect(i[0], i[1], 10, 10))
#显示成绩
font = pygame.font.Font('simhei.ttf', 25)
score_show = font.render('得分: %s' % score, 1 , Red) #格式化输出得分信息
window.blit(score_show, (500, 20))
pygame.display.update() #刷新界面
speed.tick(10) #FPS(数值越大蛇移动的速度越快)