fix:1、速度加快减慢优化。2、关卡配置表优化。3、白天黑夜模式切换(部分)

This commit is contained in:
2026-06-15 17:50:56 +08:00
parent 29f9aec06d
commit 13f8d572c4
18 changed files with 19510 additions and 439 deletions
+403 -326
View File
@@ -5,6 +5,8 @@ using System.Linq;
using DG.Tweening;
using FairyGUI;
using FGUI.Arrow_game;
using FGUI.Common_01;
using IgnoreOPS;
using UnityEngine;
namespace ChillConnect
@@ -26,11 +28,6 @@ namespace ChillConnect
// 关卡总配置数据
private LevelConfig _levelConfig;
// 全局固定参数
private const float _pointSpacing = 60f; // 点位间距 60px
private const float _moveSpeed = 120f; // 移动速度
private List<ArrowConfig> allArrowList = new List<ArrowConfig>();
// 网格基础参数
private readonly int gridColNum = 10;
private readonly float pointSpace = 60f;
@@ -181,6 +178,11 @@ namespace ChillConnect
// ========= 编辑器模拟触摸(仅编辑模式生效) =========
// ========== 编辑器鼠标拖拽 ==========
// 初始化未完成,直接跳过拖拽
if (!_initComplete)
return;
#if UNITY_EDITOR
float moveThreshold = 1f; // 移动阈值,大于这个值才算有效拖动
@@ -283,6 +285,8 @@ namespace ChillConnect
protected override void OnOpenBefore(object args)
{
//加载配置
InitAllLevelData();
_viewContainer = ui.view_container;
// 初始化FGUI模板
_dotTemplate = (ArrorPoint)UIPackage.CreateObject("Arrow_game", "ArrorPoint");
@@ -315,10 +319,35 @@ namespace ChillConnect
{
}
#endregion
#region
protected override void AddListener()
{
GameDispatcher.Instance.AddListener(GameMsg.reset_game, OnRestartGame);
GameDispatcher.Instance.AddListener(GameMsg.Update102, SetTopCurr);
GameDispatcher.Instance.AddListener(GameMsg.Update101, SetTopCurr);
}
#region &
protected override void RemoveListener()
{
GameDispatcher.Instance.RemoveListener(GameMsg.reset_game, OnRestartGame);
GameDispatcher.Instance.RemoveListener(GameMsg.Update102, SetTopCurr);
GameDispatcher.Instance.RemoveListener(GameMsg.Update101, SetTopCurr);
}
#endregion
#region
private bool _initComplete = false;
private void InitView()
{
// 重置手势状态
_isTwoFingerTouch = false;
_isDraging = false;
SetModel();
ui.text_level.SetVar("lv", GameHelper.GetLevel().ToString()).FlushVars();
// 关闭按钮
ui.btn_close.SetClick(() => { CtrlCloseUI(); });
ui.btn_clear.SetClick(OnClickDeleteItem);
@@ -337,30 +366,85 @@ namespace ChillConnect
// 滑动条初始居中(对应 1.0 缩放)
float initValue = GetSliderValueByScale(1f);
_zoomSlider.value = initValue;
// 容器初始居中
float startX = (Screen.width - _viewContainer.width) * 0.5f;
float startY = (Screen.height - _viewContainer.height) * 0.5f;
_viewContainer.SetPosition(startX, startY,0);
// 先兜底重置为默认锚点
_viewContainer.pivot = new Vector2(0, 0);
// 重置手势状态
_isTwoFingerTouch = false;
_isDraging = false;
if (_levelConfig == null)
{
_initComplete = true;
return;
}
if (_levelConfig == null) return;
// 1. 绘制网格圆点
// 第一步:绘制网格 → 内部会计算网格中心、修改pivot为网格中心
DrawGridDots(_levelConfig);
allArrowList = _levelConfig.arrows;
// ========== 核心:把网格中心钉在屏幕中心 ==========
// _gridWorldCenter 是 DrawGridDots 里 CalculateGridCenter 算出的值
float screenCenterX = Screen.width * 0.5f;
float screenCenterY = Screen.height * 0.5f;
// 2. 初始化所有箭头 + 路径线条 + 标记网格占用
// 计算容器需要移动多少,才能让网格中心正好对准屏幕中心
float targetContainerX = screenCenterX - _gridWorldCenter.x;
float targetContainerY = screenCenterY - _gridWorldCenter.y;
// 直接设置容器位置
_viewContainer.SetPosition(targetContainerX, targetContainerY, 0);
// ==================================================
foreach (var arrow in _levelConfig.arrows)
{
BuildArrowPath(arrow, _levelConfig);
CreateArrowAndLines(arrow, _levelConfig);
MarkArrowOccupiedCells(arrow, _levelConfig);
}
_initComplete = true;
SetTopCurr();
}
private void SetTopCurr(object a = null)
{
if (ui.com_money is com_money btnMoney)
{
btnMoney.text_gold.text = DataMgr.Ticket.Value.ToString("0.00");
btnMoney.SetClick(PopMakeup);
}
}
private void PopMakeup()
{
var makeupTaskData = DataMgr.MakeupTaskHistory.Value.Last();
var vo = ConfigSystem.GetConfig<MakeupModel>().GetData(makeupTaskData.tableId);
if (vo == null)
{
return;
}
GameHelper.showGameUI = false;
uiCtrlDispatcher.Dispatch(UICtrlMsg.MakeupConfirmUI_Open, makeupTaskData);
}
#endregion
#region UI相关
/// <summary>
/// 切换模式 默认黑夜模式
/// </summary>
/// <param name="mod">true:白天 false:黑夜</param>
private void SetModel(object mod = null)
{
int idx = 0;
if (mod != null)
{
idx = (bool)mod? 1 : 0;
}
ui.mode.selectedIndex = idx;
}
#endregion
private void InitGridBounds()
@@ -428,7 +512,10 @@ namespace ChillConnect
#region
private void LoadLevelConfig()
{
_levelConfig = JsonHelper.LoadLevel("level_1001.json");
// _levelConfig = JsonHelper.LoadLevel("level_1001.json");
// 示例:加载第1关 levelId=1001
int currentLevelId = GameHelper.GetLevel();
_levelConfig = LoadLevelById(currentLevelId);
// 给 path 为空的箭头,设置默认方向
foreach (var arrow in _levelConfig.arrows)
{
@@ -442,6 +529,38 @@ namespace ChillConnect
}
}
}
/// <summary>
/// 从 all_levels.json 中按 levelId 读取指定关卡
/// </summary>
/// <param name="targetLevelId">目标关卡ID 如 1001</param>
/// <returns>找到返回关卡数据,没找到返回null</returns>
///
private static AllLevelRoot _allLevelData;
// 游戏启动时调用一次
public static void InitAllLevelData()
{
string path = Path.Combine(Application.streamingAssetsPath, "all_levels.json");
string json = File.ReadAllText(path);
_allLevelData = JsonUtility.FromJson<AllLevelRoot>(json);
}
public static LevelConfig LoadLevelById(int targetLevelId)
{
AllLevelRoot root = _allLevelData;
if (root == null || root.levels == null) return null;
// 遍历查找对应关卡
foreach (var lv in _allLevelData.levels)
{
if (lv.levelId == targetLevelId)
{
return lv;
}
}
Debug.LogWarning($"未找到关卡ID: {targetLevelId}");
return null;
}
#endregion
#region
@@ -531,7 +650,6 @@ namespace ChillConnect
SetViewPivotToGridCenter();
}
/// <summary>计算网格整体世界中心(原有网格坐标不变)</summary>
/// <summary>计算整个网格圆点区域的世界中心点</summary>
private void CalculateGridCenter(LevelConfig cfg)
{
@@ -693,44 +811,28 @@ namespace ChillConnect
CreateArrowOnly(arrow, pathPoints[pathPoints.Count - 1]);
arrow.originalArrowPos = new Vector2(arrow.arrowObj.x, arrow.arrowObj.y);
arrow.arrowTrackIndex = arrow.totalTrack.Count - 1;
}
// 线条/箭头 统一点击回调
private void OnPathClick(ArrowConfig clickArrow)
{
if (clickArrow.isMoving)
{
Debug.Log($"[arrow] {clickArrow.id}正在移动,请勿点击其他箭头");
return;
}
// 点击的是当前提示箭头,直接隐藏手指
if (_currentTipArrow == clickArrow)
{
HideFingerTip();
}
// ========= 删除模式:直接删除箭头,不走移动逻辑 =========
if (_isDeleteMode)
{
DeleteArrowCompletely(clickArrow);
return;
}
// 在 CreateArrowAndLines 方法最后,补充这段初始化代码
// ========== 新增:初始化距离偏移 ==========
arrow.movedDistance = 0f;
// 轨迹总长度 = (点数-1) * 点间距
arrow.trackTotalLength = (arrow.totalTrack.Count - 1) * 10f;
// 箭头初始在轨迹末端
arrow.arrowInitOffset = arrow.trackTotalLength;
clickArrow.isMoving = true;
bool hasBlock = CheckBlockByGrid(clickArrow);
Debug.Log("[arrow] 点击箭头:" + clickArrow.id +$"hasBlock==={hasBlock}");
if (hasBlock)
// 每个线条的初始偏移 = 索引 * 点间距
arrow.lineInitOffsets = new List<float>();
for (int i = 0; i < arrow.lineUnits.Count; i++)
{
MoveThenReset(clickArrow);
}
else
{
MoveToDisappear(clickArrow);
arrow.lineInitOffsets.Add(i * 10f);
}
}
#endregion
#region
#region
/// <summary>点击删除道具,开启/关闭删除模式</summary>
private void OnClickDeleteItem()
{
@@ -857,6 +959,43 @@ namespace ChillConnect
#endregion
#region &
// 线条/箭头 统一点击回调
private void OnPathClick(ArrowConfig clickArrow)
{
if (clickArrow.isMoving)
{
Debug.Log($"[arrow] {clickArrow.id}正在移动,请勿点击其他箭头");
return;
}
// 点击的是当前提示箭头,直接隐藏手指
if (_currentTipArrow == clickArrow)
{
HideFingerTip();
}
// ========= 删除模式:直接删除箭头,不走移动逻辑 =========
if (_isDeleteMode)
{
DeleteArrowCompletely(clickArrow);
return;
}
clickArrow.isMoving = true;
bool hasBlock = CheckBlockByGrid(clickArrow);
Debug.Log("[arrow] 点击箭头:" + clickArrow.id +$"hasBlock==={hasBlock}");
if (hasBlock)
{
MoveThenReset(clickArrow);
}
else
{
MoveToDisappear(clickArrow);
}
}
// 基于网格行列的阻挡检测
private bool CheckBlockByGrid(ArrowConfig curArrow)
{
@@ -949,7 +1088,7 @@ namespace ChillConnect
ShowResult(false);
}
}
}
}
return isCollide;
}
@@ -1007,6 +1146,11 @@ namespace ChillConnect
{
ShowResult(true);
}
else
{
// 消除每条线小概率触发
DisappearLineGetReward();
}
// 8. 退出删除模式
_isDeleteMode = false;
Debug.Log("[arrow] 箭头已彻底删除");
@@ -1041,106 +1185,71 @@ namespace ChillConnect
arrow.arrowObj = arrowIns;
arrow.isMoving = false;
}
// 移动后复位动画(回弹,不释放占用)
private void MoveThenReset(ArrowConfig arrow)
{
RunCoroutine(MoveAndResetCoroutine(arrow));
}
// 回弹速度单独配置,和移动速度分开
private float _bounceSpeed = 180f;
private IEnumerator MoveAndResetCoroutine(ArrowConfig arrow)
{
float frameDelay = 0.01f;
int stepCount = 2;
int moved = 0;
int trackMaxIndex = arrow.totalTrack.Count - 1;
arrow.movedDistance = 0f;
arrow.finalMoveDir = GetFinalMoveDir(arrow);
// 向前移动的总距离(对应原逻辑2步=20px,可自行调整)
float forwardTotal = 20f;
float timer = 0f;
float duration = forwardTotal / _bounceSpeed;
string dir;
if (arrow.path != null && arrow.path.Count > 0)
// 第一段:向前移动
while (timer < duration)
{
dir = arrow.path[arrow.path.Count - 1];
}
else if (!string.IsNullOrEmpty(arrow.defaultDir))
{
dir = arrow.defaultDir;
}
else
{
dir = "up";
}
arrow.finalMoveDir = dir;
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];
if (curIdx < trackMaxIndex)
{
curIdx++;
arrow.lineUnits[i].SetPosition(arrow.totalTrack[curIdx].x, arrow.totalTrack[curIdx].y, 0);
arrow.lineTrackIndex[i] = curIdx;
}
else
{
float dx = 0, dy = 0;
switch (arrow.finalMoveDir)
{
case "right": dx = 10; break;
case "left": dx = -10; break;
case "down": dy = 10; break;
case "up": dy = -10; break;
}
arrow.lineUnits[i].x += dx;
arrow.lineUnits[i].y += dy;
}
}
int arrowIdx = arrow.arrowTrackIndex;
if (arrowIdx < trackMaxIndex)
{
arrowIdx++;
arrow.arrowObj.SetPosition(arrow.totalTrack[arrowIdx].x, arrow.totalTrack[arrowIdx].y, 0);
arrow.arrowTrackIndex = arrowIdx;
}
else
{
float dx = 0, dy = 0;
switch (arrow.finalMoveDir)
{
case "right": dx = 10; break;
case "left": dx = -10; break;
case "down": dy = 10; break;
case "up": dy = -10; break;
}
arrow.arrowObj.x += dx;
arrow.arrowObj.y += dy;
}
moved++;
yield return new WaitForSeconds(frameDelay);
if (arrow == null || arrow.arrowObj == null) yield break;
timer += Time.deltaTime;
arrow.movedDistance = _bounceSpeed * timer;
UpdateAllElementsPosition(arrow);
yield return null;
}
// 复位位置
// 第二段:回弹到初始位置
timer = 0f;
float startDis = arrow.movedDistance;
while (timer < duration)
{
if (arrow == null || arrow.arrowObj == null) yield break;
timer += Time.deltaTime;
float t = timer / duration;
arrow.movedDistance = Mathf.Lerp(startDis, 0f, t);
UpdateAllElementsPosition(arrow);
yield return null;
}
// 强制复位到初始状态
arrow.movedDistance = 0f;
UpdateAllElementsPosition(arrow);
arrow.isMoving = false;
}
/// <summary>统一更新箭头+所有线条的位置</summary>
private void UpdateAllElementsPosition(ArrowConfig arrow)
{
for (int i = 0; i < arrow.lineUnits.Count; i++)
{
arrow.lineUnits[i].SetPosition(arrow.originalLinePos[i].x, arrow.originalLinePos[i].y, 0);
arrow.lineTrackIndex[i] = i;
float curDist = arrow.lineInitOffsets[i] + arrow.movedDistance;
Vector2 pos = GetPositionByDistance(arrow, curDist);
arrow.lineUnits[i].SetPosition(pos.x, pos.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;
float arrowCurDist = arrow.arrowInitOffset + arrow.movedDistance;
Vector2 arrowPos = GetPositionByDistance(arrow, arrowCurDist);
arrow.arrowObj.SetPosition(arrowPos.x, arrowPos.y, 0);
}
private void MoveToDisappear(ArrowConfig arrow)
@@ -1148,136 +1257,49 @@ namespace ChillConnect
RunCoroutine(MoveAndDisappearCoroutine(arrow));
}
// 新增:统一移动速度(像素/秒),数值越大移动越快,可自由修改
[SerializeField] private float _moveSpeed = 800f;
private IEnumerator MoveAndDisappearCoroutine(ArrowConfig arrow)
{
Debug.Log($"[arrow] arrow.totalTrack.Count =={arrow.totalTrack.Count}");
float frameDelay = 0.01f;
int trackMaxIndex = arrow.totalTrack != null ? arrow.totalTrack.Count - 1 : 0;
string dir;
if (arrow.path != null && arrow.path.Count > 0)
{
dir = arrow.path[arrow.path.Count - 1];
}
else if (!string.IsNullOrEmpty(arrow.defaultDir))
{
dir = arrow.defaultDir;
}
else
{
dir = "up";
}
arrow.finalMoveDir = dir;
arrow.movedDistance = 0f;
arrow.finalMoveDir = GetFinalMoveDir(arrow);
while (true)
{
// 兜底:对象已销毁,直接退出
// 空对象兜底保护
if (arrow == null || arrow.arrowObj == null)
{
Debug.Log($"arrow 为空, 协程结束");
yield break;
}
// 线条移动
// 每帧累计移动距离:速度 * 时间增量
float deltaDis = _moveSpeed * Time.deltaTime;
arrow.movedDistance += deltaDis;
// 更新所有线条位置
for (int i = 0; i < arrow.lineUnits.Count; i++)
{
int curIdx = arrow.lineTrackIndex[i];
if (curIdx < trackMaxIndex)
{
curIdx++;
arrow.lineUnits[i].SetPosition(arrow.totalTrack[curIdx].x, arrow.totalTrack[curIdx].y, 0);
arrow.lineTrackIndex[i] = curIdx;
}
else
{
float dx = 0, dy = 0;
switch (arrow.finalMoveDir)
{
case "right": dx = 10; break;
case "left": dx = -10; break;
case "down": dy = 10; break;
case "up": dy = -10; break;
}
arrow.lineUnits[i].x += dx;
arrow.lineUnits[i].y += dy;
}
float curDist = arrow.lineInitOffsets[i] + arrow.movedDistance;
Vector2 pos = GetPositionByDistance(arrow, curDist);
arrow.lineUnits[i].SetPosition(pos.x, pos.y, 0);
}
// 箭头移动
int arrowIdx = arrow.arrowTrackIndex;
if (arrowIdx < trackMaxIndex)
{
arrowIdx++;
arrow.arrowObj.SetPosition(arrow.totalTrack[arrowIdx].x, arrow.totalTrack[arrowIdx].y, 0);
arrow.arrowTrackIndex = arrowIdx;
}
else
{
float dx = 0, dy = 0;
switch (arrow.finalMoveDir)
{
case "right": dx = 10; break;
case "left": dx = -10; break;
case "down": dy = 10; break;
case "up": dy = -10; break;
}
arrow.arrowObj.x += dx;
arrow.arrowObj.y += dy;
}
// 更新箭头位置
float arrowCurDist = arrow.arrowInitOffset + arrow.movedDistance;
Vector2 arrowPos = GetPositionByDistance(arrow, arrowCurDist);
arrow.arrowObj.SetPosition(arrowPos.x, arrowPos.y, 0);
// ========= 边界判断:有线箭头取尾部轨迹,单点箭头取自身 =========
// 直接取箭头实时坐标,不再使用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":
Debug.Log($"[arrow] checkX={checkX} | gridRight={gridRight} | gridRight + outOffset={gridRight + outOffset}");
if (checkX > gridRight + outOffset) isOut = true;
break;
case "left":
Debug.Log($"[arrow] checkX={checkX} | gridLeft={gridLeft} | gridLeft - outOffset={gridLeft - outOffset}");
if (checkX < gridLeft - outOffset) isOut = true;
break;
case "down":
Debug.Log($"[arrow] checkY={checkY} | gridBottom={gridBottom} | gridBottom + outOffset={gridBottom + outOffset}");
if (checkY > gridBottom + outOffset) isOut = true;
break;
case "up":
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)
// 边界检测:以尾部线条为准(和原逻辑一致)
Vector2 tailPos = GetPositionByDistance(arrow, arrow.movedDistance);
if (CheckIsOutOfBounds(tailPos, arrow.finalMoveDir))
{
// ========== 以下销毁逻辑和原代码保持一致 ==========
ReleaseArrowOccupied(arrow);
// 销毁线条
foreach (var line in arrow.lineUnits)
{
if(line != null)
if (line != null)
{
_viewContainer.RemoveChild(line);
line.Dispose();
@@ -1285,8 +1307,7 @@ namespace ChillConnect
}
arrow.lineUnits.Clear();
// 销毁箭头
if(arrow.arrowObj != null)
if (arrow.arrowObj != null)
{
_viewContainer.RemoveChild(arrow.arrowObj);
arrow.arrowObj.Dispose();
@@ -1294,79 +1315,142 @@ namespace ChillConnect
}
arrow.isMoving = false;
_remainArrowCount--;
if (_remainArrowCount <= 0)
{
ShowResult(true);
}
else
{
DisappearLineGetReward();
}
yield break;
}
yield return new WaitForSeconds(frameDelay);
yield return null; // 每帧执行一次,平滑移动
}
}
#endregion
#region &
private void OnArrowClick(ArrowConfig arrow)
#region
/// <summary>根据距离,计算沿轨迹的实际坐标</summary>
private Vector2 GetPositionByDistance(ArrowConfig arrow, float distance)
{
if (arrow.isMoving) return;
arrow.isMoving = true;
}
int trackCount = arrow.totalTrack.Count;
const float segmentLen = 10f; // 轨迹点固定间距
private void UpdateArrowMove(ArrowConfig arrow)
{
// 关键拦截:不允许移动 / 对象已销毁 → 直接退出
if (!arrow.isMoving || arrow.arrowObj == null)
return;
if (!arrow.isMoving) return;
List<Vector2> path = arrow.pathPointList;
if (arrow.targetIndex < 0)
// 距离在轨迹范围内:两点插值得到精确位置
if (distance <= arrow.trackTotalLength)
{
arrow.isMoving = false;
arrow.arrowObj.visible = false;
foreach (var line in arrow.lineUnits) line.visible = false;
return;
}
float indexFloat = distance / segmentLen;
int index0 = Mathf.FloorToInt(indexFloat);
int index1 = Mathf.Min(index0 + 1, trackCount - 1);
float t = indexFloat - index0;
Vector2 targetPos = path[arrow.targetIndex];
Vector2 curPos = new Vector2(arrow.arrowObj.x, arrow.arrowObj.y);
float distance = Vector2.Distance(curPos, targetPos);
if (distance < 2f)
{
arrow.targetIndex--;
Vector2 p0 = arrow.totalTrack[index0];
Vector2 p1 = arrow.totalTrack[index1];
return Vector2.Lerp(p0, p1, t);
}
// 距离超出轨迹:沿最终方向直线延伸
else
{
Vector2 dir = (targetPos - curPos).normalized;
Vector2 newPos = curPos + dir * _moveSpeed * Time.deltaTime;
arrow.arrowObj.SetPosition(newPos.x, newPos.y, 0);
float extraDis = distance - arrow.trackTotalLength;
Vector2 endPos = arrow.totalTrack[trackCount - 1];
Vector2 dir = DirToVector2(arrow.finalMoveDir);
return endPos + dir * extraDis;
}
RefreshLineVisible(arrow);
}
private void RefreshLineVisible(ArrowConfig arrow)
/// <summary>方向字符串转单位向量</summary>
/// <summary>方向字符串转单位向量(适配 FGUI 坐标系:y 轴向下)</summary>
private Vector2 DirToVector2(string dir)
{
int segIndex = 0;
int totalSeg = arrow.pathPointList.Count - 1;
for (int s = 0; s < totalSeg; s++)
return dir switch
{
bool isShow = s < arrow.targetIndex;
for (int i = 0; i < 6; i++)
{
arrow.lineUnits[segIndex + i].visible = isShow;
}
segIndex += 6;
"up" => new Vector2(0, -1), // FGUI 向上 = y 减小
"down" => new Vector2(0, 1), // FGUI 向下 = y 增大
"left" => new Vector2(-1, 0),
"right" => new Vector2(1, 0),
_ => new Vector2(0, -1)
};
}
/// <summary>统一获取箭头最终移动方向</summary>
private string GetFinalMoveDir(ArrowConfig arrow)
{
if (arrow.path != null && arrow.path.Count > 0)
return arrow.path[arrow.path.Count - 1];
if (!string.IsNullOrEmpty(arrow.defaultDir))
return arrow.defaultDir;
return "up";
}
/// <summary>统一边界检测</summary>
private bool CheckIsOutOfBounds(Vector2 pos, string dir)
{
switch (dir)
{
case "right": return pos.x > gridRight + outOffset;
case "left": return pos.x < gridLeft - outOffset;
case "down": return pos.y > gridBottom + outOffset;
case "up": return pos.y < gridTop - outOffset;
default: return false;
}
}
#endregion
/// <summary>
/// 消除每条线时概率获得奖励
/// </summary>
private void DisappearLineGetReward()
{
bool isGet = false;
int money_rate = ConfigSystem.GetConfig<CommonModel>().rewardrate;
var randomNum = UnityEngine.Random.Range(0, 100);
// Debug.Log($"[creat] money_rate------------ {randomNum}==={money_rate}");
if (GameHelper.IsGiftSwitch() && randomNum < money_rate)
{
isGet = true;
// 显示大额奖励
float[] cash_array = GameHelper.GetRewardValue(1);
var temp = new SuccessData();
temp.IsWin = true;
temp.cash_number = cash_array[0];
temp.rate = (int)cash_array[1];
temp.IsLevelSuccess = false;
temp.IsH5Reward = false;
temp.boost_array = GameHelper.GetRewardBoost(1);
DOVirtual.DelayedCall(0.55f, () =>
{
UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.LevelSuccessUI_Open, temp);
});
}
if (!isGet && Random.Range(0, 100) < ConfigSystem.GetConfig<CommonModel>().Smallrewardsrate)
{
var rewardData = new RewardData();
Vector2 fguiPosition = new Vector2(ui.samll_point.x, ui.samll_point.y);
var start = fguiPosition;
var end = GameHelper.GetUICenterPosition(ui.com_money.GetChild("text_gold"));
float[] cash_array = GameHelper.GetRewardValue(0);
Debug.Log($"小额奖励:{cash_array[0]}");
var rewardSingleData = new RewardSingleData(102, (decimal)cash_array[0], RewardOrigin.AdTask)
{
startPosition = start,
endPosition = new Vector2(end.x - 135, end.y - 135)
};
rewardData.AddReward(rewardSingleData);
rewardData.displayType = RewardDisplayType.RewardFly | RewardDisplayType.ValueChange;
GameDispatcher.Instance.Dispatch(GameMsg.GetReward, rewardData);
}
}
#endregion
#region
@@ -1403,6 +1487,8 @@ namespace ChillConnect
}
}
#endregion
#region
/// <summary>
/// 弹出结算
@@ -1454,10 +1540,15 @@ namespace ChillConnect
}
}
// 重新开始本局
/// <summary>
/// 重新开始本局
/// </summary>
/// <param name="a">true: 重生 false:重开一局或者下一局 </param>
private void OnRestartGame(object a = null)
{
if (a!=null && (bool)a)
Debug.Log($"[ArrowGameUI] 重新开始本局 a:{(bool)a}");
if (a != null && (bool)a)
{
_heartCount = 3;
for (int i = _heartCount; i > 0; i--)
@@ -1467,21 +1558,6 @@ namespace ChillConnect
return;
}
// 1. 恢复默认缩放 1.0
float defaultScale = 1f;
_viewContainer.scaleX = defaultScale;
_viewContainer.scaleY = defaultScale;
// 2. 设置滑块对应位置
_zoomSlider.value = GetSliderValueByScale(defaultScale);
// 3. 容器屏幕居中
float startX = (Screen.width - _viewContainer.width) * 0.5f;
float startY = (Screen.height - _viewContainer.height) * 0.5f;
_viewContainer.SetPosition(startX, startY,0);
// 4. 清空手势状态
_isTwoFingerTouch = false;
_isDraging = false;
// 先清空当前所有动态物体
ClearAllDynamicObj();
// 重新走初始化流程
@@ -1491,22 +1567,12 @@ namespace ChillConnect
_collidedArrows.Clear();
_remainArrowCount = _levelConfig.arrows.Count;
DataMgr.ArrowResultLevel.Value = 1;
InitView();
}
#region
protected override void AddListener()
{
GameDispatcher.Instance.AddListener(GameMsg.reset_game, OnRestartGame);
}
protected override void RemoveListener()
{
GameDispatcher.Instance.RemoveListener(GameMsg.reset_game, OnRestartGame);
}
#endregion
}
#region &
@@ -1547,12 +1613,23 @@ namespace ChillConnect
public bool isMoving;
public List<Vector2> originalLinePos;
public Vector2 originalArrowPos;
public int targetIndex;
public List<Vector2> totalTrack;
public List<int> lineTrackIndex;
public int arrowTrackIndex;
public string finalMoveDir;
// ========== 新增:距离驱动移动所需字段 ==========
public float movedDistance; // 当前整体累计移动距离
public float trackTotalLength; // 整条轨迹的总像素长度
public List<float> lineInitOffsets; // 每个线条单元的初始距离偏移
public float arrowInitOffset; // 箭头的初始距离偏移
}
[System.Serializable]
public class AllLevelRoot
{
public List<LevelConfig> levels;
}
#endregion
}
@@ -216,26 +216,6 @@ namespace ChillConnect
ui.text_award.text = DataMgr.Coin.Value.ToString();
}
ui.com_ch.btn_cash.title = GameHelper.getDesByKey("ch_out_1");
// if (IsWin)
// {
// if (GameHelper.IsGiftSwitch()) ui.text_award.text = GameHelper.Get102Str((decimal)AwardNum);
// else ui.text_award.text = ((int)AwardNum).ToString();
// var sk = FXManager.Instance.SetFx<SkeletonAnimation>(ui.bg_parent, Fx_Type.fx_win, ref closeCallback);
// sk.state.SetAnimation(0, "out", true);
// var sk1 = FXManager.Instance.SetFx<SkeletonAnimation>(ui.bg_parent_title, Fx_Type.fx_win_title, ref closeCallback);
// sk1.state.SetAnimation(0, "animation", false);
// }
// else
// {
// if (GameHelper.IsGiftSwitch()) ui.text_award.text = GameHelper.Get102Str(DataMgr.Ticket.Value);
// else ui.text_award.text = DataMgr.Coin.Value.ToString();
// }
if (GameHelper.IsGiftSwitch())
{
@@ -343,6 +323,8 @@ namespace ChillConnect
DOVirtual.DelayedCall(0.7f, () =>
{
GameDispatcher.Instance.Dispatch(GameMsg.reset_game, false);
CtrlCloseUI();
// if (IsLevelSuccess) UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.OpenGameUI_Open, true);
});