Files
zeling_v2/Assets/Scripts/World/Map/MapPanel.cs
2026-05-12 15:34:08 +08:00

124 lines
4.5 KiB
C#
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.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using BaseGames.Core;
using BaseGames.Core.Events;
namespace BaseGames.World.Map
{
/// <summary>
/// 全屏地图 UI 面板(架构 15_MapShopModule §1.3)。
/// 由 UIManager PanelStack 管理开关OnEnable 时重建格子并订阅更新事件。
/// </summary>
public class MapPanel : MonoBehaviour
{
[SerializeField] private MapDatabaseSO _database;
[SerializeField] private RectTransform _roomContainer; // 格子图放置根节点
[SerializeField] private MapRoomCellUI _cellPrefab; // 地图格子预制
[Header("图标 Sprites")]
[SerializeField] private Sprite _iconSavePoint;
[SerializeField] private Sprite _iconBossRoom;
[SerializeField] private Sprite _iconShop;
[SerializeField] private Sprite _iconPlayerPos;
[Header("颜色")]
[SerializeField] private Color _colorDiscovered = Color.white;
[SerializeField] private Color _colorUndiscovered = Color.black;
[Header("Event Channels")]
[SerializeField] private StringEventChannelSO _onMapUpdated; // 房间发现时刷新
private Dictionary<string, MapRoomCellUI> _cells = new();
private readonly CompositeDisposable _subs = new();
private void OnEnable()
{
BuildGrid();
_onMapUpdated?.Subscribe(OnMapUpdated).AddTo(_subs);
}
private void OnDisable()
{
_subs.Clear();
// 清理动态生成的格子
foreach (var cell in _cells.Values)
if (cell != null) Destroy(cell.gameObject);
_cells.Clear();
}
// ── 内部 ──────────────────────────────────────────────────────────────
private void BuildGrid()
{
if (_database == null || _database.AllRooms == null) return;
var mapManager = ServiceLocator.GetOrDefault<IMapService>();
foreach (var room in _database.AllRooms)
{
if (room == null) continue;
var cell = Instantiate(_cellPrefab, _roomContainer);
bool discovered = mapManager != null && mapManager.IsExplored(room.RoomId);
cell.Setup(room, discovered, ChooseIcon(room));
_cells[room.RoomId] = cell;
}
}
private void OnMapUpdated(string roomId)
{
if (_cells.TryGetValue(roomId, out var cell))
cell.SetDiscovered(true);
}
private Sprite ChooseIcon(MapRoomDataSO room)
{
if (room.MapIconOverride != null) return room.MapIconOverride;
if (room.IsSavePoint) return _iconSavePoint;
if (room.IsBossRoom) return _iconBossRoom;
if (room.IsShop) return _iconShop;
return null;
}
}
// ─── 单个地图格子 UI ─────────────────────────────────────────────────────────
/// <summary>地图面板中每个房间对应的格子 UI 组件。</summary>
public class MapRoomCellUI : MonoBehaviour
{
[SerializeField] private Image _bg;
[SerializeField] private Image _icon;
private static readonly Color Discovered = Color.white;
private static readonly Color Undiscovered = Color.black;
/// <summary>初始化格子(位置、颜色、图标)。</summary>
public void Setup(MapRoomDataSO room, bool discovered, Sprite icon)
{
// 根据 GridPosition/GridSize 设置 RectTransform 位置与大小
if (TryGetComponent<RectTransform>(out var rt))
{
rt.anchoredPosition = new Vector2(
room.GridPosition.x * 32f,
room.GridPosition.y * 32f);
rt.sizeDelta = new Vector2(
room.GridSize.x * 32f,
room.GridSize.y * 32f);
}
SetDiscovered(discovered);
if (_icon != null)
{
_icon.sprite = icon;
_icon.enabled = icon != null;
}
}
public void SetDiscovered(bool v)
{
if (_bg != null) _bg.color = v ? Discovered : Undiscovered;
}
}
}