一、游戏介绍 贪吃蛇是个非常简单的游戏,适合练手。先来看一下我的游戏截图: 游戏截图 玩法介绍: 回车键:开始游戏 空格键:暂停继续 方向键或WSAD键:控制移动方向。 食物分红、绿、蓝三种,分别对应10分、20分、30分,每吃一个食物增加对应分值,每增加100分速度加快一级,没有设置关卡,我玩到1100分,速度太快了,然后就GAMEOVER了。二、游戏分析 贪吃蛇这个游戏很简单,屏幕上随机出现一个点,表示食物,上下左右控制蛇的移动,吃到食物以后蛇的身体加长,蛇碰到边框或自己的身体,则游戏结束。 我们先来分析一下,要写出这个游戏来需要注意哪些点。 1、蛇怎么表示 我们可以将整个游戏区域划分成一个个的小格子,由一组连在一起的小格子组成蛇,我们可以用不同的颜色来表示,如上图中,我以深色表示背景,浅色表示蛇。 我们可以用坐标来表示每一个小方格,X轴和Y轴的范围都是可以设定好的。用一个列表来存放蛇身的坐标,那么一条蛇就出来了,最后只要显示的时候以不同的颜色表示即可。 2、蛇怎么移动? 第一反应就是像蚯蚓蠕动一样,每一个小方块向前移动一格,但这样实现起来很麻烦。一开始就是被这里卡住了。 想象一下我们玩过的贪吃蛇,每次蛇的移动感觉上是整体往前移动了一格,排除掉脑子中蛇的动作,细想移动前和移动后蛇的位置变化,其实除了头尾,其他部分根本就没有变。那就简单了,将下一格的坐标添加到列表开头,并移除列表的最后一个元素,就相当于蛇向前移动了一格。 3、如何判定游戏结束? 蛇移动超出了游戏区的范围或者碰到了自己就算输了,轴坐标的范围是事先定好的,超出范围很容易判断。那么如何判断碰到自己呢? 如果脑子里想的是蛇动的画面,那真的比较难了,但是放到代码中,我们的蛇是一个列表,那么只要判断下一格的坐标是否已经包含在蛇的列表中岂不就可以了? 理清了这些问题,我们就可以开始编码了。三、代码实现 由于程序中要频繁的对蛇进行头尾的添加和删除操作,为了性能更好那么一点,我们用deque代替列表。 首先需要初始化蛇,蛇的初始长度为3,位置位于左上角。游戏区域的坐标范围SCOPEX(0,SCREENWIDTHSIZE1)SCOPEY(2,SCREENHEIGHTSIZE1)初始化蛇snakedeque()definitsnake():snake。clear()snake。append((2,scopey〔0〕))snake。append((1,scopey〔0〕))snake。append((0,scopey〔0〕))创建食物,在屏幕内随机选取一个点作为食物,但是要保证食物不在蛇身上。食物defcreatefood(snake):foodxrandom。randint(SCOPEX〔0〕,SCOPEX〔1〕)foodyrandom。randint(SCOPEY〔0〕,SCOPEY〔1〕)while(foodx,foody)insnake:如果食物出现在蛇身上,则重来foodxrandom。randint(SCOPEX〔0〕,SCOPEX〔1〕)foodyrandom。randint(SCOPEY〔0〕,SCOPEY〔1〕)returnfoodx,foody 蛇的移动可以有4个方向,用一个元组来表示移动的方向,每次按下方向键,给赋对应的值 方向pos(1,0)foreventinpygame。event。get():ifevent。typeQUIT:sys。exit()elifevent。typeKEYDOWN:ifevent。keyin(Kw,KUP):这个判断是为了防止蛇向上移时按了向下键,导致直接GAMEOVERifpos〔1〕:pos(0,1)elifevent。keyin(Ks,KDOWN):ifpos〔1〕:pos(0,1)elifevent。keyin(Ka,KLEFT):ifpos〔0〕:pos(1,0)elifevent。keyin(Kd,KRIGHT):ifpos〔0〕:pos(1,0) 而蛇的移动就可以表示为:nexts(snake〔0〕〔0〕pos〔0〕,snake〔0〕〔1〕pos〔1〕)ifnextsfood:吃到了食物snake。appendleft(nexts)foodcreatefood(snake)else:ifSCOPEX〔0〕nexts〔0〕SCOPEX〔1〕andSCOPEY〔0〕nexts〔1〕SCOPEY〔1〕andnextsnotinsnake:snake。appendleft(nexts)snake。pop()else:gameoverTrue 完整代码贪吃蛇小游戏importrandomimportsysimporttimeimportpygamefrompygame。localsimportfromcollectionsimportdequeSCREENWIDTH600SCREENHEIGHT480SIZE20defprinttext(screen,font,x,y,text,fcolor(255,255,255)):imgTextfont。render(text,True,fcolor)screen。blit(imgText,(x,y))defmain():pygame。init()screenpygame。display。setmode((SCREENWIDTH,SCREENHEIGHT))pygame。display。setcaption(贪吃蛇)light(100,100,100)蛇的颜色dark(200,200,200)食物颜色font1pygame。font。SysFont(SimHei,24)得分的字体font2pygame。font。Font(None,72)GAMEOVER的字体red(200,30,30)GAMEOVER的字体颜色fwidth,fheightfont2。size(GAMEOVER)linewidth1网格线宽度black(0,0,0)网格线颜色bgcolor(40,40,60)背景色方向,起始向右posx1posy0如果蛇正在向右移动,那么快速点击向下向左,由于程序刷新没那么快,向下事件会被向左覆盖掉,导致蛇后退,直接GAMEOVERb变量就是用于防止这种情况的发生bTrue范围scopex(0,SCREENWIDTHSIZE1)scopey(2,SCREENHEIGHTSIZE1)蛇snakedeque()食物foodx0foody0初始化蛇definitsnake():nonlocalsnakesnake。clear()snake。append((2,scopey〔0〕))snake。append((1,scopey〔0〕))snake。append((0,scopey〔0〕))食物defcreatefood():nonlocalfoodx,foodyfoodxrandom。randint(scopex〔0〕,scopex〔1〕)foodyrandom。randint(scopey〔0〕,scopey〔1〕)while(foodx,foody)insnake:为了防止食物出到蛇身上foodxrandom。randint(scopex〔0〕,scopex〔1〕)foodyrandom。randint(scopey〔0〕,scopey〔1〕)initsnake()createfood()gameoverTruestartFalse是否开始,当startTrue,gameoverTrue时,才显示GAMEOVERscore0得分orispeed0。5原始速度speedorispeedlastmovetimeNonepauseFalse暂停whileTrue:foreventinpygame。event。get():ifevent。typeQUIT:sys。exit()elifevent。typeKEYDOWN:ifevent。keyKRETURN:ifgameover:startTruegameoverFalsebTrueinitsnake()createfood()posx1posy0得分score0lastmovetimetime。time()elifevent。keyKSPACE:ifnotgameover:pausenotpauseelifevent。keyin(Kw,KUP):这个判断是为了防止蛇向上移时按了向下键,导致直接GAMEOVERifbandnotposy:posx0posy1bFalseelifevent。keyin(Ks,KDOWN):ifbandnotposy:posx0posy1bFalseelifevent。keyin(Ka,KLEFT):ifbandnotposx:posx1posy0bFalseelifevent。keyin(Kd,KRIGHT):ifbandnotposx:posx1posy0bFalse填充背景色screen。fill(bgcolor)画网格线竖线forxinrange(SIZE,SCREENWIDTH,SIZE):pygame。draw。line(screen,black,(x,scopey〔0〕SIZE),(x,SCREENHEIGHT),linewidth)画网格线横线foryinrange(scopey〔0〕SIZE,SCREENHEIGHT,SIZE):pygame。draw。line(screen,black,(0,y),(SCREENWIDTH,y),linewidth)ifgameover:ifstart:printtext(screen,font2,(SCREENWIDTHfwidth)2,(SCREENHEIGHTfheight)2,GAMEOVER,red)else:curTimetime。time()ifcurTimelastmovetimespeed:ifnotpause:bTruelastmovetimecurTimenexts(snake〔0〕〔0〕posx,snake〔0〕〔1〕posy)ifnexts〔0〕foodxandnexts〔1〕foody:吃到了食物createfood()snake。appendleft(nexts)score10speedorispeed0。03(score100)else:ifscopex〔0〕nexts〔0〕scopex〔1〕andscopey〔0〕nexts〔1〕scopey〔1〕andnextsnotinsnake:snake。appendleft(nexts)snake。pop()else:gameoverTrue画食物ifnotgameover:避免GAMEOVER的时候把GAMEOVER的字给遮住了pygame。draw。rect(screen,light,(foodxSIZE,foodySIZE,SIZE,SIZE),0)画蛇forsinsnake:pygame。draw。rect(screen,dark,(s〔0〕SIZElinewidth,s〔1〕SIZElinewidth,SIZElinewidth2,SIZElinewidth2),0)printtext(screen,font1,30,7,f速度:{score100})printtext(screen,font1,450,7,f得分:{score})pygame。display。update()ifnamemain:main() 最后 为了感谢读者们,我想把我最近收藏的一些编程干货分享给大家,回馈每一个读者,希望能帮到你们。 里面有适合小白新手的全套资料给到大家 快来和小鱼一起成长进步吧! 100多本Python电子书(主流和经典的书籍应该都有了) Python标准库资料(最全中文版) 爬虫项目源码(四五十个有趣且经典的练手项目及源码) Python基础入门、爬虫、web开发、大数据分析方面的视频(适合小白学习) Python学习路线图(告别不入流的学习) 资料 对文章有问题的,或者有其他关于python的问题,可以在评论区留言或者私信我哦 觉得我分享的文章不错的话,可以关注一下我,或者给文章点赞() 获。得教程的方式 转发本文,私信:视频, 即可获取!