Files
ArrowBeatTap-Gp/Assets/Editor/BatchLevelGenerator.cs
T

214 lines
5.9 KiB
C#

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
}