fix:1、修复bug:尾部移动到边界后才隐藏。2、添加删除道具

This commit is contained in:
2026-06-13 18:27:00 +08:00
parent 9b468b835f
commit 6f351139cf
9 changed files with 279 additions and 100 deletions
+2 -1
View File
@@ -8,4 +8,5 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AShortcutExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F2348fb5ecc9e4e689f37f7d7fadaea9a27a00_003F77_003F364dbea6_003FShortcutExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASystem_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F3ea01e77be99618395f448b16bd7cc2bd4248bd9e5d8474964b2d97f39c5d74_003FSystem_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F1071a2cb0cb3433aae80a793c277a04846ac00_003Fb8_003Fdebf208b_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AVector2_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F37cc348edc804f4cb176b63962c716e7177200_003Fab_003F9e3ea355_003FVector2_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AVector2_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F37cc348edc804f4cb176b63962c716e7177200_003Fab_003F9e3ea355_003FVector2_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AWaitForSeconds_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F37cc348edc804f4cb176b63962c716e7177200_003Fdd_003F64399fa4_003FWaitForSeconds_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
@@ -13,6 +13,7 @@ namespace FGUI.Arrow_game
UIObjectFactory.SetPackageItemExtension(LineTile.URL, typeof(LineTile));
UIObjectFactory.SetPackageItemExtension(ArrorPoint.URL, typeof(ArrorPoint));
UIObjectFactory.SetPackageItemExtension(HeartsPanel.URL, typeof(HeartsPanel));
UIObjectFactory.SetPackageItemExtension(com_finger.URL, typeof(com_finger));
}
}
}
@@ -14,6 +14,9 @@ namespace FGUI.Arrow_game
public ArrorPoint point;
public GButton btn_close;
public HeartsPanel HeartsPanel;
public GButton btn_clear;
public GButton btn_hint;
public com_finger com_finger;
public const string URL = "ui://sjl9teijrsd40";
public static com_arrow_game CreateInstance()
@@ -32,6 +35,9 @@ namespace FGUI.Arrow_game
point = (ArrorPoint)GetChildAt(4);
btn_close = (GButton)GetChildAt(6);
HeartsPanel = (HeartsPanel)GetChildAt(7);
btn_clear = (GButton)GetChildAt(9);
btn_hint = (GButton)GetChildAt(10);
com_finger = (com_finger)GetChildAt(11);
}
}
}
@@ -0,0 +1,27 @@
/** This is an automatically generated class by FairyGUI. Please do not modify it. **/
using FairyGUI;
using FairyGUI.Utils;
namespace FGUI.Arrow_game
{
public partial class com_finger : GComponent
{
public GImage finger;
public Transition t0;
public const string URL = "ui://sjl9teijrsd4f";
public static com_finger CreateInstance()
{
return (com_finger)UIPackage.CreateObject("Arrow_game", "com_finger");
}
public override void ConstructFromXML(XML xml)
{
base.ConstructFromXML(xml);
finger = (GImage)GetChildAt(0);
t0 = GetTransitionAt(0);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d110f1d5f9c887b4d9194e2f3ca1c58c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 18 KiB

+199 -47
View File
@@ -54,8 +54,11 @@ namespace ChillConnect
// 统计场上还存在的箭头总数(用于判断全部移除=通关)
private int _remainArrowCount = 0;
// 结算界面UI引用(根据你FGUI包名/组件名自行修改)
// private ResultPanel _resultPanel;
// 记录当前UI所有由 CrazyAsyKit 启动的协程,用于统一停止
private List<Coroutine> _activeCoroutines = new List<Coroutine>();
// 是否开启删除道具模式
private bool _isDeleteMode = false;
public ArrowGameUI(ArrowGameUICtrl ctrl) : base(ctrl)
{
@@ -80,6 +83,26 @@ namespace ChillConnect
protected override void OnClose()
{
// ========= 第一步:统一停止所有协程(核心修复) =========
foreach (var co in _activeCoroutines)
{
if (co != null)
{
CrazyAsyKit.StopCoroutine(co);
}
}
// 清空列表
_activeCoroutines.Clear();
// 保险========= 强制停止所有移动,终止对应协程 =========
if (_levelConfig != null)
{
foreach (var arrow in _levelConfig.arrows)
{
arrow.isMoving = false;
}
}
// 销毁所有动态FGUI对象
ClearAllDynamicObj();
@@ -152,6 +175,8 @@ namespace ChillConnect
{
// 关闭按钮
ui.btn_close.SetClick(() => { CtrlCloseUI(); });
ui.btn_clear.SetClick(OnClickDeleteItem);
if (_levelConfig == null) return;
@@ -410,6 +435,8 @@ namespace ChillConnect
arrow.finalMoveDir = GetDirByRotation(arrow.arrowObj.rotation);
// ========= 修复2:强制记录原始坐标(关键!)=========
arrow.originalArrowPos = new Vector2(arrow.arrowObj.x, arrow.arrowObj.y);
// 优化:给单点箭头填充一个轨迹点,和有线箭头逻辑完全一致
arrow.totalTrack.Add(pathPoints[0]);
return;
}
@@ -467,10 +494,21 @@ namespace ChillConnect
private void OnPathClick(ArrowConfig clickArrow)
{
if (clickArrow.isMoving)
{
Debug.Log($"[arrow] {clickArrow.id}正在移动,请勿点击其他箭头");
return;
}
// ========= 删除模式:直接删除箭头,不走移动逻辑 =========
if (_isDeleteMode)
{
DeleteArrowCompletely(clickArrow);
return;
}
clickArrow.isMoving = true;
bool hasBlock = CheckBlockByGrid(clickArrow);
Debug.Log("[arrow] 点击箭头:" + clickArrow.id +$"hasBlock==={hasBlock}");
if (hasBlock)
{
MoveThenReset(clickArrow);
@@ -480,6 +518,23 @@ namespace ChillConnect
MoveToDisappear(clickArrow);
}
}
/// <summary>点击删除道具,开启/关闭删除模式</summary>
public void OnClickDeleteItem()
{
_isDeleteMode = !_isDeleteMode;
// 可选:加提示,区分状态
if (_isDeleteMode)
{
Debug.Log("已开启删除模式,点击箭头即可删除");
// 可加UI提示:如图标高亮、文字提示
}
else
{
Debug.Log("已关闭删除模式");
}
}
// 基于网格行列的阻挡检测
private bool CheckBlockByGrid(ArrowConfig curArrow)
@@ -577,6 +632,58 @@ namespace ChillConnect
return isCollide;
}
/// <summary>彻底删除指定箭头:销毁UI+清数据+停逻辑+移除列表</summary>
private void DeleteArrowCompletely(ArrowConfig arrow)
{
if (arrow == null) return;
// 1. 停止移动标记,拦截Update和协程
arrow.isMoving = false;
// 2. 销毁箭头中所有线条UI
if (arrow.lineUnits != null)
{
foreach (var line in arrow.lineUnits)
{
if (line != null)
{
_viewContainer.RemoveChild(line);
line.Dispose();
}
}
arrow.lineUnits.Clear();
}
// 3. 销毁箭头本体UI
if (arrow.arrowObj != null)
{
_viewContainer.RemoveChild(arrow.arrowObj);
arrow.arrowObj.Dispose();
arrow.arrowObj = null;
}
// 4. 释放网格占用数据(和飞出边界逻辑保持一致)
ReleaseArrowOccupied(arrow);
// 5. 存活箭头计数-1
_remainArrowCount--;
// 6. 从总列表移除该箭头(核心:删除数据源)
if (_levelConfig != null && _levelConfig.arrows != null)
{
_levelConfig.arrows.Remove(arrow);
}
// 7. 可选:判断是否全部删除完成,触发结算(按需开启)
if (_remainArrowCount <= 0)
{
ShowResult(true);
}
// 8. 退出删除模式
_isDeleteMode = false;
Debug.Log("[arrow] 箭头已彻底删除");
}
// 创建箭头 + 绑定点击
private void CreateArrowOnly(ArrowConfig arrow, Vector2 arrowPos)
@@ -611,7 +718,7 @@ namespace ChillConnect
// 移动后复位动画(回弹,不释放占用)
private void MoveThenReset(ArrowConfig arrow)
{
CrazyAsyKit.StartCoroutine(MoveAndResetCoroutine(arrow));
RunCoroutine(MoveAndResetCoroutine(arrow));
}
private IEnumerator MoveAndResetCoroutine(ArrowConfig arrow)
@@ -638,6 +745,13 @@ namespace ChillConnect
while (moved < stepCount)
{
// 新增空对象防护
if (arrow == null || arrow.arrowObj == null)
{
Debug.Log($"[arrow] MoveAndResetCoroutine arrow 为空, 协程结束");
yield break;
}
for (int i = 0; i < arrow.lineUnits.Count; i++)
{
int curIdx = arrow.lineTrackIndex[i];
@@ -693,8 +807,10 @@ namespace ChillConnect
arrow.lineUnits[i].SetPosition(arrow.originalLinePos[i].x, arrow.originalLinePos[i].y, 0);
arrow.lineTrackIndex[i] = i;
}
// 单点/多点箭头统一读取原始坐标复位
arrow.arrowObj.SetPosition(arrow.originalArrowPos.x, arrow.originalArrowPos.y, 0);
if(arrow.arrowObj != null)
{
arrow.arrowObj.SetPosition(arrow.originalArrowPos.x, arrow.originalArrowPos.y, 0);
}
arrow.arrowTrackIndex = arrow.totalTrack.Count - 1;
arrow.isMoving = false;
@@ -702,13 +818,14 @@ namespace ChillConnect
private void MoveToDisappear(ArrowConfig arrow)
{
CrazyAsyKit.StartCoroutine(MoveAndDisappearCoroutine(arrow));
RunCoroutine(MoveAndDisappearCoroutine(arrow));
}
private IEnumerator MoveAndDisappearCoroutine(ArrowConfig arrow)
{
Debug.Log($"[arrow] arrow.totalTrack.Count =={arrow.totalTrack.Count}");
float frameDelay = 0.01f;
int trackMaxIndex = arrow.totalTrack.Count - 1;
int trackMaxIndex = arrow.totalTrack != null ? arrow.totalTrack.Count - 1 : 0;
string dir;
if (arrow.path != null && arrow.path.Count > 0)
@@ -727,6 +844,14 @@ namespace ChillConnect
while (true)
{
// 兜底:对象已销毁,直接退出
if (arrow == null || arrow.arrowObj == null)
{
Debug.Log($"arrow 为空, 协程结束");
yield break;
}
// 线条移动
for (int i = 0; i < arrow.lineUnits.Count; i++)
{
@@ -774,38 +899,75 @@ namespace ChillConnect
arrow.arrowObj.y += dy;
}
// 边界判断
float curX = arrow.arrowObj.x;
float curY = arrow.arrowObj.y;
// ========= 边界判断:有线箭头取尾部轨迹,单点箭头取自身 =========
// 直接取箭头实时坐标,不再使用totalTrack静态点位
bool isOut = false;
float checkX = 0;
float checkY = 0;
// 线段从起点生成,第 0 个元素才是尾巴
if (arrow.lineUnits != null && arrow.lineUnits.Count > 0)
{
var tailLine = arrow.lineUnits[0];
checkX = tailLine.x;
checkY = tailLine.y;
}
else if (arrow.arrowObj != null)
{
// 纯单点箭头,使用自身坐标
checkX = arrow.arrowObj.x;
checkY = arrow.arrowObj.y;
}
Debug.Log($"[arrow] arrow.finalMoveDir =={arrow.finalMoveDir}");
switch (arrow.finalMoveDir)
{
case "right":
if (curX > gridRight + outOffset) isOut = true;
Debug.Log($"[arrow] checkX={checkX} | gridRight={gridRight} | gridRight + outOffset={gridRight + outOffset}");
if (checkX > gridRight + outOffset) isOut = true;
break;
case "left":
if (curX < gridLeft - outOffset) isOut = true;
Debug.Log($"[arrow] checkX={checkX} | gridLeft={gridLeft} | gridLeft - outOffset={gridLeft - outOffset}");
if (checkX < gridLeft - outOffset) isOut = true;
break;
case "down":
if (curY > gridBottom + outOffset) isOut = true;
Debug.Log($"[arrow] checkY={checkY} | gridBottom={gridBottom} | gridBottom + outOffset={gridBottom + outOffset}");
if (checkY > gridBottom + outOffset) isOut = true;
break;
case "up":
if (curY < gridTop - outOffset) isOut = true;
Debug.Log($"[arrow] checkY={checkY} | gridTop={gridTop} | gridTop - outOffset={gridTop - outOffset}");
if (checkY < gridTop - outOffset) isOut = true;
break;
}
// ========= 超出边界:隐藏 + 计数 + 终止协程 =========
Debug.Log($"[arrow] isOut =={isOut}");
if (isOut)
{
// 箭头移出屏幕,释放网格占用
ReleaseArrowOccupied(arrow);
// 隐藏视图
// 销毁线条
foreach (var line in arrow.lineUnits)
line.visible = false;
arrow.arrowObj.visible = false;
{
if(line != null)
{
_viewContainer.RemoveChild(line);
line.Dispose();
}
}
arrow.lineUnits.Clear();
// 销毁箭头
if(arrow.arrowObj != null)
{
_viewContainer.RemoveChild(arrow.arrowObj);
arrow.arrowObj.Dispose();
arrow.arrowObj = null;
}
arrow.isMoving = false;
// ========== 新增:存活箭头-1,判断全部移除 ==========
_remainArrowCount--;
if (_remainArrowCount <= 0)
{
@@ -818,33 +980,6 @@ namespace ChillConnect
yield return new WaitForSeconds(frameDelay);
}
}
private void CreateLineUnitBetweenTwoPoint(Vector2 pStart, Vector2 pEnd, Color lineColor, List<GComponent> lineList)
{
if (_lineUnitTemplate == null) return;
float offsetX = 0f;
float offsetY = 0f;
if (Mathf.Abs(pEnd.x - pStart.x) > 1f)
offsetX = 10f;
else
offsetY = 10f;
Vector2 curPos = pStart;
for (int i = 0; i < 6; i++)
{
LineTile unit = LineTile.CreateInstance();
unit.SetPosition(curPos.x, curPos.y, 0);
unit.GetChild("line").asGraph.color = lineColor;
unit.visible = true;
_viewContainer.AddChild(unit);
lineList.Add(unit);
curPos.x += offsetX;
curPos.y += offsetY;
}
}
#endregion
#region &
@@ -856,6 +991,10 @@ namespace ChillConnect
private void UpdateArrowMove(ArrowConfig arrow)
{
// 关键拦截:不允许移动 / 对象已销毁 → 直接退出
if (!arrow.isMoving || arrow.arrowObj == null)
return;
if (!arrow.isMoving) return;
List<Vector2> path = arrow.pathPointList;
@@ -903,6 +1042,19 @@ namespace ChillConnect
#endregion
#region
/// <summary>全局启动协程 + 自动记录,关闭界面时统一停止</summary>
private Coroutine RunCoroutine(IEnumerator cor)
{
if (cor == null) return null;
Coroutine co = CrazyAsyKit.StartCoroutine(cor);
if (co != null)
{
_activeCoroutines.Add(co);
}
return co;
}
private void ClearAllDynamicObj()
{
if (_levelConfig == null || _viewContainer == null) return;
+33 -52
View File
@@ -8,42 +8,41 @@
{
"id": 1,
"startPoint": 0,
"endPoint": 25,
"endPoint": 17,
"color": "#FFFFFF",
"path": [
"right",
"right",
"right",
"right",
"right",
"down",
"down"
]
},
{
"id": 2,
"startPoint": 30,
"endPoint": 37,
"color": "#FFFFFF",
"path": [
"right",
"right",
"right",
"right",
"right",
"right",
"right"
]
},
{
"id": 3,
"startPoint": 50,
"endPoint": 46,
"color": "#FFFFFF",
"id": 2,
"startPoint": 18,
"endPoint": 23,
"color": "#FFCC00",
"path": [
"down",
"left",
"left",
"left",
"left",
"down",
"left",
"up"
]
},
{
"id": 3,
"startPoint": 36,
"endPoint": 29,
"color": "#33FF00",
"path": [
"right",
"right",
"right",
"right",
"right",
"right",
@@ -52,44 +51,26 @@
},
{
"id": 4,
"startPoint": 60,
"endPoint": 66,
"color": "#FFFFFF",
"path": [
"right",
"right",
"right",
"right",
"right",
"right"
]
"startPoint": 88,
"endPoint": 88,
"color": "#FFFF00",
"path": []
},
{
"id": 5,
"startPoint": 93,
"endPoint": 73,
"startPoint": 92,
"endPoint": 84,
"color": "#FFFFFF",
"path": [
"up",
"up"
]
},
{
"id": 6,
"startPoint": 9,
"endPoint": 89,
"color": "#FFFFFF",
"path": [
"down",
"down",
"down",
"down",
"down",
"left",
"down",
"down",
"left",
"up",
"right",
"down"
"right",
"right",
"down",
"right"
]
}
]