diff --git a/ArrowBeatTap-Gp.sln.DotSettings.user b/ArrowBeatTap-Gp.sln.DotSettings.user
index 6e39860..526b660 100644
--- a/ArrowBeatTap-Gp.sln.DotSettings.user
+++ b/ArrowBeatTap-Gp.sln.DotSettings.user
@@ -8,4 +8,5 @@
ForceIncluded
ForceIncluded
ForceIncluded
- ForceIncluded
\ No newline at end of file
+ ForceIncluded
+ ForceIncluded
\ No newline at end of file
diff --git a/Assets/ChillConnect/FGUI/package/Arrow_game/Arrow_gameBinder.cs b/Assets/ChillConnect/FGUI/package/Arrow_game/Arrow_gameBinder.cs
index 511cc1d..8d5a146 100644
--- a/Assets/ChillConnect/FGUI/package/Arrow_game/Arrow_gameBinder.cs
+++ b/Assets/ChillConnect/FGUI/package/Arrow_game/Arrow_gameBinder.cs
@@ -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));
}
}
}
\ No newline at end of file
diff --git a/Assets/ChillConnect/FGUI/package/Arrow_game/com_arrow_game.cs b/Assets/ChillConnect/FGUI/package/Arrow_game/com_arrow_game.cs
index 52af3dd..d9fee3c 100644
--- a/Assets/ChillConnect/FGUI/package/Arrow_game/com_arrow_game.cs
+++ b/Assets/ChillConnect/FGUI/package/Arrow_game/com_arrow_game.cs
@@ -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);
}
}
}
\ No newline at end of file
diff --git a/Assets/ChillConnect/FGUI/package/Arrow_game/com_finger.cs b/Assets/ChillConnect/FGUI/package/Arrow_game/com_finger.cs
new file mode 100644
index 0000000..6140f12
--- /dev/null
+++ b/Assets/ChillConnect/FGUI/package/Arrow_game/com_finger.cs
@@ -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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Assets/ChillConnect/FGUI/package/Arrow_game/com_finger.cs.meta b/Assets/ChillConnect/FGUI/package/Arrow_game/com_finger.cs.meta
new file mode 100644
index 0000000..1677c84
--- /dev/null
+++ b/Assets/ChillConnect/FGUI/package/Arrow_game/com_finger.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: d110f1d5f9c887b4d9194e2f3ca1c58c
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Resources/ChillConnectAssets/FGUI/Arrow_game_atlas0.png b/Assets/Resources/ChillConnectAssets/FGUI/Arrow_game_atlas0.png
index 9e86b35..d17798f 100644
Binary files a/Assets/Resources/ChillConnectAssets/FGUI/Arrow_game_atlas0.png and b/Assets/Resources/ChillConnectAssets/FGUI/Arrow_game_atlas0.png differ
diff --git a/Assets/Resources/ChillConnectAssets/FGUI/Arrow_game_fui.bytes b/Assets/Resources/ChillConnectAssets/FGUI/Arrow_game_fui.bytes
index 15908b1..1d028d0 100644
Binary files a/Assets/Resources/ChillConnectAssets/FGUI/Arrow_game_fui.bytes and b/Assets/Resources/ChillConnectAssets/FGUI/Arrow_game_fui.bytes differ
diff --git a/Assets/Scripts/ModuleUI/ArrowGame/ArrowGameUI.cs b/Assets/Scripts/ModuleUI/ArrowGame/ArrowGameUI.cs
index 7ce3121..b611cf3 100644
--- a/Assets/Scripts/ModuleUI/ArrowGame/ArrowGameUI.cs
+++ b/Assets/Scripts/ModuleUI/ArrowGame/ArrowGameUI.cs
@@ -54,8 +54,11 @@ namespace ChillConnect
// 统计场上还存在的箭头总数(用于判断全部移除=通关)
private int _remainArrowCount = 0;
- // 结算界面UI引用(根据你FGUI包名/组件名自行修改)
- // private ResultPanel _resultPanel;
+ // 记录当前UI所有由 CrazyAsyKit 启动的协程,用于统一停止
+ private List _activeCoroutines = new List();
+
+ // 是否开启删除道具模式
+ 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);
}
}
+
+ /// 点击删除道具,开启/关闭删除模式
+ 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;
}
+
+ /// 彻底删除指定箭头:销毁UI+清数据+停逻辑+移除列表
+ 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 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 path = arrow.pathPointList;
@@ -903,6 +1042,19 @@ namespace ChillConnect
#endregion
#region 资源清理
+
+ /// 全局启动协程 + 自动记录,关闭界面时统一停止
+ 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;
diff --git a/Assets/StreamingAssets/level_1001.json b/Assets/StreamingAssets/level_1001.json
index 436367c..bff258a 100644
--- a/Assets/StreamingAssets/level_1001.json
+++ b/Assets/StreamingAssets/level_1001.json
@@ -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"
]
}
]