这篇文章上次修改于 220 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
注意事项
本文需使用pygame模块,有关如何安装pygame模块,请参照我之前的文章:
先来段演示结果:
游戏编写思路
游戏入口与结束函数
注册键盘热键:上下左右
蛇的死亡:撞墙和碰到自己
食物的随机生成
那么让我们来看下各个步骤:
游戏结束函数
def gameover():
pygame.quit()#用于退出pygame模块
sys.exit()#用于退出程序
在入口函数中,我们需要初始化游戏界面,定义蛇的身体,方向和开始循环
入口函数
def main():
pygame.init()#初始化pygame
fpsClock=pygame.time.Clock()#创建时钟,屏幕刷新函数
screen=pygame.display.set_mode((640,480))#创建一个720x560的窗口
pygame.display.set_caption("python贪吃蛇")#将窗口命名为python贪吃蛇
定义蛇的身体、位置和方向,以及食物的初始位置
#定义蛇的初始位置
snake=[100,100]
#初始为1段身体,每段间隔20个单位,以列表形式保存
snakebody=[[100,100]]
#定义蛇的移动方向,向300x300的方向移动
snaket=[300,300]
#标记方块,初始为1,吃掉后为0
cube=1
#初始化人为控制的按键方向,默认为向右
direction='right'
#人为控制的方向变量
cdirection=direction
游戏循环开始
注册热键:
while True:
for event in pygame.event.get(): #队列中获取事件
if event.type==pygame.QUIT:#若点击右上角的x,则退出
gameover()
elif event.type==pygame.KEYDOWN:#注册热键,按键按下
if event.key==pygame.K_d:#按下d键,以下等同
cdirection='right'
#多个if判断,不用elif,防冲突
if event.key==pygame.K_a:
cdirection='left'
if event.key==pygame.K_w:
cdirection='up'
if event.key==pygame.K_s:
cdirection='down'
这里注册了WASD四个热键,用于控制蛇的移动方向
确定蛇的方向是否相反:
if cdirection =='left' and not direction =='right':
direction = cdirection
if cdirection =='right' and not direction =='left':
direction = cdirection
if cdirection =='up' and not direction =='down':
direction = cdirection
if cdirection =='down' and not direction =='up':
direction = cdirection
移动蛇头:
#根据方向移动蛇头,蛇头位置第一个位置加20
if direction =='right':
snake[0] +=20
if direction =='left':
snake[0] -=20
if direction =='up':
snake[1] -=20
if direction =='down':
snake[1] +=20
增加蛇的身体长度及食物判断:
#增加蛇的长度
snakebody.insert(0,list(snake))#在尾部插入一段身体
#贪吃蛇和目标食物相互重叠的情况下(吃到食物情况下)
if snake[0]==snaket[0] and snake[1]==snaket[1]:
cube=0
else:
snakebody.pop()
#随机生成食物判断
if cube==0:
x=random.randrange(1,32)
y=random.randrange(1,24)
snaket=[int(x*20),int(y*20)]#防止随机生成的数值在蛇中间无法吃到
cube=1
绘制图形
这里我们先定义蛇,食物和界面的颜色
#各种颜色
color1=pygame.Color(255,2,2)#吃的方块的颜色
color2=pygame.Color(0,0,0)#背景颜色
color3=pygame.Color(255,100,100)#蛇的颜色
开始绘制图形:
#开始填充颜色
screen.fill(color2)
#开始绘图
for draws in snakebody:
#第一个参数指定一个编辑区,在这个区域内绘制
#第二个参数颜色
#第三个参数:rect:返回一个矩形(x和y),(宽,高)
pygame.draw.rect(screen,color3,pygame.Rect(draws[0],draws[1],20,20))
pygame.draw.rect(screen,color1,pygame.Rect(snaket[0],snaket[1], 20, 20))
pygame.display.flip()#让最近绘制的屏幕可见
游戏结束判断
#判断游戏结束
#触碰边境墙死亡
if snake[0] > 640 or snake[0] < 0:
gameover()
elif snake[1] > 480 or snake[1] < 0:
gameover()
#撞到身体死亡
for snakebodys in snakebody[1:]:
if snake[0]==snakebodys[0] and snake[1]==snakebodys[1]:
gameover()
这样,一个仅100多行代码的贪吃蛇游戏就基本完成了。
完整代码
import pygame
import sys
import random
#游戏结束函数
def gameover():
pygame.quit()#用于退出pygame模块
sys.exit()#用于退出程序
#各种颜色
color1=pygame.Color(255,2,2)#吃的方块的颜色
color2=pygame.Color(0,0,0)#背景颜色
color3=pygame.Color(255,100,100)#蛇的颜色
#入口函数
def main():
pygame.init()#初始化pygame
fpsClock=pygame.time.Clock()
screen=pygame.display.set_mode((640,480))#创建一个720x560的窗口
pygame.display.set_caption("python贪吃蛇")#将窗口命名为python贪吃蛇
#定义蛇的初始位置
snake=[100,100]
#初始为1段身体,每段间隔20个单位,以列表形式保存
snakebody=[[100,100]]
#定义蛇的移动方向,向300x300的方向移动
snaket=[300,300]
#标记方块,初始为1,吃掉后为0
cube=1
#初始化人为控制的按键方向,默认为向右
direction='right'
#人为控制的方向变量
cdirection=direction
#开始游戏循环
while True:
for event in pygame.event.get(): #队列中获取事件
if event.type==pygame.QUIT:#若点击右上角的x,则退出
gameover()
elif event.type==pygame.KEYDOWN:#注册热键,按键按下
if event.key==pygame.K_d:#按下d键,以下等同
cdirection='right'
#多个if判断,不用elif,防冲突
if event.key==pygame.K_a:
cdirection='left'
if event.key==pygame.K_w:
cdirection='up'
if event.key==pygame.K_s:
cdirection='down'
#确定蛇的方向
if cdirection =='left' and not direction =='right':
direction = cdirection
if cdirection =='right' and not direction =='left':
direction = cdirection
if cdirection =='up' and not direction =='down':
direction = cdirection
if cdirection =='down' and not direction =='up':
direction = cdirection
#根据方向移动蛇头,蛇头位置第一个位置加20
if direction =='right':
snake[0] +=20
if direction =='left':
snake[0] -=20
if direction =='up':
snake[1] -=20
if direction =='down':
snake[1] +=20
#增加蛇的长度
snakebody.insert(0,list(snake))#在尾部插入一段身体
#贪吃蛇和目标食物相互重叠的情况下(吃到食物情况下)
if snake[0]==snaket[0] and snake[1]==snaket[1]:
cube=0
else:
snakebody.pop()
if cube==0:
x=random.randrange(1,32)
y=random.randrange(1,24)
snaket=[int(x*20),int(y*20)]#防止随机生成的数值在蛇中间无法吃到
cube=1
#开始填充颜色
screen.fill(color2)
#开始绘图
for draws in snakebody:
#第一个参数指定一个编辑区,在这个区域内绘制
#第二个参数颜色
#第三个参数:rect:返回一个矩形(x和y),(宽,高)
pygame.draw.rect(screen,color3,pygame.Rect(draws[0],draws[1],20,20))
pygame.draw.rect(screen,color1,pygame.Rect(snaket[0],snaket[1], 20, 20))
pygame.display.flip()#让最近绘制的屏幕可见
#判断游戏结束
#触碰边境墙死亡
if snake[0] > 640 or snake[0] < 0:
gameover()
elif snake[1] > 480 or snake[1] < 0:
gameover()
#撞到身体死亡
for snakebodys in snakebody[1:]:
if snake[0]==snakebodys[0] and snake[1]==snakebodys[1]:
gameover()
#控制刷新频率,数值越大,刷新速度越快,蛇移动的速度也越快
fpsClock.tick(4)
#脚本函数
if __name__ =='__main__':
main()
结论
通过以上内容,我将一个贪吃蛇游戏的基本功能都实现了,但是,这样的代码其实并不是很美观,下一步,我打算用类和继承重构这个小游戏代码。并且,从上述代码可以看出,在游戏结束判断上,游戏结束的时候是直接调用结束函数,下一步,我将添加游戏结束提示“game over”,而不是直接退出程序,并且设置一个开始引导界面。这也是我将标题命名为贪吃蛇(一)的原因。
当然,具体什么时候重构贪吃蛇(二),我也不知道,因为人的本质就是懒(笑)。
没有评论