import pygame import random # 初始化 Pygame pygame.init() # 游戏窗口设置 WINDOW_X = 720 WINDOW_Y = 480 game_window = pygame.display.set_mode((WINDOW_X, WINDOW_Y)) pygame.display.set_caption('贪吃蛇游戏') # 颜色定义 BLACK = pygame.Color(0, 0, 0) WHITE = pygame.Color(255, 255, 255) RED = pygame.Color(255, 0, 0) GREEN = pygame.Color(0, 255, 0) # 游戏控制 FPS = pygame.time.Clock() FONT_SMALL = pygame.font.SysFont('simhei', 20) FONT_MEDIUM = pygame.font.SysFont('simhei', 30) FONT_LARGE = pygame.font.SysFont('simhei', 50) class SnakeGame: def __init__(self): self.reset_game() def reset_game(self): """重置游戏状态""" self.snake_position = [100, 50] self.snake_body = [[100, 50], [90, 50], [80, 50], [70, 50]] self.food_position = [ random.randrange(1, (WINDOW_X // 10)) * 10, random.randrange(1, (WINDOW_Y // 10)) * 10 ] self.food_spawn = True self.direction = 'RIGHT' self.change_to = self.direction self.score = 0 self.speed = 10 self.game_over_flag = False self.key_press_time = None def show_score(self, position=1): """显示当前分数""" score_surface = FONT_SMALL.render(f'分数 : {self.score}', True, WHITE) score_rect = score_surface.get_rect() if position == 1: score_rect.midtop = (WINDOW_X / 10, 15) else: score_rect.midtop = (WINDOW_X / 2, WINDOW_Y / 1.25) game_window.blit(score_surface, score_rect) def game_over(self): """显示游戏结束界面""" game_over_surface = FONT_LARGE.render(f'你的分数 : {self.score}', True, RED) game_over_rect = game_over_surface.get_rect() game_over_rect.midtop = (WINDOW_X / 2, WINDOW_Y / 4) game_window.blit(game_over_surface, game_over_rect) restart_surface = FONT_MEDIUM.render('按C键重新开始游戏', True, WHITE) restart_rect = restart_surface.get_rect() restart_rect.midtop = (WINDOW_X / 2, WINDOW_Y / 2) game_window.blit(restart_surface, restart_rect) pygame.display.flip() def handle_events(self): """处理用户输入事件""" for event in pygame.event.get(): if event.type == pygame.QUIT: return False if event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: self.change_to = 'UP' self.key_press_time = pygame.time.get_ticks() / 1000 if event.key == pygame.K_DOWN: self.change_to = 'DOWN' self.key_press_time = pygame.time.get_ticks() / 1000 if event.key == pygame.K_LEFT: self.change_to = 'LEFT' self.key_press_time = pygame.time.get_ticks() / 1000 if event.key == pygame.K_RIGHT: self.change_to = 'RIGHT' self.key_press_time = pygame.time.get_ticks() / 1000 if event.key == pygame.K_c and self.game_over_flag: self.reset_game() if event.type == pygame.KEYUP: self.key_press_time = None return True def update_speed(self): """根据按键时间调整蛇的速度""" if self.key_press_time: elapsed_time = pygame.time.get_ticks() / 1000 - self.key_press_time if elapsed_time < 0.5: self.speed = 15 elif elapsed_time < 1: self.speed = 20 else: self.speed = 25 else: self.speed = 10 def validate_direction(self): """确保蛇不能直接反向移动""" if self.change_to == 'UP' and self.direction != 'DOWN': self.direction = self.change_to if self.change_to == 'DOWN' and self.direction != 'UP': self.direction = self.change_to if self.change_to == 'LEFT' and self.direction != 'RIGHT': self.direction = self.change_to if self.change_to == 'RIGHT' and self.direction != 'LEFT': self.direction = self.change_to def move_snake(self): """移动蛇并处理碰撞检测""" # 根据方向移动蛇头 if self.direction == 'UP': self.snake_position[1] -= 10 if self.direction == 'DOWN': self.snake_position[1] += 10 if self.direction == 'LEFT': self.snake_position[0] -= 10 if self.direction == 'RIGHT': self.snake_position[0] += 10 # 蛇吃食物 self.snake_body.insert(0, list(self.snake_position)) if self.snake_position == self.food_position: self.score += 10 self.food_spawn = False else: self.snake_body.pop() # 生成新食物 if not self.food_spawn: self.food_position = [ random.randrange(1, (WINDOW_X // 10)) * 10, random.randrange(1, (WINDOW_Y // 10)) * 10 ] # 确保新食物不会出现在蛇身上 while self.food_position in self.snake_body: self.food_position = [ random.randrange(1, (WINDOW_X // 10)) * 10, random.randrange(1, (WINDOW_Y // 10)) * 10 ] self.food_spawn = True # 边界碰撞检测 if (self.snake_position[0] < 0 or self.snake_position[0] > WINDOW_X - 10 or self.snake_position[1] < 0 or self.snake_position[1] > WINDOW_Y - 10): self.game_over_flag = True # 自身碰撞检测 for block in self.snake_body[1:]: if self.snake_position == block: self.game_over_flag = True def draw(self): """绘制游戏元素""" game_window.fill(BLACK) # 绘制蛇身和食物 for pos in self.snake_body: pygame.draw.rect(game_window, GREEN, pygame.Rect(pos[0], pos[1], 10, 10)) pygame.draw.rect(game_window, WHITE, pygame.Rect(self.food_position[0], self.food_position[1], 10, 10)) # 显示分数 self.show_score(1) pygame.display.update() def run(self): """游戏主循环""" running = True while running: if self.game_over_flag: self.game_over() # 游戏结束后等待用户按键,不自动重置 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if event.type == pygame.KEYDOWN and event.key == pygame.K_c: self.reset_game() else: running = self.handle_events() if not running: break self.update_speed() self.validate_direction() self.move_snake() self.draw() FPS.tick(self.speed) pygame.quit() if __name__ == "__main__": game = SnakeGame() game.run()