VirtualFramework/Assets/Scripts/UI/UIImageSelectMap.cs

282 lines
9.8 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using QFramework;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using System;
using TMPro;
using System.Xml;
using System.Linq;
namespace QFramework.Example
{
public class UIImageSelectMapData : UIPanelData
{
public class OptionItem
{
public string pic;
public string name;
}
public class Row
{
public string name;
public List<OptionItem> items = new List<OptionItem>();
}
public string scoreName;
public float totalScore;
public float rightScore;
public float wrongScore;
public string rightLabel;
public string wrongLabel;
public string finishedEvent;
public bool random = false;
public List<Row> rows = new List<Row>();
}
public partial class UIImageSelectMap : UIPanel
{
/// <summary>
/// 右侧数据结构
/// </summary>
class RightDataItem
{
public GameObject rightObj;
public bool isRight = false;
}
ResLoader loader;
GameObject moveObj;
GameObject enterRight;
GameObject leftDragObj;
Dictionary<GameObject, UIImageSelectMapData.OptionItem> itemDatas = new Dictionary<GameObject, UIImageSelectMapData.OptionItem>();
Dictionary<GameObject, RightDataItem> leftAndRightMap = new Dictionary<GameObject, RightDataItem>();
// 新增:存储分类行对象和数据的映射
Dictionary<GameObject, UIImageSelectMapData.Row> rowMap = new Dictionary<GameObject, UIImageSelectMapData.Row>();
protected override void OnInit(IUIData uiData = null)
{
mData = uiData as UIImageSelectMapData ?? new UIImageSelectMapData();
TypeEventSystem.Global.Register<OnModuleQuit>(OnModuleQuitHandler);
// please add init code here
loader = ResLoader.Allocate();
}
protected override void OnOpen(IUIData uiData = null)
{
mData = uiData as UIImageSelectMapData ?? new UIImageSelectMapData();
LeftContent.RemoveAllChildren();
RightContent.RemoveAllChildren();
itemDatas.Clear();
leftAndRightMap.Clear();
rowMap.Clear(); // 清空行映射
foreach (var row in mData.rows)
{
GameObject rowObj = GameObject.Instantiate(RightRowItem.gameObject, RightContent);
var typeText = rowObj.transform.Find("Type").GetComponent<TextMeshProUGUI>();
typeText.text = row.name.Replace("\\n", "\n");
rowObj.name = row.name.Replace("\\n", "\n");
Transform itemContent = rowObj.transform.Find("Items");
// 存储行对象和数据的映射
rowMap.Add(rowObj, row);
foreach (var item in row.items)
{
var rightObj = GameObject.Instantiate(RightItem, itemContent);
var nameText = rightObj.transform.Find("Name").GetComponent<TextMeshProUGUI>();
nameText.text = item.name;
nameText.color = Color.white;
rightObj.name = item.name;
rightObj.transform.Find("PicBg/Pic").GetComponent<Image>().color = new Color(1, 1, 1, 0);
rightObj.OnPointerEnterEvent(RightOnEnter);
rightObj.OnPointerExitEvent(RightOnExit);
rightObj.OnPointerClickEvent(RightOnClick);
var leftObj = GameObject.Instantiate(LeftItem, LeftContent);
leftObj.name = row.name + "|" + item.name;
var path = Global.deviceIconsPath + item.pic;
loader.Add2Load(path.ToNetImageResName(), (success, res) =>
{
if (success)
{
leftObj.GetComponent<Image>().sprite = Utility.GetSprite(res.Asset as Texture2D);
}
});
leftObj.OnBeginDragEvent(LeftOnBeginDrag);
leftObj.OnDragEvent(LeftOnDrag);
leftObj.OnEndDragEvent(LeftOnEndDrag);
itemDatas.Add(leftObj.gameObject, item);
}
}
if (mData.random)
{
Utility.ShuffleChildObjects(LeftContent);
}
loader.LoadAsync();
}
private void OnModuleQuitHandler(OnModuleQuit quit)
{
Hide();
}
private void RightOnClick(PointerEventData data)
{
Transform trans = data.pointerClick.transform;
if (leftAndRightMap.ContainsKey(trans.gameObject))
{
leftAndRightMap[trans.gameObject].rightObj.SetActive(true);
trans.GetComponent<Image>().color = Color.white;
trans.Find("PicBg/Pic").GetComponent<Image>().color = new Color(1, 1, 1, 0);
enterRight.transform.Find("Name").GetComponent<TextMeshProUGUI>().color = Color.white;
leftAndRightMap.Remove(trans.gameObject);
}
}
private void RightOnExit(PointerEventData data)
{
enterRight = null;
}
private void RightOnEnter(PointerEventData data)
{
enterRight = data.pointerEnter.gameObject;
}
private void LeftOnBeginDrag(PointerEventData data)
{
leftDragObj = data.pointerDrag;
moveObj = GameObject.Instantiate(leftDragObj, gameObject.transform);
moveObj.name = moveObj.name.Replace("(Clone)", "");
moveObj.GetComponent<RectTransform>().sizeDelta = LeftContent.GetComponent<GridLayoutGroup>().cellSize;
moveObj.GetComponent<Image>().raycastTarget = false;
}
private void LeftOnEndDrag(PointerEventData data)
{
if (enterRight == null || leftAndRightMap.ContainsKey(enterRight))
return;
TextMeshProUGUI nameText = enterRight.transform.Find("Name").GetComponent<TextMeshProUGUI>();
bool isRight = false;
// 获取正确的分类数据
UIImageSelectMapData.Row categoryRow = GetCategoryRow(enterRight);
if (categoryRow == null)
{
Debug.LogError("无法找到对应的分类数据");
return;
}
var draggedItem = itemDatas[leftDragObj];
bool foundMatch = CheckItemInCategory(draggedItem, categoryRow);
// 更新UI反馈
if (foundMatch)
{
nameText.color = Color.green;
isRight = true;
Debug.Log($"正确匹配: {draggedItem.name} 到分类 {categoryRow.name}");
}
else
{
nameText.color = Color.red;
Debug.Log($"错误匹配: {draggedItem.name} 到分类 {categoryRow.name}");
}
// 更新图片显示
Image img = enterRight.transform.Find("PicBg/Pic").GetComponent<Image>();
img.sprite = moveObj.GetComponent<Image>().sprite;
img.color = Color.white;
// 记录匹配结果
leftAndRightMap.Add(enterRight, new RightDataItem { rightObj = leftDragObj, isRight = isRight });
leftDragObj.SetActive(false);
// 检查当前分类是否完成
if (isRight && CheckCategoryCompletion(categoryRow))
{
if (!string.IsNullOrEmpty(mData.finishedEvent))
{
StringEventSystem.Global.Send(mData.finishedEvent);
Debug.Log($"分类 {categoryRow.name} 已完成,触发完成事件");
}
}
// 清理拖拽对象
GameObject.Destroy(moveObj);
moveObj = null;
leftDragObj = null;
}
// 获取分类行数据
private UIImageSelectMapData.Row GetCategoryRow(GameObject targetObj)
{
Transform parentTransform = targetObj.transform.parent;
// 查找行对象
while (parentTransform != null && parentTransform != RightContent.transform)
{
if (rowMap.ContainsKey(parentTransform.gameObject))
{
return rowMap[parentTransform.gameObject];
}
parentTransform = parentTransform.parent;
}
return null;
}
// 检查项目是否在分类中
private bool CheckItemInCategory(UIImageSelectMapData.OptionItem item, UIImageSelectMapData.Row categoryRow)
{
return categoryRow.items.Exists(i => i.pic == item.pic || i.name == item.name);
}
// 检查分类是否完成匹配
private bool CheckCategoryCompletion(UIImageSelectMapData.Row categoryRow)
{
if (categoryRow == null)
return false;
// 查找该分类需要匹配的项目数
int required = categoryRow.items.Count;
// 查找该分类已正确匹配的项目数
int actual = 0;
if (leftAndRightMap.Any(p => p.Value.isRight && GetCategoryRow(p.Key) == categoryRow))
{
actual = leftAndRightMap.Count(p => p.Value.isRight && GetCategoryRow(p.Key) == categoryRow);
}
// 判断是否完成
return actual >= required;
}
private void LeftOnDrag(PointerEventData data)
{
if (moveObj)
{
moveObj.transform.position = Input.mousePosition;
}
}
protected override void OnShow()
{
}
protected override void OnHide()
{
}
protected override void OnClose()
{
TypeEventSystem.Global.UnRegister<OnModuleQuit>(OnModuleQuitHandler);
}
}
}