import pygame, sys, random
import pickle
from pygame.locals import *
初始化Pygame
pygame.init()
fpsClock = pygame.time.Clock()
设置窗口大小(放大比例)
SCALE_FACTOR = 2
WINDOW_WIDTH = 400 * SCALE_FACTOR
WINDOW_HEIGHT = 300 * SCALE_FACTOR
WINDOW = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('greedy snake')
定义颜色
BLACK = pygame.Color(0, 0, 0)
WHITE = pygame.Color(255, 255, 255)
RED = pygame.Color(255, 0, 0)
蛇的初始位置和身体(按比例放大)
snake_position = [100 * SCALE_FACTOR, 50 * SCALE_FACTOR]
snake_body = [[100 * SCALE_FACTOR, 50 * SCALE_FACTOR],
[90 * SCALE_FACTOR, 50 * SCALE_FACTOR],
[80 * SCALE_FACTOR, 50 * SCALE_FACTOR]]
食物的初始位置(按比例放大)
food_position = [300 * SCALE_FACTOR, 150 * SCALE_FACTOR]
food_spawn = True
is_big_food = False # 是否是大食物
big_food_timer = 0 # 大食物计时器
蛇的初始方向
direction = 'RIGHT'
change_to = direction
初始化积分和最高历史记录
score = 0
字体设置(按比例放大)
font = pygame.font.Font(None, 36 * SCALE_FACTOR)
start_font = pygame.font.Font(None, 24 * SCALE_FACTOR) # 开始面板的字体大小
游戏状态
game_paused = False
game_over = False
game_started = False
show_scores = False # 是否显示成绩列表
初始化食物出现次数
food_count = 0
初始化难度和速度
difficulty = 'medium'
speed = 12
初始化最高历史记录
high_scores = {
'easy': 0,
'medium': 0,
'hard': 0
}
def load_high_scores():
try:
with open('high_scores.pkl', 'rb') as file:
return pickle.load(file)
except FileNotFoundError:
return {'easy': 0, 'medium': 0, 'hard': 0}
except Exception as e:
print(f"Error loading high scores: {e}")
return {'easy': 0, 'medium': 0, 'hard': 0}
def save_high_scores(high_scores):
with open('high_scores.pkl', 'wb') as file:
pickle.dump(high_scores, file)
def game_over_screen():
global high_scores, game_over
if score > high_scores[difficulty]:
high_scores[difficulty] = score
save_high_scores(high_scores)
game_over = True
def spawn_food():
global food_position, food_spawn, food_count, is_big_food, big_food_timer
while True:
food_position = [random.randint(0, 39) * 10 * SCALE_FACTOR,
random.randint(0, 29) * 10 * SCALE_FACTOR]
if food_position not in snake_body and food_position[1] < WINDOW_HEIGHT - 100 * SCALE_FACTOR:
break
food_spawn = True
food_count += 1
if score >= 10 and food_count % 5 == 0:
is_big_food = True
big_food_timer = pygame.time.get_ticks() # 重置大食物计时器
else:
is_big_food = False
def pause_game():
global game_paused
game_paused = not game_paused
def restart_game():
global snake_position, snake_body, food_position, food_spawn, direction, change_to, score, game_over, food_count, game_started, is_big_food, big_food_timer
snake_position = [100 * SCALE_FACTOR, 50 * SCALE_FACTOR]
snake_body = [[100 * SCALE_FACTOR, 50 * SCALE_FACTOR],
[90 * SCALE_FACTOR, 50 * SCALE_FACTOR],
[80 * SCALE_FACTOR, 50 * SCALE_FACTOR]]
food_position = [300 * SCALE_FACTOR, 150 * SCALE_FACTOR]
food_spawn = True
direction = 'RIGHT'
change_to = direction
score = 0
game_over = False
food_count = 0
game_started = False
is_big_food = False
big_food_timer = 0
def start_game(selected_difficulty):
global game_started, difficulty, speed
game_started = True
difficulty = selected_difficulty
if difficulty == 'easy':
speed = 8
elif difficulty == 'medium':
speed = 12
elif difficulty == 'hard':
speed = 16
初始化最高历史记录
high_scores = load_high_scores()
游戏主循环
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if game_started:
if event.key == K_RIGHT or event.key == ord('d'):
change_to = 'RIGHT'
if event.key == K_LEFT or event.key == ord('a'):
change_to = 'LEFT'
if event.key == K_UP or event.key == ord('w'):
change_to = 'UP'
if event.key == K_DOWN or event.key == ord('s'):
change_to = 'DOWN'
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
if event.key == K_p:
pause_game()
if event.key == K_r:
restart_game()
else:
if event.key == ord('1'):
start_game('easy')
if event.key == ord('2'):
start_game('medium')
if event.key == ord('3'):
start_game('hard')
if event.key == ord('r'):
restart_game()
if event.key == ord('l'):
show_scores = True
if show_scores and event.key != ord('l'):
show_scores = False # 退出成绩列表界面
if game_started and not game_over:
# 防止蛇直接反向移动
if change_to == 'RIGHT' and not direction == 'LEFT':
direction = 'RIGHT'
if change_to == 'LEFT' and not direction == 'RIGHT':
direction = 'LEFT'
if change_to == 'UP' and not direction == 'DOWN':
direction = 'UP'
if change_to == 'DOWN' and not direction == 'UP':
direction = 'DOWN'
# 根据方向更新蛇头位置
if not game_paused:
if direction == 'RIGHT':
snake_position[0] += 10 * SCALE_FACTOR
if direction == 'LEFT':
snake_position[0] -= 10 * SCALE_FACTOR
if direction == 'UP':
snake_position[1] -= 10 * SCALE_FACTOR
if direction == 'DOWN':
snake_position[1] += 10 * SCALE_FACTOR
# 将蛇头的新位置插入到蛇身列表的开头
snake_body.insert(0, list(snake_position))
# 判断蛇是否吃到了食物
if is_big_food:
# 检测大食物的碰撞
if (snake_position[0] in range(food_position[0], food_position[0] + 20 * SCALE_FACTOR) and
snake_position[1] in range(food_position[1], food_position[1] + 20 * SCALE_FACTOR)):
score += 5
for _ in range(5):
snake_body.append(snake_body[-1])
food_spawn = False
else:
snake_body.pop()
else:
# 检测普通食物的碰撞
if snake_position[0] == food_position[0] and snake_position[1] == food_position[1]:
score += 1
food_spawn = False
else:
snake_body.pop()
# 如果食物消失,生成新的食物
if not food_spawn:
spawn_food()
# 检查大食物是否超时
if is_big_food and pygame.time.get_ticks() - big_food_timer >= 20000:
is_big_food = False
food_spawn = False
spawn_food()
# 填充背景色
WINDOW.fill(BLACK)
# 绘制游戏区域
game_area = pygame.Rect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT - 100 * SCALE_FACTOR)
pygame.draw.rect(WINDOW, WHITE, game_area, 1 * SCALE_FACTOR)
# 绘制蛇身
for pos in snake_body:
pygame.draw.rect(WINDOW, RED, pygame.Rect(pos[0], pos[1], 10 * SCALE_FACTOR, 10 * SCALE_FACTOR))
# 绘制食物
if is_big_food:
pygame.draw.rect(WINDOW, WHITE, pygame.Rect(food_position[0], food_position[1], 20 * SCALE_FACTOR, 20 * SCALE_FACTOR))
else:
pygame.draw.rect(WINDOW, WHITE, pygame.Rect(food_position[0], food_position[1], 10 * SCALE_FACTOR, 10 * SCALE_FACTOR))
# 绘制积分显示区域
score_area = pygame.Rect(0, WINDOW_HEIGHT - 100 * SCALE_FACTOR, WINDOW_WIDTH, 100 * SCALE_FACTOR)
pygame.draw.rect(WINDOW, WHITE, score_area, 1 * SCALE_FACTOR)
# 绘制积分
score_text = font.render(f"Score: {score}", True, WHITE)
WINDOW.blit(score_text, (10 * SCALE_FACTOR, WINDOW_HEIGHT - 80 * SCALE_FACTOR))
# 绘制最高历史记录
high_score_text = font.render(f"High Score ({difficulty}): {high_scores[difficulty]}", True, WHITE)
WINDOW.blit(high_score_text, (10 * SCALE_FACTOR, WINDOW_HEIGHT - 40 * SCALE_FACTOR))
# 判断蛇是否撞到了边界或自己的身体
if not game_paused:
if snake_position[0] >= WINDOW_WIDTH or snake_position[0] < 0:
game_over_screen()
if snake_position[1] >= WINDOW_HEIGHT - 100 * SCALE_FACTOR or snake_position[1] < 0:
game_over_screen()
for block in snake_body[1:]:
if snake_position[0] == block[0] and snake_position[1] == block[1]:
game_over_screen()
# 绘制暂停或游戏结束界面
if game_paused:
overlay = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT))
overlay.set_alpha(128) # 设置透明度
overlay.fill((0, 0, 0)) # 填充黑色
WINDOW.blit(overlay, (0, 0))
pause_text = font.render("stop", True, WHITE)
WINDOW.blit(pause_text, (WINDOW_WIDTH // 2 - pause_text.get_width() // 2, WINDOW_HEIGHT // 2 - pause_text.get_height() // 2))
resume_text = font.render("take R to continue", True, WHITE)
WINDOW.blit(resume_text, (WINDOW_WIDTH // 2 - resume_text.get_width() // 2, WINDOW_HEIGHT // 2 + resume_text.get_height()))
elif game_over:
# 绘制游戏结束界面
WINDOW.fill(BLACK)
game_over_text = font.render("game over", True, WHITE)
WINDOW.blit(game_over_text, (WINDOW_WIDTH // 2 - game_over_text.get_width() // 2, WINDOW_HEIGHT // 2 - game_over_text.get_height() // 2))
restart_text = font.render("take R to replay", True, WHITE)
WINDOW.blit(restart_text, (WINDOW_WIDTH // 2 - restart_text.get_width() // 2, WINDOW_HEIGHT // 2 + restart_text.get_height()))
elif show_scores:
# 绘制成绩列表界面
WINDOW.fill(BLACK)
title_text = font.render("High Scores", True, WHITE)
WINDOW.blit(title_text, (WINDOW_WIDTH // 2 - title_text.get_width() // 2, 50 * SCALE_FACTOR))
easy_score_text = font.render(f"Easy: {high_scores['easy']}", True, WHITE)
WINDOW.blit(easy_score_text, (WINDOW_WIDTH // 2 - easy_score_text.get_width() // 2, 100 * SCALE_FACTOR))
medium_score_text = font.render(f"Medium: {high_scores['medium']}", True, WHITE)
WINDOW.blit(medium_score_text, (WINDOW_WIDTH // 2 - medium_score_text.get_width() // 2, 150 * SCALE_FACTOR))
hard_score_text = font.render(f"Hard: {high_scores['hard']}", True, WHITE)
WINDOW.blit(hard_score_text, (WINDOW_WIDTH // 2 - hard_score_text.get_width() // 2, 200 * SCALE_FACTOR))
back_text = font.render("Press any key to go back", True, WHITE)
WINDOW.blit(back_text, (WINDOW_WIDTH // 2 - back_text.get_width() // 2, 250 * SCALE_FACTOR))
else:
# 绘制开始面板
WINDOW.fill(BLACK)
title_text = start_font.render("greedy snake", True, WHITE)
WINDOW.blit(title_text, (WINDOW_WIDTH // 2 - title_text.get_width() // 2, 50 * SCALE_FACTOR))
instruction_text = start_font.render("Choose difficulty: 1-Easy 2-Medium 3-Hard", True, WHITE)
WINDOW.blit(instruction_text, (WINDOW_WIDTH // 2 - instruction_text.get_width() // 2, 100 * SCALE_FACTOR))
list_text = start_font.render("Press L to view high scores", True, WHITE)
WINDOW.blit(list_text, (WINDOW_WIDTH // 2 - list_text.get_width() // 2, 150 * SCALE_FACTOR))
# 动态调整游戏速度
if difficulty == 'easy':
if score >= 50:
speed = 10
elif score >= 30:
speed = 9
elif score >= 10:
speed = 8
elif difficulty == 'medium':
if score >= 50:
speed = 14
elif score >= 30:
speed = 13
elif score >= 10:
speed = 12
elif difficulty == 'hard':
if score >= 50:
speed = 18
elif score >= 30:
speed = 17
elif score >= 10:
speed = 16
# 控制游戏帧率
fpsClock.tick(speed)
# 更新屏幕显示
pygame.display.update()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!