本人系python小白,这是我的第一篇博客,一路摸爬滚打,终于入了门。花了两天琢磨,写了这个超简单的容易理解的贪吃蛇游戏,给大家分享自己的理解吧。
简介:
1,老方法用pygame库来画背景,蛇,食物等等。
2,sys库控制程序窗口
3,random库来取随机数处理食物生成问题。
4,time库让游戏结束时短暂停顿后自动结束程序。
详解:
第一步:毋庸置疑肯定就是导入库
import pygame
import sys
import random
import time
第二步:创建游戏窗口等准备部分
pygame.init() # 初始化pygame库
size = (640, 480) # 设置窗口大小
screen = pygame.display.set_mode(size) # 初始化窗口
pygame.display.set_caption("The PPSnake") # 设置的窗口名称
snake_body = [[100, 100]] # 贪吃蛇初始长度只有一节(蛇头),提供是的坐标(x轴,y轴)
font = pygame.font.SysFont("SIMYOU.TTF", 80) # 由于会涉及到分数,所以设置字体格式
clock = pygame.time.Clock() # 控制运行速度,增加游戏乐趣,随着蛇的长度越长,速度越快
food_flag = 1 # 食物存在的标志
food_position = [300, 300] # 食物最初的位置
direction = '' # 存下方向变量
第三步:主循环搭建好
while True:
clock.tick(2*len(snake_body)+9) # 设置游戏速度,蛇长度越长,游戏速度越快
# 监视键盘事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit() #退出游戏
sys.exit() #退出程序
# 贪吃蛇移动方向标志
elif event.type == pygame.KEYDOWN:
if event.key == K_UP and direction != 'DOWN':
direction = 'UP'
if event.key == K_DOWN and direction != 'UP':
direction = 'DOWN'
if event.key == K_LEFT and direction != 'RIGHT':
direction = 'LEFT'
if event.key == K_RIGHT and direction != 'LEFT':
direction = 'RIGHT'
# snake移动
snake_move(snake_body)
# 判断食物存在
food_flag = food_judge(screen, food_position, food_flag)
# 判断食物是否被吃
food_eat(food_position, snake_body)
# 绘制分数
draw_score(screen, snake_body, font)
# 判断游戏结束, 只要蛇头超出屏幕就结束游戏
if snake_body[0][0] > screen.get_width() or snake_body[0][0] < 0:
GameOver(screen, font)
elif snake_body[0][1] > screen.get_height() or snake_body[0][0] < 0:
GameOver(screen, font)
# 这里的判断方法很特别,而且也很方便我自己认为,因为蛇在屏幕上是由一个一个正方形小格子构成
# 所以头咬到自己的身体至少说明蛇是5个正方形以上,因此我们从snak_body中从第4个元素起开始
# 查找,只要会咬到,蛇头的坐标就肯定出现在后面的列表中
elif snake_body[0] in snake_body[4:]:
GameOver(screen, font)
# 窗口背景色
screen.fill((125, 125, 125))
# 绘制贪吃蛇
draw_snake(screen, snake_body)
# 绘制食物
draw_food(screen, food_position)
第四步:实现各个功能
(1)snake移动:这里运用也比较巧妙,通过删除蛇的尾巴,和将要移动的方向,来找到新蛇头
的位置,然后通过列表操作,加入新的蛇头的坐标。这样就实现了蛇的移动,
而且又没有改变蛇的长度。(只要拿起笔算一算蛇的坐标很容易就理解了)
def snake_move(snake_body): # 因为靠蛇的首尾部分来实现移动,所以把蛇的长度传入函数中
global direction # direction是最初设置的存方向的变量,这里声明为全局变量
if direction == 'UP':
x = snake_body[0][0]
y = snake_body[0][1] - 10
snake_body.insert(0, [x, y]) # 加入新的蛇头
snake_body.pop(-1) # 删除尾巴
if direction == 'DOWN':
x = snake_body[0][0]
y = snake_body[0][1] + 10
snake_body.insert(0, [x, y])
snake_body.pop(-1)
if direction == 'LEFT':
x = snake_body[0][0] - 10
y = snake_body[0][1]
snake_body.insert(0, [x, y])
snake_body.pop(-1)
if direction == 'RIGHT':
x = snake_body[0][0] + 10
y = snake_body[0][1]
snake_body.insert(0, [x, y])
snake_body.pop(-1)
(2)food_eat部分:因为要判断食物是否被吃,也就是要判断蛇头与食物的位置是否重合,
所以把food_position(食物的位置), snake_body传入到函数中。这
里蛇吃到食物后变长也运用比较巧妙,记录下即将被删除的尾巴坐标,
判断吃到食物,然后就重新添加回到列表,这样自然就变长了一个长度
def food_eat(food_position, snake_body):
global food_flag # food_flag食物存在标志初始准备定义的,这里声明为全局变量
# 判断食物是否被吃
if food_position[0] == snake_body[0][0] and food_position[1] == snake_body[0][1]:
# 被吃后设置食物标志为0
food_flag = 0
# 记下即将被删除尾巴的坐标,然后给加回来用于增加一个长度
x = snake_body[-1][0]
y = snake_body[-1][1]
snake_body.insert(-1, [x, y])
(3)food_judge部分:首先判断是否食物存在,若不存在就用random库中的randint()函数重新
生成食物的位置,然后再画出食物,并把食物标志设置为1表示存在。
# 判断食物存在
if food_flag == 0:
# 重新生成食物并设置标志为1
food_position[0] = int(10 * random.randint(0, 64))
food_position[1] = int(10 * random.randint(4, 32))
pygame.draw.rect(screen, (255, 0, 0), (food_position[0], food_position[1], 10, 10))
food_flag = 1
return food_flag
(4)draw_snake部分:因为在屏幕上画出蛇,所以传入screen,snake_body两个参数到函数。
for循环遍历组成蛇的格子的坐标,screen屏幕,(255,255,255)是
蛇的颜色,i[0],i[1]是坐标,10,10是10*10像素的格子。
def draw_snake(screen, snake_body):
for i in snake_body:
pygame.draw.rect(screen, (255, 255, 255), (i[0], i[1], 10, 10))
(5)draw_food部分: 同理(4)
def draw_food(screen, food_position):
pygame.draw.rect(screen, (255, 0, 0), (food_position[0], food_position[1], 10, 10))
(6)draw_score部分:
def draw_score(screen, snake_body, font):
# 绘制分数
score_surf = font.render("%s" % (len(snake_body) - 1), True, (0, 0, 0)) # 创建字体对象
score_rect = score_surf.get_rect() # 获得字体对象的外接矩形
score_rect.midtop = (320, 0) # 设置矩形的位置
screen.blit(score_surf, score_rect) # 画出字体对象
pygame.display.flip() # 更新屏幕
(7)GameOver部分:
def GameOver(screen, font): 同理(6)
# 绘制游戏结束
Gameover_surf = font.render("Game Over", True, (0, 0, 0))
Gameover_rect = Gameover_surf.get_rect()
Gameover_rect.midtop = (320, 240)
screen.blit(Gameover_surf, Gameover_rect)
pygame.display.flip()
time.sleep(3) # 暂停3后退出
pygame.quit()
sys.exit()
最后:代码如下
import pygame
import sys
import random
import time
from pygame import K_LEFT, K_DOWN, K_UP, K_RIGHT
pygame.init() # 初始化pygame库
size = (640, 480) # 窗口大小
screen = pygame.display.set_mode(size) # 初始化窗口
pygame.display.set_caption("The PPSnake") # 窗口名称
snake_body = [[100, 100]] # 贪吃蛇初始长度
font = pygame.font.SysFont("SIMYOU.TTF", 80) # 设置字体格式
clock = pygame.time.Clock() # 控制运行速度
food_flag = 1 # 食物存在到标志
food_position = [300, 300] # 食物最初的位置
direction = '' # 方向
def snake_move(snake_body):
global direction
if direction == 'UP':
x = snake_body[0][0]
y = snake_body[0][1] - 10
snake_body.insert(0, [x, y])
snake_body.pop(-1)
if direction == 'DOWN':
x = snake_body[0][0]
y = snake_body[0][1] + 10
snake_body.insert(0, [x, y])
snake_body.pop(-1)
if direction == 'LEFT':
x = snake_body[0][0] - 10
y = snake_body[0][1]
snake_body.insert(0, [x, y])
snake_body.pop(-1)
if direction == 'RIGHT':
x = snake_body[0][0] + 10
y = snake_body[0][1]
snake_body.insert(0, [x, y])
snake_body.pop(-1)
def food_eat(food_position, snake_body):
global food_flag
# 判断食物是否被吃
if food_position[0] == snake_body[0][0] and food_position[1] == snake_body[0][1]:
# 被吃后设置标志为0
food_flag = 0
# 记下即将被删除尾巴的坐标,然后给加回来用于增加一个长度
x = snake_body[-1][0]
y = snake_body[-1][1]
snake_body.insert(-1, [x, y])
def food_judge(screen, food_position, food_flag):
# 判断食物存在
if food_flag == 0:
# 重新生成食物并设置标志为1
food_position[0] = int(10 * random.randint(0, 64))
food_position[1] = int(10 * random.randint(4, 32))
pygame.draw.rect(screen, (255, 0, 0), (food_position[0], food_position[1], 10, 10))
food_flag = 1
return food_flag
def draw_snake(screen, snake_body):
for i in snake_body:
pygame.draw.rect(screen, (255, 255, 255), (i[0], i[1], 10, 10))
def draw_food(screen, food_position):
pygame.draw.rect(screen, (255, 0, 0), (food_position[0], food_position[1], 10, 10))
def draw_score(screen, snake_body, font):
# 绘制分数
score_surf = font.render("%s" % (len(snake_body) - 1), True, (0, 0, 0)) # 创建字体对象
score_rect = score_surf.get_rect() # 获得字体对象的外接矩形
score_rect.midtop = (320, 0) # 设置矩形的位置
screen.blit(score_surf, score_rect) # 画出字体对象
pygame.display.flip()
def GameOver(screen, font):
# 绘制游戏结束
Gameover_surf = font.render("Game Over", True, (0, 0, 0))
Gameover_rect = Gameover_surf.get_rect()
Gameover_rect.midtop = (320, 240)
screen.blit(Gameover_surf, Gameover_rect)
pygame.display.flip()
time.sleep(3) # 暂停3后退出
pygame.quit()
sys.exit()
while True:
clock.tick(2*len(snake_body)+9) # 设置每秒运行的次数控制游戏速度
# 监视键盘事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 贪吃蛇移动方向标志
elif event.type == pygame.KEYDOWN:
if event.key == K_UP and direction != 'DOWN':
direction = 'UP'
if event.key == K_DOWN and direction != 'UP':
direction = 'DOWN'
if event.key == K_LEFT and direction != 'RIGHT':
direction = 'LEFT'
if event.key == K_RIGHT and direction != 'LEFT':
direction = 'RIGHT'
# snake移动
snake_move(snake_body)
# 判断食物存在
food_flag = food_judge(screen, food_position, food_flag)
# 判断食物是否被吃
food_eat(food_position, snake_body)
# 绘制分数
draw_score(screen, snake_body, font)
# 判断游戏结束
if snake_body[0][0] > screen.get_width() or snake_body[0][0] < 0:
GameOver(screen, font)
elif snake_body[0][1] > screen.get_height() or snake_body[0][0] < 0:
GameOver(screen, font)
elif snake_body[0] in snake_body[4:]:
GameOver(screen, font)
# 窗口背景色
screen.fill((125, 125, 125))
# 绘制贪吃蛇
draw_snake(screen, snake_body)
# 绘制食物
draw_food(screen, food_position)
后记:本人系初学者小白,尽自己最大努力写了这篇博客,这也是第一篇博客,希望自己的能力越来越好,对于代码能够挥刀自如,也希望用能够见证自己的成长。