机器人
积分排行榜
Scratch
积分排行榜
Python
在线答题
积分排行榜
活跃排行榜
打字练习
Microbit
C++
在线答题
积分排行榜
活跃排行榜
网盘
积分
未登录
未登录
登录学习
作者:
陈果
更新时间:
2025-05-21 21:39
浏览:
13次
点赞:
0次
热度:
20
import pygame import sys import random import time # 初始化pygame pygame.init() # 确保中文正常显示 pygame.font.init() font_path = pygame.font.match_font('simsun') or pygame.font.match_font('simhei') if not font_path: # 如果找不到中文字体,使用默认字体 font_path = pygame.font.get_default_font() # 游戏常量 SCREEN_WIDTH = 800 SCREEN_HEIGHT = 600 GRID_SIZE = 20 GRID_WIDTH = SCREEN_WIDTH // GRID_SIZE GRID_HEIGHT = SCREEN_HEIGHT // GRID_SIZE # 颜色定义 BLACK = (0, 0, 0) WHITE = (255, 255, 255) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) YELLOW = (255, 255, 0) GRAY = (200, 200, 200) # 方向定义 UP = (0, -1) DOWN = (0, 1) LEFT = (-1, 0) RIGHT = (1, 0) class Snake: def __init__(self): self.reset() def reset(self): self.length = 3 self.positions = [(GRID_WIDTH // 2, GRID_HEIGHT // 2)] self.direction = RIGHT self.last_direction = self.direction self.color = GREEN self.head_color = BLUE self.score = 0 self.grow_pending = 2 # 初始长度为3 def get_head_position(self): return self.positions[0] def turn(self, new_direction): # 确保蛇不能直接反向移动 if (new_direction[0] * -1, new_direction[1] * -1) == self.last_direction: return self.direction = new_direction def move(self): self.last_direction = self.direction head = self.get_head_position() x, y = self.direction new_x = (head[0] + x) % GRID_WIDTH new_y = (head[1] + y) % GRID_HEIGHT new_head = (new_x, new_y) # 检查是否撞到自己 if new_head in self.positions[1:]: return False self.positions.insert(0, new_head) if self.grow_pending > 0: self.grow_pending -= 1 else: self.positions.pop() return True def grow(self, amount=1): self.grow_pending += amount self.score += 10 * amount def draw(self, surface): for i, p in enumerate(self.positions): rect = pygame.Rect((p[0] * GRID_SIZE, p[1] * GRID_SIZE), (GRID_SIZE, GRID_SIZE)) if i == 0: # 蛇头 pygame.draw.rect(surface, self.head_color, rect) # 眼睛 eye_size = GRID_SIZE // 5 if self.direction == RIGHT: pygame.draw.circle(surface, WHITE, (p[0] * GRID_SIZE + 3*GRID_SIZE//4, p[1] * GRID_SIZE + GRID_SIZE//3), eye_size) pygame.draw.circle(surface, WHITE, (p[0] * GRID_SIZE + 3*GRID_SIZE//4, p[1] * GRID_SIZE + 2*GRID_SIZE//3), eye_size) elif self.direction == LEFT: pygame.draw.circle(surface, WHITE, (p[0] * GRID_SIZE + GRID_SIZE//4, p[1] * GRID_SIZE + GRID_SIZE//3), eye_size) pygame.draw.circle(surface, WHITE, (p[0] * GRID_SIZE + GRID_SIZE//4, p[1] * GRID_SIZE + 2*GRID_SIZE//3), eye_size) elif self.direction == UP: pygame.draw.circle(surface, WHITE, (p[0] * GRID_SIZE + GRID_SIZE//3, p[1] * GRID_SIZE + GRID_SIZE//4), eye_size) pygame.draw.circle(surface, WHITE, (p[0] * GRID_SIZE + 2*GRID_SIZE//3, p[1] * GRID_SIZE + GRID_SIZE//4), eye_size) elif self.direction == DOWN: pygame.draw.circle(surface, WHITE, (p[0] * GRID_SIZE + GRID_SIZE//3, p[1] * GRID_SIZE + 3*GRID_SIZE//4), eye_size) pygame.draw.circle(surface, WHITE, (p[0] * GRID_SIZE + 2*GRID_SIZE//3, p[1] * GRID_SIZE + 3*GRID_SIZE//4), eye_size) else: # 蛇身 # 蛇身体的渐变色效果 color_factor = 1 - min(i / len(self.positions), 0.7) body_color = ( int(self.color[0] * color_factor), int(self.color[1] * color_factor), int(self.color[2] * color_factor) ) pygame.draw.rect(surface, body_color, rect) # 蛇身体的边框 pygame.draw.rect(surface, BLACK, rect, 1) class Food: def __init__(self): self.position = (0, 0) self.color = RED self.special_color = YELLOW self.randomize_position() self.is_special = False self.spawn_time = 0 self.special_duration = 5000 # 特殊食物持续5秒 def randomize_position(self): self.position = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1)) self.is_special = random.random() < 0.2 # 20%概率生成特殊食物 if self.is_special: self.spawn_time = pygame.time.get_ticks() def draw(self, surface): rect = pygame.Rect((self.position[0] * GRID_SIZE, self.position[1] * GRID_SIZE), (GRID_SIZE, GRID_SIZE)) if self.is_special: # 检查特殊食物是否过期 current_time = pygame.time.get_ticks() if current_time - self.spawn_time > self.special_duration: self.randomize_position() return # 闪烁效果 if (current_time // 300) % 2 == 0: pygame.draw.rect(surface, self.special_color, rect) else: pygame.draw.rect(surface, self.color, rect) # 特殊食物的星星形状 points = [ (self.position[0] * GRID_SIZE + GRID_SIZE // 2, self.position[1] * GRID_SIZE), (self.position[0] * GRID_SIZE + GRID_SIZE * 3 // 4, self.position[1] * GRID_SIZE + GRID_SIZE * 2 // 5), (self.position[0] * GRID_SIZE + GRID_SIZE, self.position[1] * GRID_SIZE + GRID_SIZE * 2 // 5), (self.position[0] * GRID_SIZE + GRID_SIZE * 3 // 4, self.position[1] * GRID_SIZE + GRID_SIZE * 3 // 5), (self.position[0] * GRID_SIZE + GRID_SIZE, self.position[1] * GRID_SIZE + GRID_SIZE * 3 // 5), (self.position[0] * GRID_SIZE + GRID_SIZE // 2, self.position[1] * GRID_SIZE + GRID_SIZE), (self.position[0] * GRID_SIZE + GRID_SIZE // 4, self.position[1] * GRID_SIZE + GRID_SIZE * 3 // 5), (self.position[0] * GRID_SIZE, self.position[1] * GRID_SIZE + GRID_SIZE * 3 // 5), (self.position[0] * GRID_SIZE + GRID_SIZE // 4, self.position[1] * GRID_SIZE + GRID_SIZE * 2 // 5), (self.position[0] * GRID_SIZE, self.position[1] * GRID_SIZE + GRID_SIZE * 2 // 5), ] pygame.draw.polygon(surface, YELLOW, points) else: pygame.draw.rect(surface, self.color, rect) pygame.draw.rect(surface, BLACK, rect, 1) class Game: def __init__(self): self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("贪吃蛇游戏") self.clock = pygame.time.Clock() self.snake = Snake() self.food = Food() self.state = "START" # START, PLAYING, GAME_OVER self.speed = 10 self.max_speed = 20 self.speed_increase = 0.5 self.last_move_time = 0 self.move_interval = 1000 / self.speed # 毫秒 def handle_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if self.state == "START": if event.key == pygame.K_SPACE: self.state = "PLAYING" elif self.state == "PLAYING": if event.key == pygame.K_UP: self.snake.turn(UP) elif event.key == pygame.K_DOWN: self.snake.turn(DOWN) elif event.key == pygame.K_LEFT: self.snake.turn(LEFT) elif event.key == pygame.K_RIGHT: self.snake.turn(RIGHT) elif event.key == pygame.K_p: self.state = "PAUSED" elif self.state == "GAME_OVER": if event.key == pygame.K_r: self.reset() elif event.key == pygame.K_q: pygame.quit() sys.exit() elif self.state == "PAUSED": if event.key == pygame.K_p: self.state = "PLAYING" def update(self): if self.state != "PLAYING": return current_time = pygame.time.get_ticks() # 根据分数调整速度 self.speed = min(self.max_speed, self.speed_increase * (self.snake.score // 100) + 10) self.move_interval = 1000 / self.speed if current_time - self.last_move_time > self.move_interval: if not self.snake.move(): self.state = "GAME_OVER" self.last_move_time = current_time # 检查是否吃到食物 if self.snake.get_head_position() == self.food.position: if self.food.is_special: self.snake.grow(3) # 特殊食物增加3个长度 else: self.snake.grow() self.food.randomize_position() # 确保新生成的食物不会出现在蛇身上 while self.food.position in self.snake.positions: self.food.randomize_position() def draw(self): self.screen.fill(BLACK) if self.state == "START": self.draw_start_screen() elif self.state == "PLAYING": self.draw_game_screen() elif self.state == "GAME_OVER": self.draw_game_over_screen() elif self.state == "PAUSED": self.draw_pause_screen() pygame.display.update() def draw_start_screen(self): title_font = pygame.font.Font(font_path, 72) sub_font = pygame.font.Font(font_path, 36) small_font = pygame.font.Font(font_path, 24) title = title_font.render("贪吃蛇游戏", True, WHITE) start_text = sub_font.render("按空格键开始游戏", True, WHITE) controls_text = small_font.render("方向键控制蛇的移动", True, WHITE) pause_text = small_font.render("按 P 键暂停游戏", True, WHITE) title_rect = title.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//3)) start_rect = start_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2)) controls_rect = controls_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT*2//3)) pause_rect = pause_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT*3//4)) self.screen.blit(title, title_rect) self.screen.blit(start_text, start_rect) self.screen.blit(controls_text, controls_rect) self.screen.blit(pause_text, pause_rect) # 绘制示例蛇 snake_example = Snake() snake_example.positions = [(5, 15), (4, 15), (3, 15), (2, 15)] snake_example.direction = RIGHT snake_example.draw(self.screen) # 绘制示例食物 food_example = Food() food_example.position = (8, 15) food_example.draw(self.screen) special_food_example = Food() special_food_example.position = (11, 15) special_food_example.is_special = True special_food_example.draw(self.screen) food_text = small_font.render("普通食物", True, WHITE) special_food_text = small_font.render("特殊食物(+3分)", True, WHITE) food_text_rect = food_text.get_rect(center=(8*GRID_SIZE + GRID_SIZE//2, 17*GRID_SIZE)) special_food_text_rect = special_food_text.get_rect(center=(11*GRID_SIZE + GRID_SIZE//2, 17*GRID_SIZE)) self.screen.blit(food_text, food_text_rect) self.screen.blit(special_food_text, special_food_text_rect) def draw_game_screen(self): # 绘制网格背景 for x in range(0, SCREEN_WIDTH, GRID_SIZE): for y in range(0, SCREEN_HEIGHT, GRID_SIZE): rect = pygame.Rect(x, y, GRID_SIZE, GRID_SIZE) if (x // GRID_SIZE + y // GRID_SIZE) % 2 == 0: pygame.draw.rect(self.screen, (30, 30, 30), rect) else: pygame.draw.rect(self.screen, (25, 25, 25), rect) # 绘制蛇和食物 self.snake.draw(self.screen) self.food.draw(self.screen) # 绘制分数和速度 font = pygame.font.Font(font_path, 24) score_text = font.render(f"分数: {self.snake.score}", True, WHITE) speed_text = font.render(f"速度: {int(self.speed)}", True, WHITE) self.screen.blit(score_text, (10, 10)) self.screen.blit(speed_text, (10, 40)) # 绘制暂停提示 pause_font = pygame.font.Font(font_path, 18) pause_text = pause_font.render("按 P 键暂停", True, GRAY) self.screen.blit(pause_text, (SCREEN_WIDTH - 120, 10)) def draw_game_over_screen(self): self.draw_game_screen() # 继续显示游戏画面 # 半透明遮罩 overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA) overlay.fill((0, 0, 0, 180)) self.screen.blit(overlay, (0, 0)) # 游戏结束文本 font = pygame.font.Font(font_path, 72) game_over_text = font.render("游戏结束", True, RED) game_over_rect = game_over_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//3)) self.screen.blit(game_over_text, game_over_rect) # 最终分数 score_font = pygame.font.Font(font_path, 36) score_text = score_font.render(f"最终分数: {self.snake.score}", True, WHITE) score_rect = score_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2)) self.screen.blit(score_text, score_rect) # 重新开始和退出提示 small_font = pygame.font.Font(font_path, 24) restart_text = small_font.render("按 R 键重新开始", True, WHITE) quit_text = small_font.render("按 Q 键退出", True, WHITE) restart_rect = restart_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT*2//3)) quit_rect = quit_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT*3//4)) self.screen.blit(restart_text, restart_rect) self.screen.blit(quit_text, quit_rect) def draw_pause_screen(self): # 半透明遮罩 overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA) overlay.fill((0, 0, 0, 150)) self.screen.blit(overlay, (0, 0)) # 暂停文本 font = pygame.font.Font(font_path, 72) pause_text = font.render("游戏暂停", True, WHITE) pause_rect = pause_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2)) self.screen.blit(pause_text, pause_rect) # 继续提示 small_font = pygame.font.Font(font_path, 24) continue_text = small_font.render("按 P 键继续", True, WHITE) continue_rect = continue_text.get_rect(center=(SCREEN_WIDTH//2, SCREEN_HEIGHT*3//4)) self.screen.blit(continue_text, continue_rect) def reset(self): self.snake.reset() self.food.randomize_position() self.state = "START" self.speed = 10 def run(self): while True: self.handle_events() self.update() self.draw() self.clock.tick(60) if __name__ == "__main__": game = Game() game.run()
点赞成功
分享作品
×