fix:1、更换关卡获取,改为单关一个json文件
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -8,6 +9,7 @@ using FGUI.Arrow_game;
|
||||
using FGUI.Common_01;
|
||||
using IgnoreOPS;
|
||||
using UnityEngine;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace ChillConnect
|
||||
{
|
||||
@@ -23,7 +25,8 @@ namespace ChillConnect
|
||||
private LevelConfig _levelConfig;
|
||||
|
||||
// 网格基础参数
|
||||
private readonly int gridColNum = 10;
|
||||
private int gridColNum = 10;
|
||||
private int gridRowNum = 10;
|
||||
private readonly float pointSpace = 60f;
|
||||
private readonly float outOffset = 200f;
|
||||
|
||||
@@ -32,7 +35,6 @@ namespace ChillConnect
|
||||
|
||||
private float gridLeft;
|
||||
private float gridRight;
|
||||
private readonly int gridRowNum = 10;
|
||||
private float gridTop;
|
||||
private float gridBottom;
|
||||
|
||||
@@ -85,7 +87,7 @@ namespace ChillConnect
|
||||
|
||||
#region 缩放、拖拽、滑动条 全局变量
|
||||
// 缩放阈值(滑动条左右边界对应这两个值)
|
||||
private readonly float _minScale = 0.6f;
|
||||
private readonly float _minScale = 0.5f;
|
||||
private readonly float _maxScale = 1.5f;
|
||||
// FGUI 滑动条组件
|
||||
private GSlider _zoomSlider;
|
||||
@@ -99,6 +101,7 @@ namespace ChillConnect
|
||||
private readonly float _dragBorder = 100f;
|
||||
#endregion
|
||||
|
||||
|
||||
public ArrowGameUI(ArrowGameUICtrl ctrl) : base(ctrl)
|
||||
{
|
||||
uiName = UIConst.ArrowGameUI;
|
||||
@@ -188,7 +191,7 @@ namespace ChillConnect
|
||||
{
|
||||
_lastTouchPos = fguiPos;
|
||||
_isDraging = true;
|
||||
Debug.Log("鼠标按下,在拖拽区域内,开始拖拽");
|
||||
// Debug.Log("鼠标按下,在拖拽区域内,开始拖拽");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -211,7 +214,7 @@ namespace ChillConnect
|
||||
if (InputHelper.Instance.GetMouseButtonUp(0))
|
||||
{
|
||||
_isDraging = false;
|
||||
Debug.Log("鼠标抬起,结束拖拽");
|
||||
// Debug.Log("鼠标抬起,结束拖拽");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -262,6 +265,12 @@ namespace ChillConnect
|
||||
_isDraging = true;
|
||||
_isTwoFingerTouch = false;
|
||||
}
|
||||
|
||||
// 只有点击在网格范围内才触发震动
|
||||
// if (IsInGridArea(curTouchPos))
|
||||
// {
|
||||
// TriggerVibration();
|
||||
// }
|
||||
}
|
||||
else if (touch.phase == TouchPhase.Moved && _isDraging)
|
||||
{
|
||||
@@ -285,9 +294,9 @@ namespace ChillConnect
|
||||
protected override void OnOpenBefore(object args)
|
||||
{
|
||||
//加载配置
|
||||
InitAllLevelData();
|
||||
_viewContainer = ui.view_container_parent.panel;
|
||||
// InitAllLevelData();
|
||||
LoadLevelConfig();
|
||||
_viewContainer = ui.view_container_parent.panel;
|
||||
InitGridBounds();
|
||||
|
||||
// 初始化网格占用数组
|
||||
@@ -361,7 +370,7 @@ namespace ChillConnect
|
||||
ui.HeartsPanel.GetChild($"xin_{i}").visible = true;
|
||||
}
|
||||
|
||||
|
||||
// ui.ch_progress.value = DataMgr.ArrowChProgress.Value;
|
||||
|
||||
_currentTipArrow = null;
|
||||
|
||||
@@ -369,11 +378,11 @@ namespace ChillConnect
|
||||
// 2. 绑定滑动条拖动回调
|
||||
_zoomSlider.onChanged.Add(OnZoomSliderChange);
|
||||
// 3. 容器初始缩放、位置
|
||||
_viewContainer.scaleX = 1f;
|
||||
_viewContainer.scaleY = 1f;
|
||||
// 滑动条初始居中(对应 1.0 缩放)
|
||||
float initValue = GetSliderValueByScale(1f);
|
||||
_zoomSlider.value = initValue;
|
||||
// _viewContainer.scaleX = 1f;
|
||||
// _viewContainer.scaleY = 1f;
|
||||
// // 滑动条初始居中(对应 1.0 缩放)
|
||||
// float initValue = GetSliderValueByScale(1f);
|
||||
// _zoomSlider.value = initValue;
|
||||
// 先兜底重置为默认锚点
|
||||
_viewContainer.pivot = new Vector2(0, 0);
|
||||
|
||||
@@ -385,6 +394,15 @@ namespace ChillConnect
|
||||
|
||||
// 第一步:绘制网格 → 内部会计算网格中心、修改pivot为网格中心
|
||||
DrawGridDots(_levelConfig);
|
||||
|
||||
// ===== 新增:计算并应用初始缩放 =====
|
||||
float initialScale = CalculateInitialScale();
|
||||
_viewContainer.scaleX = initialScale;
|
||||
_viewContainer.scaleY = initialScale;
|
||||
|
||||
// 同步滑动条位置(假设滑动条映射范围为 _minScale~_maxScale)
|
||||
float sliderValue = GetSliderValueByScale(initialScale);
|
||||
_zoomSlider.value = Mathf.Clamp(sliderValue, 0f, 100f); // 确保不越界
|
||||
|
||||
// ========== 核心:把网格中心钉在屏幕中心 ==========
|
||||
// _gridWorldCenter 是 DrawGridDots 里 CalculateGridCenter 算出的值
|
||||
@@ -415,10 +433,42 @@ namespace ChillConnect
|
||||
_fingerTipObj = com_finger.CreateInstance();
|
||||
_viewContainer.AddChild(_fingerTipObj);
|
||||
_fingerTipObj.visible = false;
|
||||
_fingerTipObj.touchable = false;
|
||||
_fingerTipObj.sortingOrder = 9999;
|
||||
|
||||
}
|
||||
|
||||
private float CalculateInitialScale()
|
||||
{
|
||||
if (_levelConfig == null) return 0.8f; // 保底
|
||||
|
||||
int cols = _levelConfig.gridCols;
|
||||
int rows = _levelConfig.gridRows;
|
||||
float spacing = _levelConfig.pointSpacing;
|
||||
|
||||
// 网格实际像素宽高
|
||||
float gridWidth = (cols - 1) * spacing;
|
||||
float gridHeight = (rows - 1) * spacing;
|
||||
|
||||
// 容器有效尺寸(可减去固定边距,如 40px)
|
||||
float margin = 80f;
|
||||
float containerWidth = ui.view_container_parent.width - margin * 2;
|
||||
float containerHeight = ui.view_container_parent.height - margin * 2;
|
||||
|
||||
// 边界保护(网格可能只有一行/列)
|
||||
if (gridWidth <= 0) gridWidth = 1f;
|
||||
if (gridHeight <= 0) gridHeight = 1f;
|
||||
|
||||
float scaleX = containerWidth / gridWidth;
|
||||
float scaleY = containerHeight / gridHeight;
|
||||
|
||||
float scale = Mathf.Min(scaleX, scaleY);
|
||||
|
||||
// 限制上限(避免网格过大时缩放太小;下限由滑动条范围决定,建议调整 _minScale)
|
||||
scale = Mathf.Clamp(scale, _minScale, _maxScale); // 下限设 0.3 更合理
|
||||
return scale;
|
||||
}
|
||||
|
||||
private void SetTopCurr(object a = null)
|
||||
{
|
||||
if (ui.com_money is com_money btnMoney)
|
||||
@@ -591,15 +641,58 @@ namespace ChillConnect
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//反馈特效工具
|
||||
/// <summary>
|
||||
/// 触发震动反馈
|
||||
/// </summary>
|
||||
/// <param name="isStrong">true=强震动(阻挡时用),false=轻震动(普通点击)</param>
|
||||
private void TriggerVibration(bool isStrong = false)
|
||||
{
|
||||
// 编辑器模式跳过震动
|
||||
#if UNITY_EDITOR
|
||||
return;
|
||||
#endif
|
||||
|
||||
// 通用震动(兼容iOS/安卓,系统默认时长)
|
||||
// Handheld.Vibrate();
|
||||
|
||||
Debug.Log($"震动反馈:{isStrong}");
|
||||
// ===== 进阶:安卓自定义震动时长(可选开启)=====
|
||||
if (Application.platform == RuntimePlatform.Android)
|
||||
{
|
||||
long duration = isStrong ? 100L : 50L;
|
||||
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
|
||||
AndroidJavaObject activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
|
||||
AndroidJavaObject vibrator = activity.Call<AndroidJavaObject>("getSystemService", "vibrator");
|
||||
vibrator.Call("vibrate", duration);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 触发阻挡时两侧红色闪烁效果
|
||||
/// </summary>
|
||||
private void TriggerBlockFlash()
|
||||
{
|
||||
// 先终止正在播放的动画,避免叠加错乱
|
||||
ui.com_ficker.visible = true;
|
||||
ui.com_ficker.t0.Play(() =>
|
||||
{
|
||||
ui.com_ficker.visible = false;
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void InitGridBounds()
|
||||
{
|
||||
// 第0列、第0行的起点坐标
|
||||
gridLeft = ui.point.x;
|
||||
gridRight = ui.point.x + gridColNum * pointSpace;
|
||||
gridTop = ui.point.y;
|
||||
gridBottom = ui.point.y + gridRowNum * pointSpace;
|
||||
|
||||
// 正确计算:(点数 - 1) × 点间距 = 总跨度
|
||||
gridRight = ui.point.x + (_levelConfig.gridCols - 1) * _levelConfig.pointSpacing;
|
||||
gridBottom = ui.point.y + (_levelConfig.gridRows - 1) * _levelConfig.pointSpacing;
|
||||
}
|
||||
|
||||
/// <summary>初始化网格占用二维数组</summary>
|
||||
@@ -660,21 +753,34 @@ namespace ChillConnect
|
||||
private void LoadLevelConfig()
|
||||
{
|
||||
// _levelConfig = JsonHelper.LoadLevel("level_1001.json");
|
||||
// 示例:加载第1关 levelId=1001
|
||||
// 示例:加载第1关 levelId=0
|
||||
int currentLevelId = GameHelper.GetLevel();
|
||||
_levelConfig = LoadLevelById(currentLevelId);
|
||||
// 给 path 为空的箭头,设置默认方向
|
||||
foreach (var arrow in _levelConfig.arrows)
|
||||
|
||||
// 替换为:按ID加载单关
|
||||
bool loadSuccess = LevelManager.Instance.LoadLevel(currentLevelId);
|
||||
if (!loadSuccess)
|
||||
{
|
||||
if (arrow.path == null || arrow.path.Count == 0)
|
||||
{
|
||||
arrow.defaultDir = "up";
|
||||
}
|
||||
else
|
||||
{
|
||||
arrow.defaultDir = null;
|
||||
}
|
||||
// 加载失败兜底(比如回到第一关)
|
||||
return;
|
||||
}
|
||||
|
||||
// 直接取当前关卡配置,后续逻辑完全不变
|
||||
_levelConfig = LevelManager.Instance.CurrentLevel;
|
||||
|
||||
// if (_allLevelData.levels.Count < currentLevelId) currentLevelId = _allLevelData.levels.Count;
|
||||
// _levelConfig = LoadLevelById(currentLevelId);
|
||||
// // 给 path 为空的箭头,设置默认方向
|
||||
// foreach (var arrow in _levelConfig.arrows)
|
||||
// {
|
||||
// if (arrow.path == null || arrow.path.Count == 0)
|
||||
// {
|
||||
// arrow.defaultDir = "up";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// arrow.defaultDir = null;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1113,6 +1219,23 @@ namespace ChillConnect
|
||||
&& localPos.y >= 0
|
||||
&& localPos.y <= ui.view_container_parent.height;
|
||||
}
|
||||
/// <summary>
|
||||
/// 判断FGUI全局坐标是否落在圆点网格范围内
|
||||
/// </summary>
|
||||
private bool IsInGridArea(Vector2 fguiGlobalPos)
|
||||
{
|
||||
if (_viewContainer == null || _levelConfig == null)
|
||||
return false;
|
||||
|
||||
// 全局坐标转成 _viewContainer 本地坐标(网格坐标基于该容器)
|
||||
Vector2 localPos = _viewContainer.GlobalToLocal(fguiGlobalPos);
|
||||
|
||||
// 和网格四边边界比对
|
||||
return localPos.x >= gridLeft
|
||||
&& localPos.x <= gridRight
|
||||
&& localPos.y >= gridTop
|
||||
&& localPos.y <= gridBottom;
|
||||
}
|
||||
|
||||
/// <summary>根据缩放值,计算滑动条 value(0~1)</summary>
|
||||
private float GetSliderValueByScale(float scale)
|
||||
@@ -1182,6 +1305,9 @@ namespace ChillConnect
|
||||
return;
|
||||
}
|
||||
|
||||
TriggerVibration(true);
|
||||
|
||||
|
||||
// 点击的是当前提示箭头,直接隐藏手指
|
||||
if (_currentTipArrow == clickArrow)
|
||||
{
|
||||
@@ -1197,7 +1323,7 @@ namespace ChillConnect
|
||||
|
||||
clickArrow.isMoving = true;
|
||||
bool hasBlock = CheckBlockByGrid(clickArrow);
|
||||
Debug.Log("[arrow] 点击箭头:" + clickArrow.id +$"hasBlock==={hasBlock}");
|
||||
Debug.Log("[arrow] 点击箭头 id:" + clickArrow.id +$" hasBlock=阻挡=={hasBlock}");
|
||||
if (hasBlock)
|
||||
{
|
||||
MoveThenReset(clickArrow);
|
||||
@@ -1304,6 +1430,68 @@ namespace ChillConnect
|
||||
return isCollide;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算箭头沿射出方向,到前方第一个阻挡点的前移距离(像素)
|
||||
/// </summary>
|
||||
/// <param name="arrow">目标箭头</param>
|
||||
/// <param name="hitMargin">碰撞预留余量,离阻挡点还差多少像素就停下回弹</param>
|
||||
/// <returns>实际前移的总像素距离</returns>
|
||||
private float GetDistanceToFirstBlock(ArrowConfig arrow, float hitMargin = 20f)
|
||||
{
|
||||
if (_gridOccupied == null || _levelConfig == null)
|
||||
return 20f; // 异常兜底,保持原默认值
|
||||
|
||||
// 计算箭头头部所在的网格坐标(路径终点)
|
||||
int curRow = arrow.startPoint / _levelConfig.gridCols;
|
||||
int curCol = arrow.startPoint % _levelConfig.gridCols;
|
||||
|
||||
// 沿路径走到终点,定位箭头头部网格位置
|
||||
foreach (string dir in arrow.path)
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case "up": curRow--; break;
|
||||
case "down": curRow++; break;
|
||||
case "left": curCol--; break;
|
||||
case "right": curCol++; break;
|
||||
}
|
||||
}
|
||||
|
||||
string moveDir = GetFinalMoveDir(arrow);
|
||||
int emptyGridCount = 0;
|
||||
|
||||
// 沿射出方向逐格检测第一个阻挡
|
||||
while (true)
|
||||
{
|
||||
// 前进一步
|
||||
switch (moveDir)
|
||||
{
|
||||
case "up": curRow--; break;
|
||||
case "down": curRow++; break;
|
||||
case "left": curCol--; break;
|
||||
case "right": curCol++; break;
|
||||
}
|
||||
|
||||
// 出界无阻挡,兜底返回默认距离
|
||||
if (curRow < 0 || curRow >= _levelConfig.gridRows
|
||||
|| curCol < 0 || curCol >= _levelConfig.gridCols)
|
||||
{
|
||||
return 20f;
|
||||
}
|
||||
|
||||
// 找到阻挡点
|
||||
if (_gridOccupied[curRow, curCol])
|
||||
{
|
||||
// 总距离 = 空格数*点间距 + (单格距离 - 预留余量)
|
||||
float total = (emptyGridCount + 1) * _levelConfig.pointSpacing - hitMargin;
|
||||
// 最小前移保护,避免阻挡太近时几乎没动画
|
||||
return Mathf.Max(total, 6f);
|
||||
}
|
||||
|
||||
emptyGridCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>彻底删除指定箭头:销毁UI+清数据+停逻辑+移除列表</summary>
|
||||
private void DeleteArrowCompletely(ArrowConfig arrow)
|
||||
{
|
||||
@@ -1404,56 +1592,44 @@ namespace ChillConnect
|
||||
RunCoroutine(MoveAndResetCoroutine(arrow));
|
||||
}
|
||||
|
||||
private float _bounceSpeed = 180f;
|
||||
private readonly float _bounceSpeed = 1200f;
|
||||
private IEnumerator MoveAndResetCoroutine(ArrowConfig arrow)
|
||||
{
|
||||
arrow.movedDistance = 0f;
|
||||
arrow.finalMoveDir = GetFinalMoveDir(arrow);
|
||||
|
||||
// 向前移动的总距离(对应原逻辑2步=20px)
|
||||
float forwardTotal = 20f;
|
||||
// 动态计算:前移到快碰到阻挡点的距离
|
||||
float forwardTotal = GetDistanceToFirstBlock(arrow, 3f);
|
||||
float duration = forwardTotal / _bounceSpeed;
|
||||
float timer = 0f;
|
||||
|
||||
// ========== 第一段:向前移动 ==========
|
||||
// ========== 第一段:向前移动到快碰到阻挡 ==========
|
||||
while (timer < duration)
|
||||
{
|
||||
if (arrow == null || arrow.arrowObj == null) yield break;
|
||||
|
||||
timer += Time.deltaTime;
|
||||
// 钳制:保证前移距离不超过设定值,不会多走
|
||||
arrow.movedDistance = Mathf.Min(_bounceSpeed * timer, forwardTotal);
|
||||
|
||||
UpdateAllElementsPosition(arrow);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// 强制对齐前顶点,消除浮点误差
|
||||
// 核心:阻挡强震动 + 红色氛围闪烁
|
||||
TriggerBlockFlash();
|
||||
|
||||
// 强制对齐前移终点,消除浮点误差
|
||||
arrow.movedDistance = forwardTotal;
|
||||
UpdateAllElementsPosition(arrow);
|
||||
|
||||
// ========== 第二段:回弹复位 ==========
|
||||
timer = 0f;
|
||||
float startDis = arrow.movedDistance;
|
||||
// ========== 直接瞬间复位(删除原渐变回弹逻辑)==========
|
||||
// 可选:加 1 帧停顿,模拟碰撞卡顿感,觉得突兀就打开注释
|
||||
// yield return null;
|
||||
|
||||
while (timer < duration)
|
||||
{
|
||||
if (arrow == null || arrow.arrowObj == null) yield break;
|
||||
|
||||
timer += Time.deltaTime;
|
||||
// 核心修复:钳制 t 在 0~1 之间,防止插值超出范围变成负数
|
||||
float t = Mathf.Clamp01(timer / duration);
|
||||
arrow.movedDistance = Mathf.Lerp(startDis, 0f, t);
|
||||
|
||||
UpdateAllElementsPosition(arrow);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
// ========== 最终强制复位(双保险,绝对回到初始位置)==========
|
||||
// 距离归零 + 原始坐标强制校准,双保险保证精准回到初始位置
|
||||
arrow.movedDistance = 0f;
|
||||
UpdateAllElementsPosition(arrow);
|
||||
|
||||
// 兜底:直接用原始坐标校准,彻底消除距离计算的累计误差
|
||||
if (arrow.arrowObj != null)
|
||||
{
|
||||
arrow.arrowObj.SetPosition(arrow.originalArrowPos.x, arrow.originalArrowPos.y, 0);
|
||||
@@ -1762,6 +1938,8 @@ namespace ChillConnect
|
||||
if (isSuccess)
|
||||
{
|
||||
GameHelper.SetLevel(GameHelper.GetLevel() + 1);
|
||||
|
||||
// DataMgr.ArrowChProgress.Value += 10;
|
||||
//通关成功
|
||||
float[] cash_array = GameHelper.GetRewardValue(2);
|
||||
|
||||
@@ -1815,6 +1993,9 @@ namespace ChillConnect
|
||||
|
||||
// 先清空当前所有动态物体
|
||||
ClearAllDynamicObj();
|
||||
|
||||
//获取下一关的配置数据
|
||||
LoadLevelConfig();
|
||||
// 重新走初始化流程
|
||||
InitGridBounds();
|
||||
InitGridOccupied();
|
||||
@@ -1856,31 +2037,31 @@ namespace ChillConnect
|
||||
{
|
||||
public int id;
|
||||
public int startPoint;
|
||||
public int endPoint;
|
||||
public string color;
|
||||
public List<string> path;
|
||||
[NonSerialized] public int endPoint;
|
||||
[NonSerialized] public string color;
|
||||
|
||||
[NonSerialized]public string defaultDir;
|
||||
[NonSerialized]public List<Vector2> pathPointList;
|
||||
[NonSerialized]public List<GComponent> lineUnits;
|
||||
[NonSerialized]public GComponent arrowObj;
|
||||
|
||||
public string defaultDir;
|
||||
public List<Vector2> pathPointList;
|
||||
public List<GComponent> lineUnits;
|
||||
public GComponent arrowObj;
|
||||
[NonSerialized]public bool isMoving;
|
||||
[NonSerialized]public List<Vector2> originalLinePos;
|
||||
[NonSerialized]public Vector2 originalArrowPos;
|
||||
|
||||
public bool isMoving;
|
||||
public List<Vector2> originalLinePos;
|
||||
public Vector2 originalArrowPos;
|
||||
|
||||
public List<Vector2> totalTrack;
|
||||
public List<int> lineTrackIndex;
|
||||
public int arrowTrackIndex;
|
||||
public string finalMoveDir;
|
||||
[NonSerialized]public List<Vector2> totalTrack;
|
||||
[NonSerialized]public List<int> lineTrackIndex;
|
||||
[NonSerialized]public int arrowTrackIndex;
|
||||
[NonSerialized]public string finalMoveDir;
|
||||
|
||||
// ========== 距离驱动移动所需字段 ==========
|
||||
public float movedDistance; // 当前整体累计移动距离
|
||||
public float trackTotalLength; // 整条轨迹的总像素长度
|
||||
public List<float> lineInitOffsets; // 每个线条单元的初始距离偏移
|
||||
public float arrowInitOffset; // 箭头的初始距离偏移
|
||||
[NonSerialized]public float movedDistance; // 当前整体累计移动距离
|
||||
[NonSerialized]public float trackTotalLength; // 整条轨迹的总像素长度
|
||||
[NonSerialized]public List<float> lineInitOffsets; // 每个线条单元的初始距离偏移
|
||||
[NonSerialized]public float arrowInitOffset; // 箭头的初始距离偏移
|
||||
// ========== 运行时颜色缓存 ==========
|
||||
public Color runtimeColor;
|
||||
[NonSerialized]public Color runtimeColor;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
|
||||
Reference in New Issue
Block a user