main
HuangHai 4 months ago
parent e7d594fbdb
commit ecdc84e44a

@ -0,0 +1,256 @@
import pygame
import random
import os
# 初始化 Pygame
pygame.init()
# 设置窗口尺寸
cell_size = 20 # 单元格大小
grid_width = 30 # 网格宽度
grid_height = 20 # 网格高度
window_width = grid_width * cell_size
window_height = grid_height * cell_size
window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("迷宫游戏")
# 设置颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
# 设置时钟
clock = pygame.time.Clock()
# 加载胜利动画帧
frames = []
frame_folder = "frames" # 确保这个文件夹存在并包含PNG图片
if os.path.exists(frame_folder):
for frame_file in sorted(os.listdir(frame_folder)):
if frame_file.endswith(".png"):
frame = pygame.image.load(os.path.join(frame_folder, frame_file))
# 等比例缩放帧图片
frame_width, frame_height = frame.get_size()
scale_factor = min(window_width / frame_width, window_height / frame_height) * 0.8 # 缩小一点以便显示文字
scaled_frame = pygame.transform.scale(frame,
(int(frame_width * scale_factor), int(frame_height * scale_factor)))
frames.append(scaled_frame)
else:
print(f"警告: 文件夹 '{frame_folder}' 不存在,将不显示胜利动画")
# 设置字体(使用支持中文的字体文件)
try:
font_path = "c:/Windows/Fonts/simhei.ttf" # 替换为你的中文字体文件路径
font = pygame.font.Font(font_path, 36) # 使用中文字体,字号 36
except:
print("无法加载指定字体,使用默认字体")
font = pygame.font.Font(None, 36) # 使用默认字体
# 生成随机迷宫
def generate_maze(width, height):
# 初始化迷宫,所有单元格都是墙壁
maze = [[1 for _ in range(width)] for _ in range(height)]
# 确保入口和出口是通道
maze[0][0] = 0
maze[height - 1][width - 1] = 0
# 使用深度优先搜索生成迷宫
def carve_passages(x, y):
# 随机选择方向
directions = [(0, 2), (2, 0), (0, -2), (-2, 0)]
random.shuffle(directions)
for dx, dy in directions:
nx, ny = x + dx, y + dy
# 检查是否在边界内
if 0 <= nx < width and 0 <= ny < height:
# 如果目标单元格是墙壁
if maze[ny][nx] == 1:
# 打通墙壁
maze[ny][nx] = 0
# 打通中间的墙壁
maze[y + dy // 2][x + dx // 2] = 0
# 递归处理下一个单元格
carve_passages(nx, ny)
# 从入口开始生成迷宫
carve_passages(0, 0)
# 确保出口附近有通道
maze[height - 2][width - 1] = 0
maze[height - 1][width - 2] = 0
return maze
# 生成迷宫
maze = generate_maze(grid_width, grid_height)
# 定义小人类
class Character:
def __init__(self, grid_x, grid_y):
self.grid_x = grid_x # 小人的网格 x 坐标
self.grid_y = grid_y # 小人的网格 y 坐标
self.x = grid_x * cell_size + cell_size // 2 # 小人的像素 x 坐标
self.y = grid_y * cell_size + cell_size // 2 # 小人的像素 y 坐标
self.radius = cell_size // 3 - 1 # 稍微减小半径,避免卡住
self.speed = 3 # 移动速度
self.collision_margin = 2 # 碰撞检测的边缘余量
def move(self, dx, dy):
# 计算目标位置
new_x = self.x + dx
new_y = self.y + dy
# 检测是否与墙壁碰撞
if self.will_collide(new_x, new_y):
# 尝试单独移动 X 或 Y 方向
if dx != 0 and not self.will_collide(new_x, self.y):
new_y = self.y # 只移动 X 方向
elif dy != 0 and not self.will_collide(self.x, new_y):
new_x = self.x # 只移动 Y 方向
else:
return # 两个方向都不能移动
# 更新位置
self.x = new_x
self.y = new_y
self.grid_x = self.x // cell_size
self.grid_y = self.y // cell_size
def will_collide(self, x, y):
# 计算碰撞检测的实际半径
collision_radius = self.radius - self.collision_margin
# 检测小球是否会与墙壁碰撞
# 计算小球边缘的四个点
points = [
(x - collision_radius, y), # 左
(x + collision_radius, y), # 右
(x, y - collision_radius), # 上
(x, y + collision_radius) # 下
]
# 检测每个点是否在墙壁内
for px, py in points:
# 计算点所在的网格位置
grid_x = int(px // cell_size)
grid_y = int(py // cell_size)
# 检测是否超出边界
if grid_x < 0 or grid_x >= grid_width or grid_y < 0 or grid_y >= grid_height:
return True
# 检测是否与墙壁碰撞
if maze[grid_y][grid_x] == 1:
return True
return False
def draw(self, window):
# 绘制小人(红色小球)
pygame.draw.circle(window, RED, (self.x, self.y), self.radius)
# 创建小人对象(初始位置在左上角)
character = Character(0, 0)
# 设置出口位置
exit_grid_x = grid_width - 1
exit_grid_y = grid_height - 1
# 游戏状态
game_state = "playing" # "playing", "victory"
current_frame = 0
victory_time = 0
# 主循环
running = True
while running:
# 处理事件
for event in pygame.event.get():
if event.type == pygame.QUIT: # 检测窗口关闭事件
running = False
elif event.type == pygame.KEYDOWN and game_state == "victory":
if event.key == pygame.K_RETURN: # 按回车键重新开始游戏
game_state = "playing"
maze = generate_maze(grid_width, grid_height)
character = Character(0, 0)
# 游戏逻辑
if game_state == "playing":
# 检测键盘持续按下状态
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]: # 按下上箭头键
character.move(0, -character.speed)
if keys[pygame.K_DOWN]: # 按下下箭头键
character.move(0, character.speed)
if keys[pygame.K_LEFT]: # 按下左箭头键
character.move(-character.speed, 0)
if keys[pygame.K_RIGHT]: # 按下右箭头键
character.move(character.speed, 0)
# 检测是否到达出口
exit_x = exit_grid_x * cell_size + cell_size // 2
exit_y = exit_grid_y * cell_size + cell_size // 2
if abs(character.x - exit_x) < cell_size // 2 and abs(character.y - exit_y) < cell_size // 2:
print("胜利!")
game_state = "victory"
victory_time = pygame.time.get_ticks()
current_frame = 0
# 清空屏幕
window.fill(WHITE)
if game_state == "playing":
# 绘制迷宫
for i in range(grid_height):
for j in range(grid_width):
if maze[i][j] == 1: # 绘制墙壁
pygame.draw.rect(window, BLACK, (j * cell_size, i * cell_size, cell_size, cell_size))
# 绘制出口
exit_x = exit_grid_x * cell_size + cell_size // 2
exit_y = exit_grid_y * cell_size + cell_size // 2
pygame.draw.circle(window, GREEN, (exit_x, exit_y), cell_size // 3)
# 绘制小人
character.draw(window)
elif game_state == "victory":
# 绘制胜利动画
if frames: # 如果有加载动画帧
# 将帧居中显示
frame_width, frame_height = frames[current_frame].get_size()
x = (window_width - frame_width) // 2
y = (window_height - frame_height) // 2
window.blit(frames[current_frame], (x, y))
# 更新帧索引
if pygame.time.get_ticks() - victory_time > 100: # 每100毫秒更新一次帧
current_frame = (current_frame + 1) % len(frames)
victory_time = pygame.time.get_ticks()
# 绘制胜利文字
victory_text = font.render("胜利!", True, (255, 0, 0)) # 红色文字
text_rect = victory_text.get_rect(center=(window_width // 2, window_height - 50))
window.blit(victory_text, text_rect)
# 绘制提示文字
restart_text = font.render("按回车键重新开始", True, (0, 0, 0)) # 黑色文字
restart_rect = restart_text.get_rect(center=(window_width // 2, window_height - 20))
window.blit(restart_text, restart_rect)
# 更新屏幕
pygame.display.flip()
# 控制帧率
clock.tick(60)
# 退出 Pygame
pygame.quit()
Loading…
Cancel
Save