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
+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;