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
+1
View File
@@ -3,6 +3,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AColorUtility_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F37cc348edc804f4cb176b63962c716e7177200_003Fc7_003Fbf270f3f_003FColorUtility_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AColorUtility_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F37cc348edc804f4cb176b63962c716e7177200_003Fc7_003Fbf270f3f_003FColorUtility_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5a41d6b7189842eca409fd0b1c3e3dcf17bf78_003F0b_003F65960d28_003FDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADictionary_00602_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F5a41d6b7189842eca409fd0b1c3e3dcf17bf78_003F0b_003F65960d28_003FDictionary_00602_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEditorGUILayout_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4b8f645257c94d1296f440a10c6f388e961000_003Fa2_003F73a0821f_003FEditorGUILayout_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEditorGUILayout_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4b8f645257c94d1296f440a10c6f388e961000_003Fa2_003F73a0821f_003FEditorGUILayout_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AInput_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fe35f1b2769b6499aa0f83a53f65df1367c00_003F58_003F54ee7497_003FInput_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F37cc348edc804f4cb176b63962c716e7177200_003F25_003Fe0bd2277_003FObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F37cc348edc804f4cb176b63962c716e7177200_003F25_003Fe0bd2277_003FObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AScriptableObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F37cc348edc804f4cb176b63962c716e7177200_003F45_003F06fae3db_003FScriptableObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AScriptableObject_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003FUsers_003F97354_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F37cc348edc804f4cb176b63962c716e7177200_003F45_003F06fae3db_003FScriptableObject_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<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_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>
@@ -21,9 +21,9 @@ namespace FGUI.Arrow_game
{ {
base.ConstructFromXML(xml); base.ConstructFromXML(xml);
xin_1 = (GImage)GetChildAt(0); xin_1 = (GImage)GetChildAt(3);
xin_2 = (GImage)GetChildAt(1); xin_2 = (GImage)GetChildAt(4);
xin_3 = (GImage)GetChildAt(2); xin_3 = (GImage)GetChildAt(5);
} }
} }
} }
@@ -7,11 +7,12 @@ namespace FGUI.Arrow_game
{ {
public partial class com_arrow_game : GComponent public partial class com_arrow_game : GComponent
{ {
public GGraph bg; public Controller mode;
public GButton btn_menu; public GButton btn_menu;
public GComponent view_container; public GComponent view_container;
public ArrorPoint point; public ArrorPoint point;
public GButton btn_close; public GButton btn_close;
public GComponent com_money;
public HeartsPanel HeartsPanel; public HeartsPanel HeartsPanel;
public GButton btn_clear; public GButton btn_clear;
public GButton btn_hint; public GButton btn_hint;
@@ -19,6 +20,8 @@ namespace FGUI.Arrow_game
public btn_big btn_big; public btn_big btn_big;
public btn_big btn_small; public btn_big btn_small;
public GSlider zoomSlide; public GSlider zoomSlide;
public GGraph samll_point;
public GTextField text_level;
public const string URL = "ui://sjl9teijrsd40"; public const string URL = "ui://sjl9teijrsd40";
public static com_arrow_game CreateInstance() public static com_arrow_game CreateInstance()
@@ -30,18 +33,21 @@ namespace FGUI.Arrow_game
{ {
base.ConstructFromXML(xml); base.ConstructFromXML(xml);
bg = (GGraph)GetChildAt(0); mode = GetControllerAt(0);
btn_menu = (GButton)GetChildAt(1); btn_menu = (GButton)GetChildAt(2);
view_container = (GComponent)GetChildAt(2); view_container = (GComponent)GetChildAt(3);
point = (ArrorPoint)GetChildAt(3); point = (ArrorPoint)GetChildAt(4);
btn_close = (GButton)GetChildAt(5); btn_close = (GButton)GetChildAt(5);
HeartsPanel = (HeartsPanel)GetChildAt(6); com_money = (GComponent)GetChildAt(6);
btn_clear = (GButton)GetChildAt(8); HeartsPanel = (HeartsPanel)GetChildAt(7);
btn_hint = (GButton)GetChildAt(9); btn_clear = (GButton)GetChildAt(9);
com_finger = (com_finger)GetChildAt(10); btn_hint = (GButton)GetChildAt(10);
btn_big = (btn_big)GetChildAt(11); com_finger = (com_finger)GetChildAt(11);
btn_small = (btn_big)GetChildAt(12); btn_big = (btn_big)GetChildAt(12);
zoomSlide = (GSlider)GetChildAt(13); btn_small = (btn_big)GetChildAt(13);
zoomSlide = (GSlider)GetChildAt(14);
samll_point = (GGraph)GetChildAt(15);
text_level = (GTextField)GetChildAt(17);
} }
} }
} }
+214
View File
@@ -0,0 +1,214 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using Random = UnityEngine.Random;
public static class BatchAllLevelsToOneFile
{
// 全局网格配置(和游戏一致)
private static int GridRows = 10;
private static int GridCols = 10;
private const int PointSpacing = 60;
// 关卡范围
private const int StartLevelId = 1;
private const int TotalLevelCount = 100;
// 颜色池、方向池
private static readonly List<string> ColorPool = new List<string>
{
"#FF3333", "#3399FF", "#33FF66", "#FFFF33", "#CC66FF"
};
private static readonly List<string> DirPool = new List<string>
{
"up", "down", "left", "right"
};
[MenuItem("关卡工具/生成全部100关 → 合并到单文件 all_levels.json")]
public static void GenerateAllLevelsToOneJson()
{
AllLevelRoot root = new AllLevelRoot();
root.levels = new List<LevelConfig>();
for (int i = 0; i < TotalLevelCount; i++)
{
int levelIndex = i + 1;
GetGridSize(levelIndex);
int currentLevelId = StartLevelId + i;
int diffGroup = GetDifficultyGroup(levelIndex);
LevelConfig oneLevel = BuildOneLevel(currentLevelId, levelIndex, diffGroup);
root.levels.Add(oneLevel);
Debug.Log($"已组装关卡: {currentLevelId}");
}
// 写入单文件
string savePath = Path.Combine(Application.streamingAssetsPath, "all_levels.json");
string json = JsonUtility.ToJson(root, prettyPrint: true);
File.WriteAllText(savePath, json);
EditorUtility.DisplayDialog("完成",
$"共 {TotalLevelCount} 关已合并到单个文件\n路径: StreamingAssets/all_levels.json", "确定");
}
private static void GetGridSize(int levelIndex)
{
if (levelIndex <= 20)
{
GridRows = 10;
GridCols = 10;
}
else if (levelIndex <= 40)
{
GridRows = 15;
GridCols = 15;
}
else if (levelIndex <= 60)
{
GridRows = 20;
GridCols = 20;
}
else if (levelIndex <= 80)
{
GridRows = 30;
GridCols = 30;
}
}
// 难度分组 1~5
private static int GetDifficultyGroup(int levelIndex)
{
if (levelIndex <= 20) return 1;
if (levelIndex <= 40) return 2;
if (levelIndex <= 60) return 3;
if (levelIndex <= 80) return 4;
return 5;
}
// 构建单关数据
private static LevelConfig BuildOneLevel(int levelId, int levelIndex, int diffGroup)
{
LevelConfig cfg = new LevelConfig
{
levelId = levelId,
levelName = $"第{levelIndex}关",
gridRows = GridRows,
gridCols = GridCols,
pointSpacing = PointSpacing,
arrows = new List<ArrowConfig>()
};
int arrowCount = GetArrowCountByDiff(diffGroup);
HashSet<int> usedPoints = new HashSet<int>();
for (int aIdx = 0; aIdx < arrowCount; aIdx++)
{
ArrowConfig arrow = CreateSingleArrow(diffGroup, usedPoints, aIdx + 1);
cfg.arrows.Add(arrow);
}
return cfg;
}
private static int GetArrowCountByDiff(int diff)
{
return diff switch
{
1 => Random.Range(3, 10),
2 => Random.Range(5, 15),
3 => Random.Range(7, 20),
4 => Random.Range(10, 25),
5 => Random.Range(15, 30),
_ => 1
};
}
private static int GetPathLengthByDiff(int diff)
{
return diff switch
{
1 => 0,
2 => Random.Range(3, 5),
3 => Random.Range(3, 8),
4 => Random.Range(3, 10),
5 => Random.Range(3, 15),
_ => 0
};
}
private static ArrowConfig CreateSingleArrow(int diff, HashSet<int> usedPoints, int arrowId)
{
ArrowConfig arrow = new ArrowConfig
{
id = arrowId,
path = new List<string>(),
color = ColorPool[Random.Range(0, ColorPool.Count)]
};
int startPoint = GetRandomEmptyPoint(usedPoints);
arrow.startPoint = startPoint;
usedPoints.Add(startPoint);
int pathLen = GetPathLengthByDiff(diff);
if (pathLen > 0)
{
arrow.path = GenerateRandomPath(pathLen);
}
return arrow;
}
private static List<string> GenerateRandomPath(int length)
{
List<string> path = new List<string>();
for (int i = 0; i < length; i++)
{
path.Add(DirPool[Random.Range(0, DirPool.Count)]);
}
return path;
}
private static int GetRandomEmptyPoint(HashSet<int> used)
{
int maxPoint = GridRows * GridCols - 1;
int pointId;
do
{
pointId = Random.Range(0, maxPoint + 1);
} while (used.Contains(pointId));
return pointId;
}
#region + /
[Serializable]
public class AllLevelRoot
{
public List<LevelConfig> levels;
}
[Serializable]
public class LevelConfig
{
public int levelId;
public string levelName;
public int gridRows;
public int gridCols;
public int pointSpacing;
public List<ArrowConfig> arrows;
}
[Serializable]
public class ArrowConfig
{
public int id;
public int startPoint;
public List<string> path;
public string color;
}
#endregion
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: efc085dd10631ca48a50c72036c3514f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 435 KiB

After

Width:  |  Height:  |  Size: 667 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 MiB

After

Width:  |  Height:  |  Size: 5.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 KiB

@@ -0,0 +1,153 @@
fileFormatVersion: 2
guid: f8bdace28b3e087489176bc7aa4ecd3c
TextureImporter:
internalIDToNameTable: []
externalObjects: {}
serializedVersion: 13
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
flipGreenChannel: 0
isReadable: 0
streamingMipmaps: 0
streamingMipmapsPriority: 0
vTOnly: 0
ignoreMipmapLimit: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: 1
aniso: 1
mipBias: 0
wrapU: 0
wrapV: 0
wrapW: 0
nPOTScale: 1
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spritePixelsToUnits: 100
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spriteGenerateFallbackPhysicsShape: 1
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
singleChannelComponent: 0
flipbookRows: 1
flipbookColumns: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
ignorePngGamma: 0
applyGammaDecoding: 0
swizzle: 50462976
cookieLightType: 0
platformSettings:
- serializedVersion: 3
buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: iPhone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: WebGL
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
- serializedVersion: 3
buildTarget: Android
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
ignorePlatformSupport: 0
androidETC2FallbackOverride: 0
forceMaximumCompressionQuality_BC6H_BC7: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
bones: []
spriteID:
internalID: 0
vertices: []
indices:
edges: []
weights: []
secondaryTextures: []
nameFileIdTable: {}
mipmapLimitGroupName:
pSDRemoveMatte: 0
userData:
assetBundleName:
assetBundleVariant:
+397 -320
View File
@@ -5,6 +5,8 @@ using System.Linq;
using DG.Tweening; using DG.Tweening;
using FairyGUI; using FairyGUI;
using FGUI.Arrow_game; using FGUI.Arrow_game;
using FGUI.Common_01;
using IgnoreOPS;
using UnityEngine; using UnityEngine;
namespace ChillConnect namespace ChillConnect
@@ -26,11 +28,6 @@ namespace ChillConnect
// 关卡总配置数据 // 关卡总配置数据
private LevelConfig _levelConfig; 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 int gridColNum = 10;
private readonly float pointSpace = 60f; private readonly float pointSpace = 60f;
@@ -181,6 +178,11 @@ namespace ChillConnect
// ========= 编辑器模拟触摸(仅编辑模式生效) ========= // ========= 编辑器模拟触摸(仅编辑模式生效) =========
// ========== 编辑器鼠标拖拽 ========== // ========== 编辑器鼠标拖拽 ==========
// 初始化未完成,直接跳过拖拽
if (!_initComplete)
return;
#if UNITY_EDITOR #if UNITY_EDITOR
float moveThreshold = 1f; // 移动阈值,大于这个值才算有效拖动 float moveThreshold = 1f; // 移动阈值,大于这个值才算有效拖动
@@ -283,6 +285,8 @@ namespace ChillConnect
protected override void OnOpenBefore(object args) protected override void OnOpenBefore(object args)
{ {
//加载配置
InitAllLevelData();
_viewContainer = ui.view_container; _viewContainer = ui.view_container;
// 初始化FGUI模板 // 初始化FGUI模板
_dotTemplate = (ArrorPoint)UIPackage.CreateObject("Arrow_game", "ArrorPoint"); _dotTemplate = (ArrorPoint)UIPackage.CreateObject("Arrow_game", "ArrorPoint");
@@ -316,9 +320,34 @@ namespace ChillConnect
} }
#endregion #endregion
#region & #region
protected override void AddListener()
{
GameDispatcher.Instance.AddListener(GameMsg.reset_game, OnRestartGame);
GameDispatcher.Instance.AddListener(GameMsg.Update102, SetTopCurr);
GameDispatcher.Instance.AddListener(GameMsg.Update101, SetTopCurr);
}
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() private void InitView()
{ {
// 重置手势状态
_isTwoFingerTouch = false;
_isDraging = false;
SetModel();
ui.text_level.SetVar("lv", GameHelper.GetLevel().ToString()).FlushVars();
// 关闭按钮 // 关闭按钮
ui.btn_close.SetClick(() => { CtrlCloseUI(); }); ui.btn_close.SetClick(() => { CtrlCloseUI(); });
ui.btn_clear.SetClick(OnClickDeleteItem); ui.btn_clear.SetClick(OnClickDeleteItem);
@@ -337,30 +366,85 @@ namespace ChillConnect
// 滑动条初始居中(对应 1.0 缩放) // 滑动条初始居中(对应 1.0 缩放)
float initValue = GetSliderValueByScale(1f); float initValue = GetSliderValueByScale(1f);
_zoomSlider.value = initValue; _zoomSlider.value = initValue;
// 容器初始居中 // 先兜底重置为默认锚点
float startX = (Screen.width - _viewContainer.width) * 0.5f; _viewContainer.pivot = new Vector2(0, 0);
float startY = (Screen.height - _viewContainer.height) * 0.5f;
_viewContainer.SetPosition(startX, startY,0);
// 重置手势状态 if (_levelConfig == null)
_isTwoFingerTouch = false; {
_isDraging = false; _initComplete = true;
return;
}
// 第一步:绘制网格 → 内部会计算网格中心、修改pivot为网格中心
if (_levelConfig == null) return;
// 1. 绘制网格圆点
DrawGridDots(_levelConfig); DrawGridDots(_levelConfig);
allArrowList = _levelConfig.arrows; // ========== 核心:把网格中心钉在屏幕中心 ==========
// _gridWorldCenter 是 DrawGridDots 里 CalculateGridCenter 算出的值
float screenCenterX = Screen.width * 0.5f;
float screenCenterY = Screen.height * 0.5f;
// 计算容器需要移动多少,才能让网格中心正好对准屏幕中心
float targetContainerX = screenCenterX - _gridWorldCenter.x;
float targetContainerY = screenCenterY - _gridWorldCenter.y;
// 直接设置容器位置
_viewContainer.SetPosition(targetContainerX, targetContainerY, 0);
// ==================================================
// 2. 初始化所有箭头 + 路径线条 + 标记网格占用
foreach (var arrow in _levelConfig.arrows) foreach (var arrow in _levelConfig.arrows)
{ {
BuildArrowPath(arrow, _levelConfig); BuildArrowPath(arrow, _levelConfig);
CreateArrowAndLines(arrow, _levelConfig); CreateArrowAndLines(arrow, _levelConfig);
MarkArrowOccupiedCells(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 #endregion
private void InitGridBounds() private void InitGridBounds()
@@ -428,7 +512,10 @@ namespace ChillConnect
#region #region
private void LoadLevelConfig() 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 为空的箭头,设置默认方向 // 给 path 为空的箭头,设置默认方向
foreach (var arrow in _levelConfig.arrows) 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 #endregion
#region #region
@@ -531,7 +650,6 @@ namespace ChillConnect
SetViewPivotToGridCenter(); SetViewPivotToGridCenter();
} }
/// <summary>计算网格整体世界中心(原有网格坐标不变)</summary>
/// <summary>计算整个网格圆点区域的世界中心点</summary> /// <summary>计算整个网格圆点区域的世界中心点</summary>
private void CalculateGridCenter(LevelConfig cfg) private void CalculateGridCenter(LevelConfig cfg)
{ {
@@ -693,44 +811,28 @@ namespace ChillConnect
CreateArrowOnly(arrow, pathPoints[pathPoints.Count - 1]); CreateArrowOnly(arrow, pathPoints[pathPoints.Count - 1]);
arrow.originalArrowPos = new Vector2(arrow.arrowObj.x, arrow.arrowObj.y); arrow.originalArrowPos = new Vector2(arrow.arrowObj.x, arrow.arrowObj.y);
arrow.arrowTrackIndex = arrow.totalTrack.Count - 1; arrow.arrowTrackIndex = arrow.totalTrack.Count - 1;
}
// 线条/箭头 统一点击回调
private void OnPathClick(ArrowConfig clickArrow)
{
if (clickArrow.isMoving)
{
Debug.Log($"[arrow] {clickArrow.id}正在移动,请勿点击其他箭头");
return;
}
// 点击的是当前提示箭头,直接隐藏手指
if (_currentTipArrow == clickArrow)
{
HideFingerTip();
}
// ========= 删除模式:直接删除箭头,不走移动逻辑 ========= // 在 CreateArrowAndLines 方法最后,补充这段初始化代码
if (_isDeleteMode) // ========== 新增:初始化距离偏移 ==========
{ arrow.movedDistance = 0f;
DeleteArrowCompletely(clickArrow); // 轨迹总长度 = (点数-1) * 点间距
return; arrow.trackTotalLength = (arrow.totalTrack.Count - 1) * 10f;
} // 箭头初始在轨迹末端
arrow.arrowInitOffset = arrow.trackTotalLength;
clickArrow.isMoving = true; // 每个线条的初始偏移 = 索引 * 点间距
bool hasBlock = CheckBlockByGrid(clickArrow); arrow.lineInitOffsets = new List<float>();
Debug.Log("[arrow] 点击箭头:" + clickArrow.id +$"hasBlock==={hasBlock}"); for (int i = 0; i < arrow.lineUnits.Count; i++)
if (hasBlock)
{ {
MoveThenReset(clickArrow); arrow.lineInitOffsets.Add(i * 10f);
}
else
{
MoveToDisappear(clickArrow);
} }
} }
#endregion
#region
#region
/// <summary>点击删除道具,开启/关闭删除模式</summary> /// <summary>点击删除道具,开启/关闭删除模式</summary>
private void OnClickDeleteItem() private void OnClickDeleteItem()
{ {
@@ -857,6 +959,43 @@ namespace ChillConnect
#endregion #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) private bool CheckBlockByGrid(ArrowConfig curArrow)
{ {
@@ -1007,6 +1146,11 @@ namespace ChillConnect
{ {
ShowResult(true); ShowResult(true);
} }
else
{
// 消除每条线小概率触发
DisappearLineGetReward();
}
// 8. 退出删除模式 // 8. 退出删除模式
_isDeleteMode = false; _isDeleteMode = false;
Debug.Log("[arrow] 箭头已彻底删除"); Debug.Log("[arrow] 箭头已彻底删除");
@@ -1048,236 +1192,114 @@ namespace ChillConnect
RunCoroutine(MoveAndResetCoroutine(arrow)); RunCoroutine(MoveAndResetCoroutine(arrow));
} }
// 回弹速度单独配置,和移动速度分开
private float _bounceSpeed = 180f;
private IEnumerator MoveAndResetCoroutine(ArrowConfig arrow) private IEnumerator MoveAndResetCoroutine(ArrowConfig arrow)
{ {
float frameDelay = 0.01f; arrow.movedDistance = 0f;
int stepCount = 2; arrow.finalMoveDir = GetFinalMoveDir(arrow);
int moved = 0;
int trackMaxIndex = arrow.totalTrack.Count - 1;
string dir; // 向前移动的总距离(对应原逻辑2步=20px,可自行调整)
if (arrow.path != null && arrow.path.Count > 0) float forwardTotal = 20f;
{ float timer = 0f;
dir = arrow.path[arrow.path.Count - 1]; float duration = forwardTotal / _bounceSpeed;
}
else if (!string.IsNullOrEmpty(arrow.defaultDir))
{
dir = arrow.defaultDir;
}
else
{
dir = "up";
}
arrow.finalMoveDir = dir;
while (moved < stepCount) // 第一段:向前移动
while (timer < duration)
{ {
// 新增空对象防护 if (arrow == null || arrow.arrowObj == null) yield break;
if (arrow == null || arrow.arrowObj == null)
{ timer += Time.deltaTime;
Debug.Log($"[arrow] MoveAndResetCoroutine arrow 为空, 协程结束"); arrow.movedDistance = _bounceSpeed * timer;
yield break;
UpdateAllElementsPosition(arrow);
yield return null;
} }
for (int i = 0; i < arrow.lineUnits.Count; i++) // 第二段:回弹到初始位置
timer = 0f;
float startDis = arrow.movedDistance;
while (timer < duration)
{ {
int curIdx = arrow.lineTrackIndex[i]; if (arrow == null || arrow.arrowObj == null) yield break;
if (curIdx < trackMaxIndex)
{ timer += Time.deltaTime;
curIdx++; float t = timer / duration;
arrow.lineUnits[i].SetPosition(arrow.totalTrack[curIdx].x, arrow.totalTrack[curIdx].y, 0); arrow.movedDistance = Mathf.Lerp(startDis, 0f, t);
arrow.lineTrackIndex[i] = curIdx;
} UpdateAllElementsPosition(arrow);
else yield return null;
{
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) arrow.movedDistance = 0f;
{ UpdateAllElementsPosition(arrow);
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);
}
// 复位位置
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;
}
if(arrow.arrowObj != null)
{
arrow.arrowObj.SetPosition(arrow.originalArrowPos.x, arrow.originalArrowPos.y, 0);
}
arrow.arrowTrackIndex = arrow.totalTrack.Count - 1;
arrow.isMoving = false; arrow.isMoving = false;
} }
/// <summary>统一更新箭头+所有线条的位置</summary>
private void UpdateAllElementsPosition(ArrowConfig arrow)
{
for (int i = 0; i < arrow.lineUnits.Count; i++)
{
float curDist = arrow.lineInitOffsets[i] + arrow.movedDistance;
Vector2 pos = GetPositionByDistance(arrow, curDist);
arrow.lineUnits[i].SetPosition(pos.x, pos.y, 0);
}
float arrowCurDist = arrow.arrowInitOffset + arrow.movedDistance;
Vector2 arrowPos = GetPositionByDistance(arrow, arrowCurDist);
arrow.arrowObj.SetPosition(arrowPos.x, arrowPos.y, 0);
}
private void MoveToDisappear(ArrowConfig arrow) private void MoveToDisappear(ArrowConfig arrow)
{ {
RunCoroutine(MoveAndDisappearCoroutine(arrow)); RunCoroutine(MoveAndDisappearCoroutine(arrow));
} }
// 新增:统一移动速度(像素/秒),数值越大移动越快,可自由修改
[SerializeField] private float _moveSpeed = 800f;
private IEnumerator MoveAndDisappearCoroutine(ArrowConfig arrow) private IEnumerator MoveAndDisappearCoroutine(ArrowConfig arrow)
{ {
Debug.Log($"[arrow] arrow.totalTrack.Count =={arrow.totalTrack.Count}"); arrow.movedDistance = 0f;
float frameDelay = 0.01f; arrow.finalMoveDir = GetFinalMoveDir(arrow);
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;
while (true) while (true)
{ {
// 兜底:对象已销毁,直接退出 // 空对象兜底保护
if (arrow == null || arrow.arrowObj == null) if (arrow == null || arrow.arrowObj == null)
{ {
Debug.Log($"arrow 为空, 协程结束");
yield break; yield break;
} }
// 线条移动 // 每帧累计移动距离:速度 * 时间增量
float deltaDis = _moveSpeed * Time.deltaTime;
arrow.movedDistance += deltaDis;
// 更新所有线条位置
for (int i = 0; i < arrow.lineUnits.Count; i++) for (int i = 0; i < arrow.lineUnits.Count; i++)
{ {
int curIdx = arrow.lineTrackIndex[i]; float curDist = arrow.lineInitOffsets[i] + arrow.movedDistance;
if (curIdx < trackMaxIndex) Vector2 pos = GetPositionByDistance(arrow, curDist);
{ arrow.lineUnits[i].SetPosition(pos.x, pos.y, 0);
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; float arrowCurDist = arrow.arrowInitOffset + arrow.movedDistance;
if (arrowIdx < trackMaxIndex) Vector2 arrowPos = GetPositionByDistance(arrow, arrowCurDist);
{ arrow.arrowObj.SetPosition(arrowPos.x, arrowPos.y, 0);
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;
}
// ========= 边界判断:有线箭头取尾部轨迹,单点箭头取自身 ========= // 边界检测:以尾部线条为准(和原逻辑一致)
// 直接取箭头实时坐标,不再使用totalTrack静态点位 Vector2 tailPos = GetPositionByDistance(arrow, arrow.movedDistance);
bool isOut = false; if (CheckIsOutOfBounds(tailPos, arrow.finalMoveDir))
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)
{ {
// ========== 以下销毁逻辑和原代码保持一致 ==========
ReleaseArrowOccupied(arrow); ReleaseArrowOccupied(arrow);
// 销毁线条
foreach (var line in arrow.lineUnits) foreach (var line in arrow.lineUnits)
{ {
if(line != null) if (line != null)
{ {
_viewContainer.RemoveChild(line); _viewContainer.RemoveChild(line);
line.Dispose(); line.Dispose();
@@ -1285,8 +1307,7 @@ namespace ChillConnect
} }
arrow.lineUnits.Clear(); arrow.lineUnits.Clear();
// 销毁箭头 if (arrow.arrowObj != null)
if(arrow.arrowObj != null)
{ {
_viewContainer.RemoveChild(arrow.arrowObj); _viewContainer.RemoveChild(arrow.arrowObj);
arrow.arrowObj.Dispose(); arrow.arrowObj.Dispose();
@@ -1294,80 +1315,143 @@ namespace ChillConnect
} }
arrow.isMoving = false; arrow.isMoving = false;
_remainArrowCount--; _remainArrowCount--;
if (_remainArrowCount <= 0) if (_remainArrowCount <= 0)
{ {
ShowResult(true); ShowResult(true);
} }
else
{
DisappearLineGetReward();
}
yield break; yield break;
} }
yield return new WaitForSeconds(frameDelay); yield return null; // 每帧执行一次,平滑移动
} }
} }
#endregion
#region & #region
private void OnArrowClick(ArrowConfig arrow) /// <summary>根据距离,计算沿轨迹的实际坐标</summary>
private Vector2 GetPositionByDistance(ArrowConfig arrow, float distance)
{ {
if (arrow.isMoving) return; int trackCount = arrow.totalTrack.Count;
arrow.isMoving = true; const float segmentLen = 10f; // 轨迹点固定间距
}
private void UpdateArrowMove(ArrowConfig arrow) // 距离在轨迹范围内:两点插值得到精确位置
if (distance <= arrow.trackTotalLength)
{ {
// 关键拦截:不允许移动 / 对象已销毁 → 直接退出 float indexFloat = distance / segmentLen;
if (!arrow.isMoving || arrow.arrowObj == null) int index0 = Mathf.FloorToInt(indexFloat);
return; int index1 = Mathf.Min(index0 + 1, trackCount - 1);
float t = indexFloat - index0;
if (!arrow.isMoving) return; Vector2 p0 = arrow.totalTrack[index0];
List<Vector2> path = arrow.pathPointList; Vector2 p1 = arrow.totalTrack[index1];
return Vector2.Lerp(p0, p1, t);
if (arrow.targetIndex < 0)
{
arrow.isMoving = false;
arrow.arrowObj.visible = false;
foreach (var line in arrow.lineUnits) line.visible = false;
return;
}
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--;
} }
// 距离超出轨迹:沿最终方向直线延伸
else else
{ {
Vector2 dir = (targetPos - curPos).normalized; float extraDis = distance - arrow.trackTotalLength;
Vector2 newPos = curPos + dir * _moveSpeed * Time.deltaTime; Vector2 endPos = arrow.totalTrack[trackCount - 1];
arrow.arrowObj.SetPosition(newPos.x, newPos.y, 0); Vector2 dir = DirToVector2(arrow.finalMoveDir);
return endPos + dir * extraDis;
}
} }
RefreshLineVisible(arrow); /// <summary>方向字符串转单位向量</summary>
/// <summary>方向字符串转单位向量(适配 FGUI 坐标系:y 轴向下)</summary>
private Vector2 DirToVector2(string dir)
{
return dir switch
{
"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";
} }
private void RefreshLineVisible(ArrowConfig arrow) /// <summary>统一边界检测</summary>
private bool CheckIsOutOfBounds(Vector2 pos, string dir)
{ {
int segIndex = 0; switch (dir)
int totalSeg = arrow.pathPointList.Count - 1;
for (int s = 0; s < totalSeg; s++)
{ {
bool isShow = s < arrow.targetIndex; case "right": return pos.x > gridRight + outOffset;
for (int i = 0; i < 6; i++) case "left": return pos.x < gridLeft - outOffset;
{ case "down": return pos.y > gridBottom + outOffset;
arrow.lineUnits[segIndex + i].visible = isShow; case "up": return pos.y < gridTop - outOffset;
} default: return false;
segIndex += 6;
} }
} }
#endregion #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 #region
/// <summary>全局启动协程 + 自动记录,关闭界面时统一停止</summary> /// <summary>全局启动协程 + 自动记录,关闭界面时统一停止</summary>
@@ -1404,6 +1488,8 @@ namespace ChillConnect
} }
#endregion #endregion
#region
/// <summary> /// <summary>
/// 弹出结算 /// 弹出结算
/// isSuccess: true=成功,false=失败 /// isSuccess: true=成功,false=失败
@@ -1454,10 +1540,15 @@ namespace ChillConnect
} }
} }
// 重新开始本局 /// <summary>
/// 重新开始本局
/// </summary>
/// <param name="a">true: 重生 false:重开一局或者下一局 </param>
private void OnRestartGame(object a = null) private void OnRestartGame(object a = null)
{ {
if (a!=null && (bool)a)
Debug.Log($"[ArrowGameUI] 重新开始本局 a:{(bool)a}");
if (a != null && (bool)a)
{ {
_heartCount = 3; _heartCount = 3;
for (int i = _heartCount; i > 0; i--) for (int i = _heartCount; i > 0; i--)
@@ -1467,21 +1558,6 @@ namespace ChillConnect
return; 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(); ClearAllDynamicObj();
// 重新走初始化流程 // 重新走初始化流程
@@ -1491,22 +1567,12 @@ namespace ChillConnect
_collidedArrows.Clear(); _collidedArrows.Clear();
_remainArrowCount = _levelConfig.arrows.Count; _remainArrowCount = _levelConfig.arrows.Count;
DataMgr.ArrowResultLevel.Value = 1; DataMgr.ArrowResultLevel.Value = 1;
InitView(); 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 #endregion
} }
#region & #region &
@@ -1547,12 +1613,23 @@ namespace ChillConnect
public bool isMoving; public bool isMoving;
public List<Vector2> originalLinePos; public List<Vector2> originalLinePos;
public Vector2 originalArrowPos; public Vector2 originalArrowPos;
public int targetIndex;
public List<Vector2> totalTrack; public List<Vector2> totalTrack;
public List<int> lineTrackIndex; public List<int> lineTrackIndex;
public int arrowTrackIndex; public int arrowTrackIndex;
public string finalMoveDir; 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 #endregion
} }
@@ -216,26 +216,6 @@ namespace ChillConnect
ui.text_award.text = DataMgr.Coin.Value.ToString(); ui.text_award.text = DataMgr.Coin.Value.ToString();
} }
ui.com_ch.btn_cash.title = GameHelper.getDesByKey("ch_out_1"); 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()) if (GameHelper.IsGiftSwitch())
{ {
@@ -343,6 +323,8 @@ namespace ChillConnect
DOVirtual.DelayedCall(0.7f, () => DOVirtual.DelayedCall(0.7f, () =>
{ {
GameDispatcher.Instance.Dispatch(GameMsg.reset_game, false);
CtrlCloseUI(); CtrlCloseUI();
// if (IsLevelSuccess) UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.OpenGameUI_Open, true); // if (IsLevelSuccess) UICtrlDispatcher.Instance.Dispatch(UICtrlMsg.OpenGameUI_Open, true);
}); });
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: fdb213237d724799af65feeec096c3ec guid: b6c169ea8745dbc46aa44fc0684e3209
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}
userData: userData:
-77
View File
@@ -1,77 +0,0 @@
{
"levelId": 1001,
"levelName": "可视化编辑关卡",
"gridRows": 10,
"gridCols": 10,
"pointSpacing": 60,
"arrows": [
{
"id": 1,
"startPoint": 0,
"endPoint": 17,
"color": "#FFFFFF",
"path": [
"right",
"right",
"right",
"right",
"down",
"right",
"right",
"right"
]
},
{
"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",
"up"
]
},
{
"id": 4,
"startPoint": 88,
"endPoint": 88,
"color": "#FFFF00",
"path": []
},
{
"id": 5,
"startPoint": 92,
"endPoint": 84,
"color": "#FFFFFF",
"path": [
"up",
"left",
"left",
"up",
"right",
"right",
"right",
"down",
"right"
]
}
]
}