上代码
import pygame
import sys
import random
import math
# 初始化pygame
pygame.init()
# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (213, 50, 80)
GREEN = (0, 255, 0)
BLUE = (50, 153, 213)
BUTTON_COLOR = (100, 100, 255)
BUTTON_HOVER_COLOR = (150, 150, 255)
# 屏幕设置
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('贪吃蛇游戏 - 可穿透自己版')
# 游戏时钟
clock = pygame.time.Clock()
# 蛇的参数
SNAKE_SIZE = 15
SNAKE_SPEED = 20
# 字体设置
font_small = pygame.font.SysFont("simhei", 25)
font_medium = pygame.font.SysFont("simhei", 35)
font_large = pygame.font.SysFont("simhei", 50)
# 按钮类
class Button:
def __init__(self, x, y, width, height, text):
self.rect = pygame.Rect(x, y, width, height)
self.text = text
self.is_hovered = False
def draw(self, surface):
color = BUTTON_HOVER_COLOR if self.is_hovered else BUTTON_COLOR
pygame.draw.rect(surface, color, self.rect, border_radius=10)
pygame.draw.rect(surface, BLACK, self.rect, 2, border_radius=10)
text = font_medium.render(self.text, True, BLACK)
text_rect = text.get_rect(center=self.rect.center)
surface.blit(text, text_rect)
def check_hover(self, pos):
self.is_hovered = self.rect.collidepoint(pos)
return self.is_hovered
def is_clicked(self, pos, event):
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
return self.rect.collidepoint(pos)
return False
# 显示分数
def show_score(score):
score_text = font_medium.render(f"得分: {score}", True, BLACK)
screen.blit(score_text, [10, 10])
# 绘制蛇
def draw_snake(snake_body):
for i, segment in enumerate(snake_body):
color = BLUE if i == 0 else GREEN # 蛇头蓝色,身体绿色
pygame.draw.rect(screen, color, [segment[0], segment[1], SNAKE_SIZE, SNAKE_SIZE])
# 显示消息
def show_message(text, color, y_offset=0, font=font_medium):
msg = font.render(text, True, color)
screen.blit(msg, [SCREEN_WIDTH // 2 - msg.get_width() // 2, SCREEN_HEIGHT // 3 + y_offset])
# 计算两点距离
def get_distance(x1, y1, x2, y2):
return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
# 主菜单
def show_menu():
start_button = Button(SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT // 2, 200, 50, "开始游戏")
while True:
screen.fill(WHITE)
mouse_pos = pygame.mouse.get_pos()
# 显示标题
title = font_large.render("贪吃蛇游戏", True, BLACK)
screen.blit(title, [SCREEN_WIDTH // 2 - title.get_width() // 2, 100])
# 显示游戏说明
show_message("用鼠标控制蛇的移动", BLACK, -50, font_small)
show_message("吃到红色食物增加长度", BLACK, -10, font_small)
show_message("可以穿过自己的身体", BLACK, 30, font_small)
# 更新按钮状态
start_button.check_hover(mouse_pos)
start_button.draw(screen)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if start_button.is_clicked(mouse_pos, event):
return # 开始游戏
pygame.display.update()
clock.tick(60)
# 游戏主循环
def game_loop():
game_active = True
# 初始化蛇的位置
snake_x = SCREEN_WIDTH // 2
snake_y = SCREEN_HEIGHT // 2
# 蛇的身体
snake_body = []
snake_length = 1
# 食物位置
food_x = round(random.randrange(0, SCREEN_WIDTH - SNAKE_SIZE) / SNAKE_SIZE) * SNAKE_SIZE
food_y = round(random.randrange(0, SCREEN_HEIGHT - SNAKE_SIZE) / SNAKE_SIZE) * SNAKE_SIZE
while game_active:
mouse_pos = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
return # 返回菜单
# 计算蛇向鼠标移动的方向
dx = mouse_pos[0] - snake_x
dy = mouse_pos[1] - snake_y
dist = get_distance(snake_x, snake_y, mouse_pos[0], mouse_pos[1])
if dist > 5: # 如果距离够远才移动
# 标准化方向向量
dx /= dist
dy /= dist
# 更新蛇头位置
snake_x += dx * SNAKE_SIZE * 0.5
snake_y += dy * SNAKE_SIZE * 0.5
# 确保不会超出屏幕
snake_x = max(0, min(SCREEN_WIDTH - SNAKE_SIZE, snake_x))
snake_y = max(0, min(SCREEN_HEIGHT - SNAKE_SIZE, snake_y))
# 更新蛇身
snake_head = [snake_x, snake_y]
snake_body.append(snake_head)
if len(snake_body) > snake_length:
del snake_body[0]
# 绘制游戏
screen.fill(WHITE)
# 绘制食物
pygame.draw.rect(screen, RED, [food_x, food_y, SNAKE_SIZE, SNAKE_SIZE])
# 绘制蛇
draw_snake(snake_body)
# 显示分数
show_score(snake_length - 1)
pygame.display.update()
# 检查是否吃到食物
if (abs(snake_x - food_x) < SNAKE_SIZE and abs(snake_y - food_y) < SNAKE_SIZE):
food_x = round(random.randrange(0, SCREEN_WIDTH - SNAKE_SIZE) / SNAKE_SIZE) * SNAKE_SIZE
food_y = round(random.randrange(0, SCREEN_HEIGHT - SNAKE_SIZE) / SNAKE_SIZE) * SNAKE_SIZE
snake_length += 1
clock.tick(SNAKE_SPEED)
# 游戏结束画面
while not game_active:
screen.fill(WHITE)
show_message("游戏结束!", RED, -50, font_large)
show_message(f"得分: {snake_length - 1}", BLACK, 0)
show_message("按ESC键返回主菜单", BLACK, 50)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
return
pygame.display.update()
clock.tick(60)
# 游戏主循环
while True:
show_menu()
game_loop()