maze_python/save_ui.py

205 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import pygame
from config import *
class SaveLoadUI:
"""存档和读档界面"""
def __init__(self, font):
self.font = font
self.small_font = pygame.font.Font(FONT_FILE, FONT_SIZE - 4)
self.show_save_list = False
self.save_list = []
self.selected_save = -1
self.scroll_offset = 0
self.max_visible_saves = 8
# 双击检测
self.last_click_time = 0
self.last_clicked_index = -1
self.double_click_threshold = 500 # 毫秒
# 界面元素
button_positions = get_button_positions()
self.list_area = pygame.Rect(*button_positions['save_list_area'])
self.save_input = ""
self.input_active = False
def update_save_list(self, maze):
"""更新存档列表"""
self.save_list = maze.get_save_list()
def toggle_save_list(self):
"""切换存档列表显示状态"""
self.show_save_list = not self.show_save_list
if not self.show_save_list:
self.selected_save = -1
self.input_active = False
def handle_event(self, event, maze):
"""处理界面事件"""
if not self.show_save_list:
return None
if event.type == pygame.KEYDOWN:
if self.input_active:
if event.key == pygame.K_RETURN:
# 保存游戏
if self.save_input.strip():
result = maze.save_game(self.save_input.strip())
if result:
self.update_save_list(maze)
self.save_input = ""
self.input_active = False
return "save_success"
return "save_failed"
elif event.key == pygame.K_ESCAPE:
self.input_active = False
self.save_input = ""
elif event.key == pygame.K_BACKSPACE:
self.save_input = self.save_input[:-1]
else:
if len(self.save_input) < 20: # 限制输入长度
self.save_input += event.unicode
else:
if event.key == pygame.K_UP:
if self.selected_save > 0:
self.selected_save -= 1
elif event.key == pygame.K_DOWN:
if self.selected_save < len(self.save_list) - 1:
self.selected_save += 1
elif event.key == pygame.K_RETURN:
# 加载选中的存档
if 0 <= self.selected_save < len(self.save_list):
save_file = self.save_list[self.selected_save]['path']
if maze.load_game(save_file):
# 加载成功后检查是否需要重新生成路径
if len(maze.full_path) == 0 and maze.generater.maze:
# 只有当没有路径信息时才重新生成
from SourceCollector import SourceCollector
maze.source_collector = SourceCollector(maze=maze.generater.maze)
maze.source_collector.run()
maze.full_path = maze.source_collector.get_path()
maze.path_step = 0
maze.is_path_complete = False
# 不要重置grid保持加载的包含路径的网格
print(f"已为加载的存档重新生成路径,路径长度: {len(maze.full_path)}")
self.show_save_list = False
return "load_success"
return "load_failed"
elif event.key == pygame.K_DELETE:
# 删除选中的存档
if 0 <= self.selected_save < len(self.save_list):
save_file = self.save_list[self.selected_save]['path']
from simple_save_manager import simple_save_manager
if simple_save_manager.delete_save(save_file):
self.update_save_list(maze)
if self.selected_save >= len(self.save_list):
self.selected_save = len(self.save_list) - 1
return "delete_success"
elif event.key == pygame.K_n:
# 新建存档
self.input_active = True
self.save_input = ""
elif event.key == pygame.K_ESCAPE:
self.toggle_save_list()
elif event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 1: # 左键点击
mouse_pos = pygame.mouse.get_pos()
# 检查是否点击在存档列表区域
if self.list_area.collidepoint(mouse_pos):
# 计算点击的存档索引
relative_y = mouse_pos[1] - self.list_area.y - 30 # 减去标题高度
if relative_y >= 0:
clicked_index = relative_y // 25 # 每个存档项25像素高
if 0 <= clicked_index < len(self.save_list):
current_time = pygame.time.get_ticks()
# 检查是否为双击
if (clicked_index == self.last_clicked_index and
current_time - self.last_click_time < self.double_click_threshold):
# 双击加载存档
save_file = self.save_list[clicked_index]['path']
if maze.load_game(save_file):
# 加载成功后检查是否需要重新生成路径
if len(maze.full_path) == 0 and maze.generater.maze:
# 只有当没有路径信息时才重新生成
from SourceCollector import SourceCollector
maze.source_collector = SourceCollector(maze=maze.generater.maze)
maze.source_collector.run()
maze.full_path = maze.source_collector.get_path()
maze.path_step = 0
maze.is_path_complete = False
# 不要重置grid保持加载的包含路径的网格
print(f"已为加载的存档重新生成路径,路径长度: {len(maze.full_path)}")
self.show_save_list = False
return "load_success"
return "load_failed"
else:
# 单击选择
self.selected_save = clicked_index
self.last_clicked_index = clicked_index
self.last_click_time = current_time
else:
# 点击外部关闭界面
self.toggle_save_list()
return None
def draw(self, screen):
"""绘制存档界面"""
if not self.show_save_list:
return
# 绘制半透明背景
overlay = pygame.Surface((UI_WIDTH, UI_HEIGHT))
overlay.set_alpha(128)
overlay.fill((0, 0, 0))
screen.blit(overlay, (0, 0))
# 绘制存档列表背景
pygame.draw.rect(screen, COLOR_WHITE, self.list_area)
pygame.draw.rect(screen, COLOR_BLACK, self.list_area, 2)
# 绘制标题
title_text = self.font.render("存档管理", True, COLOR_BLACK)
screen.blit(title_text, (self.list_area.x + 10, self.list_area.y + 5))
# 绘制操作说明
if self.input_active:
hint_text = self.small_font.render("输入存档名称(.csv按回车保存:", True, COLOR_BLACK)
screen.blit(hint_text, (self.list_area.x + 10, self.list_area.y + 30))
# 绘制输入框
input_rect = pygame.Rect(self.list_area.x + 10, self.list_area.y + 50, 300, 25)
pygame.draw.rect(screen, COLOR_WHITE, input_rect)
pygame.draw.rect(screen, COLOR_BLACK, input_rect, 2)
input_text = self.small_font.render(self.save_input + "|", True, COLOR_BLACK)
screen.blit(input_text, (input_rect.x + 5, input_rect.y + 5))
else:
hint_text = self.small_font.render("↑↓选择 回车/双击加载 Delete删除 N新建 ESC关闭", True, COLOR_BLACK)
screen.blit(hint_text, (self.list_area.x + 10, self.list_area.y + 30))
# 绘制存档列表
start_y = self.list_area.y + 55
for i, save_info in enumerate(self.save_list):
y_pos = start_y + i * 25
if y_pos > self.list_area.bottom - 25:
break
# 高亮选中项
if i == self.selected_save:
highlight_rect = pygame.Rect(self.list_area.x + 5, y_pos - 2, self.list_area.width - 10, 22)
pygame.draw.rect(screen, COLOR_GRAY, highlight_rect)
# 显示存档信息
save_text = f"{save_info['name']} - {save_info['save_time'][:16]}"
text_surface = self.small_font.render(save_text, True, COLOR_BLACK)
screen.blit(text_surface, (self.list_area.x + 10, y_pos))
# 如果没有存档,显示提示
if not self.save_list and not self.input_active:
no_save_text = self.small_font.render("没有找到存档文件", True, COLOR_LIGHT_GRAY)
screen.blit(no_save_text, (self.list_area.x + 10, self.list_area.y + 60))