213 lines
9.0 KiB
Python
213 lines
9.0 KiB
Python
import pygame
|
|
from pygame import Surface
|
|
from pygame.constants import QUIT
|
|
from maze import Maze
|
|
|
|
from draw import Button, Toast
|
|
from save_ui import SaveLoadUI
|
|
from config import *
|
|
import sys
|
|
import os
|
|
|
|
screen: Surface = None # 窗口实例
|
|
clock = None # 时钟实例
|
|
|
|
textFont = None # 字体
|
|
|
|
|
|
def pygameInit(title: str = "pygame"):
|
|
"""初始化 pygame"""
|
|
pygame.init()
|
|
pygame.mixer.init() # 声音初始化
|
|
pygame.display.set_caption(title)
|
|
global screen, clock, textFont # 修改全局变量
|
|
screen = pygame.display.set_mode((UI_WIDTH, UI_HEIGHT))
|
|
clock = pygame.time.Clock()
|
|
# Initialize font with UTF-8 support
|
|
pygame.font.init()
|
|
textFont = pygame.font.Font(FONT_FILE, FONT_SIZE)
|
|
|
|
if __name__ == "__main__":
|
|
pygameInit("maze")
|
|
maze = Maze(wall_size=WALL_SIZE, maze_size=MAZE_SIZE, file_name=DEFAULT_MAZE_FILE)
|
|
|
|
# 加载图片资源
|
|
image_wall = pygame.image.load(WALL_IMAGE).convert_alpha()
|
|
image_wall = pygame.transform.scale(image_wall, (WALL_SIZE, WALL_SIZE))
|
|
|
|
image_coin = pygame.image.load(COIN_IMAGE).convert_alpha()
|
|
image_coin = pygame.transform.scale(image_coin, (WALL_SIZE, WALL_SIZE))
|
|
|
|
image_trap = pygame.image.load(TRAP_IMAGE).convert_alpha()
|
|
image_trap = pygame.transform.scale(image_trap, (WALL_SIZE, WALL_SIZE))
|
|
|
|
# 获取按钮位置配置
|
|
button_positions = get_button_positions()
|
|
|
|
# 创建按钮
|
|
button_start_texture = pygame.image.load(START_BUTTON_IMAGE).convert_alpha()
|
|
button_start_texture = pygame.transform.scale(button_start_texture, BUTTON_START_SIZE)
|
|
button_start = Button(pygame.rect.Rect(*button_positions['start_button'], *BUTTON_START_SIZE), button_start_texture)
|
|
|
|
button_save_texture = pygame.image.load(SAVE_BUTTON_IMAGE).convert_alpha()
|
|
button_save_texture = pygame.transform.scale(button_save_texture, BUTTON_SAVE_SIZE)
|
|
button_save = Button(pygame.rect.Rect(*button_positions['save_button'], *BUTTON_SAVE_SIZE), button_save_texture)
|
|
|
|
button_load_texture = pygame.image.load(LOAD_BUTTON_IMAGE).convert_alpha()
|
|
button_load_texture = pygame.transform.scale(button_load_texture, BUTTON_SAVE_SIZE)
|
|
button_load = Button(pygame.rect.Rect(*button_positions['load_button'], *BUTTON_SAVE_SIZE), button_load_texture)
|
|
|
|
# 添加路径控制按钮
|
|
button_next_step = Button(pygame.rect.Rect(*button_positions['next_step_button'], *BUTTON_CONTROL_SIZE), None)
|
|
button_reset_path = Button(pygame.rect.Rect(*button_positions['reset_path_button'], *BUTTON_CONTROL_SIZE), None)
|
|
button_auto_play = Button(pygame.rect.Rect(*button_positions['auto_play_button'], *BUTTON_CONTROL_SIZE), None)
|
|
|
|
# 提示信息
|
|
mes1 = Toast("没有生成迷宫,无法保存", UI_WIDTH, UI_HEIGHT, font=textFont)
|
|
mes2 = Toast("迷宫已保存", UI_WIDTH, UI_HEIGHT, font=textFont)
|
|
mes3 = Toast("存档已保存", UI_WIDTH, UI_HEIGHT, font=textFont)
|
|
mes4 = Toast("存档加载成功", UI_WIDTH, UI_HEIGHT, font=textFont)
|
|
mes5 = Toast("加载失败", UI_WIDTH, UI_HEIGHT, font=textFont)
|
|
|
|
# 创建存档界面
|
|
save_ui = SaveLoadUI(textFont)
|
|
|
|
# 路径控制变量
|
|
auto_play = False
|
|
auto_play_timer = 0
|
|
auto_play_interval = AUTO_PLAY_INTERVAL
|
|
|
|
running = True
|
|
while running:
|
|
clock.tick(FPS) # 限制帧数
|
|
screen.fill(COLOR_WHITE) # 铺底
|
|
|
|
# 自动播放逻辑
|
|
if auto_play and len(maze.full_path) > 0:
|
|
auto_play_timer += 1
|
|
if auto_play_timer >= auto_play_interval:
|
|
if not maze.next_path_step():
|
|
auto_play = False # 路径播放完成后停止自动播放
|
|
auto_play_timer = 0
|
|
|
|
for event in pygame.event.get():
|
|
# 首先让存档界面处理事件
|
|
save_result = save_ui.handle_event(event, maze)
|
|
if save_result == "save_success":
|
|
mes3.show()
|
|
elif save_result == "load_success":
|
|
mes4.show()
|
|
auto_play = False # 加载游戏后停止自动播放
|
|
elif save_result == "load_failed":
|
|
mes5.show()
|
|
|
|
# 如果存档界面正在显示,不处理其他按钮事件
|
|
if not save_ui.show_save_list:
|
|
button_start.handle_event(event=event)
|
|
button_save.handle_event(event=event)
|
|
button_load.handle_event(event=event)
|
|
button_next_step.handle_event(event=event)
|
|
button_reset_path.handle_event(event=event)
|
|
button_auto_play.handle_event(event=event)
|
|
|
|
if button_start.pressed == True:
|
|
maze.generate()
|
|
auto_play = False # 生成新迷宫时停止自动播放
|
|
|
|
if button_save.pressed == True:
|
|
if len(maze.grid) == 0:
|
|
mes1.show()
|
|
else:
|
|
maze.export_to_csv(DEFAULT_MAZE_FILE)
|
|
mes2.text = f"迷宫已保存至{DEFAULT_MAZE_FILE}"
|
|
mes2.show()
|
|
|
|
if button_load.pressed == True:
|
|
save_ui.update_save_list(maze)
|
|
save_ui.toggle_save_list()
|
|
|
|
# 路径控制
|
|
if button_next_step.pressed == True and len(maze.full_path) > 0:
|
|
maze.next_path_step()
|
|
|
|
if button_reset_path.pressed == True and len(maze.full_path) > 0:
|
|
maze.reset_path()
|
|
auto_play = False
|
|
|
|
if button_auto_play.pressed == True and len(maze.full_path) > 0:
|
|
auto_play = not auto_play
|
|
auto_play_timer = 0
|
|
|
|
# 键盘控制
|
|
if event.type == pygame.KEYDOWN:
|
|
if event.key == pygame.K_SPACE and len(maze.full_path) > 0:
|
|
maze.next_path_step()
|
|
elif event.key == pygame.K_r and len(maze.full_path) > 0:
|
|
maze.reset_path()
|
|
auto_play = False
|
|
elif event.key == pygame.K_a and len(maze.full_path) > 0:
|
|
auto_play = not auto_play
|
|
auto_play_timer = 0
|
|
elif event.key == pygame.K_s and pygame.key.get_pressed()[pygame.K_LCTRL]:
|
|
# Ctrl+S 保存包含路径的CSV
|
|
if len(maze.grid) > 0:
|
|
result = maze.save_game()
|
|
if result:
|
|
mes3.show()
|
|
elif event.key == pygame.K_l and pygame.key.get_pressed()[pygame.K_LCTRL]:
|
|
# Ctrl+L 打开读档界面
|
|
save_ui.update_save_list(maze)
|
|
save_ui.toggle_save_list()
|
|
|
|
if event.type == QUIT:
|
|
running = False
|
|
|
|
|
|
maze.draw(screen=screen, wall_texture=image_wall, coin_texture=image_coin, trap_texture=image_trap)
|
|
button_start.draw(screen=screen)
|
|
button_save.draw(screen=screen)
|
|
button_load.draw(screen=screen)
|
|
|
|
# 绘制路径控制按钮
|
|
if len(maze.full_path) > 0:
|
|
# 绘制按钮背景
|
|
pygame.draw.rect(screen, COLOR_GRAY, button_next_step.rect)
|
|
pygame.draw.rect(screen, COLOR_GRAY, button_reset_path.rect)
|
|
pygame.draw.rect(screen, COLOR_GREEN if auto_play else COLOR_GRAY, button_auto_play.rect)
|
|
|
|
# 绘制按钮文字
|
|
next_text = textFont.render("下一步", True, COLOR_BLACK)
|
|
reset_text = textFont.render("重置", True, COLOR_BLACK)
|
|
auto_text = textFont.render("自动播放" if not auto_play else "停止", True, COLOR_BLACK)
|
|
|
|
screen.blit(next_text, (button_next_step.rect.x + 10, button_next_step.rect.y + 15))
|
|
screen.blit(reset_text, (button_reset_path.rect.x + 25, button_reset_path.rect.y + 15))
|
|
screen.blit(auto_text, (button_auto_play.rect.x + 5, button_auto_play.rect.y + 15))
|
|
|
|
# 显示当前步数信息
|
|
progress_text = textFont.render(f"路径进度: {maze.path_step}/{len(maze.full_path)}", True, COLOR_BLACK)
|
|
screen.blit(progress_text, button_positions['progress_text'])
|
|
|
|
# 显示操作提示
|
|
if len(maze.full_path) > 0:
|
|
hint_text = textFont.render("空格键: 下一步 | R键: 重置 | A键: 自动播放", True, COLOR_LIGHT_GRAY)
|
|
screen.blit(hint_text, button_positions['hint_text'])
|
|
|
|
# 显示快捷键提示
|
|
shortcut_text = textFont.render("Ctrl+S: 保存包含路径的CSV | Ctrl+L: 读档", True, COLOR_LIGHT_GRAY)
|
|
screen.blit(shortcut_text, (MAZE_SIZE + 50, 330))
|
|
|
|
mes1.draw(screen=screen)
|
|
mes2.draw(screen=screen)
|
|
mes3.draw(screen=screen)
|
|
mes4.draw(screen=screen)
|
|
mes5.draw(screen=screen)
|
|
|
|
# 绘制存档界面(必须在最后绘制以显示在最上层)
|
|
save_ui.draw(screen)
|
|
pygame.display.flip()
|
|
pygame.quit()
|
|
|
|
|
|
|
|
|