相信不少人都在以前的翻盖手机玩过贪吃蛇吧,相信现在长大的同学们也已经步入了计算机这个行业了。见多了c++写的贪吃蛇小项目,今天旺仔带你从原理思考,窗口化手把手教会你用python写一个贪吃蛇的实战项目。
效果图展示:
所需标准库
- time:用于控制游戏的帧率或延时,比如让蛇移动得更慢或更快。
- random:用来随机生成食物的位置。
- sys:通常用来退出游戏。
-
pygame :Pygame是一个广泛使用的Python库,专为开发视频游戏设计。它提供了大量的功能,包括图像、声音、事件处理等,并且非常易于使用。使用Pygame可以方便地创建窗口、绘制图形(如蛇的身体)以及处理用户输入。
以上就是我们所需要准备的四种库函数:
在终端进行安装下载
pip install pygame
pip install random
pip install sys
pip install time
实现框架
在pycharm中先创建一个贪吃蛇的项目,新建一个.py后缀的文件,就可以编写代码了!
导入所需要的库函数
import pygame
import random
import sys
import time
-
游戏窗口和初始化设置
这段代码进行了初始化,游戏窗口大小和蛇的颜色设定,可以根据自己的爱好更改变量设置窗口大小和蛇的颜色和形状
# 初始化 pygame
pygame.init()
# 游戏窗口大小
WINDOW_WIDTH = 640
WINDOW_HEIGHT = 480
CELL_SIZE = 20
# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
SNAKE_COLOR = (0, 155, 0) # 更深的绿色
FOOD_COLOR = (255, 0, 0) # 红色
# 设置窗口大小
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("贪吃蛇")
-
帧率设置
正常速度为10,但是当我们长按方向键超过0.3秒时就会让蛇的速度翻倍达到20,提高蛇吃到果子的效率
# 设置帧率
FPS = 10 # 正常速度
SPEED_UP_FPS = 20 # 加速后的速度
ACCELERATION_THRESHOLD = 0.3 # 按住0.3秒后开始加速
# 记录方向键按下时间
key_press_time = None
-
游戏逻辑
让我们思考以下,完成一个贪吃蛇需要实现拿一些功能呢?
1. 蛇和食物初始化位置
使用random函数确保蛇的位置和果子的位置都时随机出现在任何位置
2.位置移动
可进行上下左右移动,但不可以直接与原来相反的反向移动,长按方向超过设定时间,蛇就会加速
3.吃果子逻辑
在蛇头与果子的重叠或者无线靠近时,吃掉果子,并且自身长度+1,然后随机重新刷新果子(但新生成的果子不可以在蛇身上),并且得分+1
4.结束逻辑
在碰到墙壁或者碰到自身则游戏结束
以下是剩下的代码:
# 蛇初始位置
snake_pos = [[100, 50], [90, 50], [80, 50]]
snake_direction = 'RIGHT'
# 食物位置
food_pos = [
random.randrange(1, (WINDOW_WIDTH // CELL_SIZE)) * CELL_SIZE,
random.randrange(1, (WINDOW_HEIGHT // CELL_SIZE)) * CELL_SIZE
]
# 分数
score = 0
# 游戏主循环
def game_loop():
global snake_direction, food_pos, score, key_press_time, FPS
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# 处理按键按下事件
if event.type == pygame.KEYDOWN:
if key_press_time is None: # 第一次按下时记录时间
key_press_time = time.time()
if event.key == pygame.K_UP and snake_direction != 'DOWN':
snake_direction = 'UP'
if event.key == pygame.K_DOWN and snake_direction != 'UP':
snake_direction = 'DOWN'
if event.key == pygame.K_LEFT and snake_direction != 'RIGHT':
snake_direction = 'LEFT'
if event.key == pygame.K_RIGHT and snake_direction != 'LEFT':
snake_direction = 'RIGHT'
# 检测按键松开事件,松开时恢复正常速度
if event.type == pygame.KEYUP:
key_press_time = None # 重置按键按下时间
FPS = 10 # 恢复正常速度
# 检测按键按下的时间是否超过加速阈值
if key_press_time:
time_held = time.time() - key_press_time
if time_held > ACCELERATION_THRESHOLD:
FPS = SPEED_UP_FPS # 如果按下超过0.3秒,蛇加速
# 更新蛇的位置
if snake_direction == 'UP':
new_head = [snake_pos[0][0], snake_pos[0][1] - CELL_SIZE]
elif snake_direction == 'DOWN':
new_head = [snake_pos[0][0], snake_pos[0][1] + CELL_SIZE]
elif snake_direction == 'LEFT':
new_head = [snake_pos[0][0] - CELL_SIZE, snake_pos[0][1]]
elif snake_direction == 'RIGHT':
new_head = [snake_pos[0][0] + CELL_SIZE, snake_pos[0][1]]
# 检查是否碰到墙壁
if (new_head[0] < 0 or new_head[0] >= WINDOW_WIDTH or
new_head[1] < 0 or new_head[1] >= WINDOW_HEIGHT):
game_over()
# 检查蛇是否碰到自己
if new_head in snake_pos[1:]:
game_over()
# 更新蛇的位置
snake_pos.insert(0, new_head)
# 吃到食物
if abs(snake_pos[0][0] - food_pos[0]) < CELL_SIZE and abs(snake_pos[0][1] - food_pos[1]) < CELL_SIZE:
score += 1
food_pos = generate_food(snake_pos) # 生成新的食物
else:
snake_pos.pop() # 移除尾部
# 绘制屏幕
window.fill(BLACK)
# 绘制食物
pygame.draw.circle(window, FOOD_COLOR, (food_pos[0] + CELL_SIZE // 2, food_pos[1] + CELL_SIZE // 2), CELL_SIZE // 2)
# 绘制蛇
for pos in snake_pos:
pygame.draw.circle(window, SNAKE_COLOR, (pos[0] + CELL_SIZE // 2, pos[1] + CELL_SIZE // 2), CELL_SIZE // 2)
# 显示分数
font = pygame.font.SysFont(None, 35)
text = font.render(f"Score: {score}", True, WHITE)
window.blit(text, (10, 10))
# 更新屏幕
pygame.display.flip()
# 控制帧率
clock.tick(FPS)
def generate_food(snake_pos):
"""生成新的食物位置,确保食物不会出现在蛇身上"""
while True:
food_pos = [
random.randrange(1, (WINDOW_WIDTH // CELL_SIZE)) * CELL_SIZE,
random.randrange(1, (WINDOW_HEIGHT // CELL_SIZE)) * CELL_SIZE
]
if food_pos not in snake_pos:
return food_pos
def game_over():
font = pygame.font.SysFont(None, 75)
text = font.render("Game Over!", True, RED)
window.blit(text, (150, 200))
pygame.display.flip()
pygame.time.wait(2000)
pygame.quit()
sys.exit()
# 启动游戏
game_loop()