import pygame import random import sys # 初始化pygame pygame.init() # 游戏常量 WINDOW_WIDTH = 600 WINDOW_HEIGHT = 600 GRID_SIZE = 20 GRID_WIDTH = WINDOW_WIDTH // GRID_SIZE GRID_HEIGHT = WINDOW_HEIGHT // GRID_SIZE # 颜色定义 BLACK = (0, 0, 0) WHITE = (255, 255, 255) RED = (255, 0, 0) GREEN = (0, 255, 0) DARK_GREEN = (0, 200, 0) GRAY = (128, 128, 128) # 方向常量 UP = (0, -1) DOWN = (0, 1) LEFT = (-1, 0) RIGHT = (1, 0) class Snake: def __init__(self): # 初始蛇身(三个方块) self.positions = [ (GRID_WIDTH // 2, GRID_HEIGHT // 2), (GRID_WIDTH // 2 - 1, GRID_HEIGHT // 2), (GRID_WIDTH // 2 - 2, GRID_HEIGHT // 2) ] self.direction = RIGHT self.grow_flag = False def move(self): head = self.positions[0] new_head = (head[0] + self.direction[0], head[1] + self.direction[1]) # 插入新头部 self.positions.insert(0, new_head) # 如果不生长,删除尾部 if not self.grow_flag: self.positions.pop() else: self.grow_flag = False return new_head def grow(self): self.grow_flag = True def change_direction(self, new_direction): # 防止蛇反向移动 if (new_direction[0] * -1, new_direction[1] * -1) != self.direction: self.direction = new_direction def check_collision(self): head = self.positions[0] # 检查是否撞墙 if (head[0] < 0 or head[0] >= GRID_WIDTH or head[1] < 0 or head[1] >= GRID_HEIGHT): return True # 检查是否撞到自己 if head in self.positions[1:]: return True return False class Food: def __init__(self): self.position = (0, 0) self.randomize_position([]) def randomize_position(self, snake_positions): while True: pos = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1)) if pos not in snake_positions: self.position = pos break class Game: def __init__(self): self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) pygame.display.set_caption("贪吃蛇游戏") self.clock = pygame.time.Clock() self.font = pygame.font.Font(None, 36) self.big_font = pygame.font.Font(None, 48) self.reset_game() def reset_game(self): self.snake = Snake() self.food = Food() self.food.randomize_position(self.snake.positions) self.score = 0 self.game_over = False self.game_speed = 10 def handle_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: return False if event.type == pygame.KEYDOWN: if self.game_over: if event.key == pygame.K_SPACE: self.reset_game() elif event.key == pygame.K_ESCAPE: return False else: if event.key == pygame.K_UP or event.key == pygame.K_w: self.snake.change_direction(UP) elif event.key == pygame.K_DOWN or event.key == pygame.K_s: self.snake.change_direction(DOWN) elif event.key == pygame.K_LEFT or event.key == pygame.K_a: self.snake.change_direction(LEFT) elif event.key == pygame.K_RIGHT or event.key == pygame.K_d: self.snake.change_direction(RIGHT) return True def update(self): if self.game_over: return # 移动蛇 new_head = self.snake.move() # 检查是否吃到食物 if new_head == self.food.position: self.snake.grow() self.score += 10 self.food.randomize_position(self.snake.positions) # 加快游戏速度 if self.score % 50 == 0: self.game_speed += 1 # 检查碰撞 if self.snake.check_collision(): self.game_over = True def draw_grid(self): for x in range(0, WINDOW_WIDTH, GRID_SIZE): pygame.draw.line(self.screen, GRAY, (x, 0), (x, WINDOW_HEIGHT), 1) for y in range(0, WINDOW_HEIGHT, GRID_SIZE): pygame.draw.line(self.screen, GRAY, (0, y), (WINDOW_WIDTH, y), 1) def draw(self): self.screen.fill(BLACK) self.draw_grid() # 绘制蛇 for i, pos in enumerate(self.snake.positions): rect = pygame.Rect( pos[0] * GRID_SIZE, pos[1] * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1 ) if i == 0: pygame.draw.rect(self.screen, GREEN, rect) else: pygame.draw.rect(self.screen, DARK_GREEN, rect) # 绘制食物 food_rect = pygame.Rect( self.food.position[0] * GRID_SIZE, self.food.position[1] * GRID_SIZE, GRID_SIZE - 1, GRID_SIZE - 1 ) pygame.draw.rect(self.screen, RED, food_rect) # 显示分数 score_text = self.font.render(f"分数: {self.score}", True, WHITE) self.screen.blit(score_text, (10, 10)) # 游戏结束画面 if self.game_over: overlay = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT)) overlay.set_alpha(128) overlay.fill(BLACK) self.screen.blit(overlay, (0, 0)) game_over_text = self.big_font.render("游戏结束!", True, WHITE) score_text = self.font.render(f"最终分数: {self.score}", True, WHITE) restart_text = self.font.render("按空格键重新开始", True, WHITE) exit_text = self.font.render("按ESC键退出", True, WHITE) text_rect = game_over_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 - 50)) self.screen.blit(game_over_text, text_rect) text_rect = score_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2)) self.screen.blit(score_text, text_rect) text_rect = restart_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 + 40)) self.screen.blit(restart_text, text_rect) text_rect = exit_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 + 70)) self.screen.blit(exit_text, text_rect) pygame.display.flip() def run(self): running = True while running: running = self.handle_events() self.update() self.draw() self.clock.tick(self.game_speed) pygame.quit() sys.exit() # 运行游戏 if __name__ == "__main__": game = Game() game.run()