Files
Travel_Run/Assets/Scripts/Maps/MapDatabase.cs
T
2026-07-06 17:34:13 +09:00

423 lines
16 KiB
C#

using UnityEngine;
public static class MapDatabase {
private static MapDefinition[] maps;
private const float GroundY = -2.4f;
private const float AerialY = -0.85f;
private const float BasicSpacing = 0.58f;
private const float ActionSpacing = 0.72f;
private const float LandingSpacing = 0.64f;
private const float AerialSpacing = 2.05f;
public static MapDefinition[] AllMaps {
get {
EnsureMaps();
return maps;
}
}
public static MapDefinition GetMap(MapId mapId) {
EnsureMaps();
for(int i = 0; i < maps.Length; i++)
{
if(maps[i].mapId == mapId)
{
return CloneMap(maps[i]);
}
}
return CloneMap(maps[0]);
}
public static MapDefinition GetMapByIndex(int mapIndex) {
EnsureMaps();
int clampedIndex = Mathf.Clamp(mapIndex, 0, maps.Length - 1);
return CloneMap(maps[clampedIndex]);
}
public static int GetIndex(MapId mapId) {
EnsureMaps();
for(int i = 0; i < maps.Length; i++)
{
if(maps[i].mapId == mapId)
{
return i;
}
}
return 0;
}
public static int LastMapIndex {
get {
EnsureMaps();
return maps.Length - 1;
}
}
private static void EnsureMaps() {
if(maps != null && maps.Length > 0)
{
return;
}
maps = new MapDefinition[] {
CreateTutorialIncheon(),
CreateJapan(),
CreateChina(),
CreateAmerica()
};
}
private static MapDefinition CreateTutorialIncheon() {
return new MapDefinition {
mapId = MapId.TutorialIncheon,
displayName = "Tutorial / Incheon",
routeName = "인천공항 출발 준비",
isTutorial = true,
platformSkin = Platform.PlatformSkin.Airport,
backgroundResourcePath = "Map_Tutorial_Incheon_Airport",
finishGateStyle = FinishGateStyle.AirportDeparture,
targetDistance = 320f,
timeLimit = 75f,
clearMileageReward = 150,
hasNextMap = true,
nextMapId = MapId.Japan,
openingSteps = new PlatformSpawner.TutorialStep[] {
Basic(),
Basic(),
Basic(GroundY, BasicSpacing),
Jump(GameManager.TutorialGuideType.Jump, "점프 구간", "가방 장애물이 오면 왼쪽 클릭으로 뛰어넘습니다."),
Basic(GroundY, LandingSpacing),
Basic(GroundY, BasicSpacing),
Aerial(GameManager.TutorialGuideType.DoubleJump, "2단 점프 구간", "다음 발판이 멀리 떨어져 있습니다.\n공중에서 왼쪽 클릭을 한 번 더 누릅니다."),
Basic(GroundY, LandingSpacing),
Basic(GroundY, BasicSpacing),
Slide(GameManager.TutorialGuideType.Slide, "슬라이드 구간", "천장 장애물이 오면 오른쪽 클릭을 누르고 지나갑니다."),
Basic(GroundY, LandingSpacing),
Basic(GroundY, BasicSpacing),
ForceHit(GameManager.TutorialGuideType.None, "", ""),
Basic(GroundY, LandingSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "초밥", "잃은 목숨을 1 회복합니다.\n방금 줄어든 목숨을 채워 봅니다.", Platform.ItemPattern.HealthSushi),
Basic(GroundY, LandingSpacing),
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "라멘", "잠깐 무적이 됩니다.\n먹은 뒤 다음 장애물에 일부러 부딪혀 봅니다.", Platform.ItemPattern.InvincibleRamen),
ForceHit(GameManager.TutorialGuideType.None, "", ""),
Basic(GroundY, LandingSpacing),
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "방어막", "다음 충돌 1회를 막습니다.\n먹은 뒤 바로 충돌을 막아 봅니다.", Platform.ItemPattern.Shield),
ForceHit(GameManager.TutorialGuideType.None, "", ""),
Basic(GroundY, LandingSpacing),
ForceHit(GameManager.TutorialGuideType.None, "", ""),
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "운동화", "느려진 속도를 회복합니다.\n방금 떨어진 속도를 되돌려 봅니다.", Platform.ItemPattern.SpeedShoes),
Basic(GroundY, BasicSpacing, Platform.MileagePattern.None, GameManager.TutorialGuideType.Items, "마일리지 카드", "잠깐 마일리지가 2배가 됩니다.\n먹고 바로 마일리지를 모아 봅니다.", Platform.ItemPattern.MileageCard),
Basic(GroundY, BasicSpacing, Platform.MileagePattern.SafeLine),
Basic(),
Basic(),
Basic(),
Basic(GroundY, LandingSpacing)
},
loopSteps = CreateEasyLoop()
};
}
private static MapDefinition CreateJapan() {
return new MapDefinition {
mapId = MapId.Japan,
displayName = "Japan",
routeName = "후쿠오카 라멘 투어",
isTutorial = false,
platformSkin = Platform.PlatformSkin.Japan,
backgroundResourcePath = "",
finishGateStyle = FinishGateStyle.JapanTorii,
targetDistance = 1200f,
timeLimit = 105f,
clearMileageReward = 250,
hasNextMap = true,
nextMapId = MapId.China,
openingSteps = new PlatformSpawner.TutorialStep[] {
Basic(),
Basic()
},
loopSteps = new PlatformSpawner.TutorialStep[] {
Basic(),
Jump(),
Basic(GroundY, LandingSpacing),
Aerial(),
Basic(GroundY, LandingSpacing),
Slide(SlideObstaclePattern.SlideLayout.CenterPair),
Basic(),
Jump(Platform.PlatformPattern.LowLeft),
Basic()
}
};
}
private static MapDefinition CreateChina() {
return new MapDefinition {
mapId = MapId.China,
displayName = "China",
routeName = "베이징 시장길",
isTutorial = false,
platformSkin = Platform.PlatformSkin.China,
backgroundResourcePath = "",
finishGateStyle = FinishGateStyle.ChinaPaifang,
targetDistance = 1450f,
timeLimit = 115f,
clearMileageReward = 350,
hasNextMap = true,
nextMapId = MapId.America,
openingSteps = new PlatformSpawner.TutorialStep[] {
Basic(),
Basic()
},
loopSteps = new PlatformSpawner.TutorialStep[] {
Basic(),
Jump(Platform.PlatformPattern.LowRight),
Basic(GroundY, LandingSpacing),
Slide(SlideObstaclePattern.SlideLayout.LeftPair),
Basic(),
Aerial(AerialY + 0.15f, 1.08f),
Basic(GroundY, LandingSpacing),
Jump(),
Basic(GroundY, LandingSpacing),
Slide(SlideObstaclePattern.SlideLayout.RightPair)
}
};
}
private static MapDefinition CreateAmerica() {
return new MapDefinition {
mapId = MapId.America,
displayName = "America",
routeName = "뉴욕 자유의 여신상",
isTutorial = false,
platformSkin = Platform.PlatformSkin.USA,
backgroundResourcePath = "Map_America_NewYork",
finishGateStyle = FinishGateStyle.AmericaLiberty,
targetDistance = 1700f,
timeLimit = 125f,
clearMileageReward = 500,
hasNextMap = false,
nextMapId = MapId.America,
openingSteps = new PlatformSpawner.TutorialStep[] {
Basic(),
Basic()
},
loopSteps = new PlatformSpawner.TutorialStep[] {
Basic(),
Jump(Platform.PlatformPattern.LowMid),
Basic(GroundY, 0.86f),
Slide(SlideObstaclePattern.SlideLayout.WidePair),
Basic(),
Aerial(AerialY + 0.2f, 1.0f),
Basic(GroundY, 0.86f),
Jump(Platform.PlatformPattern.LowLeft),
Basic(),
Slide(SlideObstaclePattern.SlideLayout.CenterPair),
Basic(),
Jump(Platform.PlatformPattern.LowRight)
}
};
}
private static PlatformSpawner.TutorialStep[] CreateEasyLoop() {
return new PlatformSpawner.TutorialStep[] {
Basic(),
Jump(),
Basic(GroundY, LandingSpacing),
Aerial(),
Basic(GroundY, LandingSpacing),
Slide(SlideObstaclePattern.SlideLayout.CenterPair),
Basic()
};
}
private static PlatformSpawner.TutorialStep Basic(
float yPosition = GroundY,
float spawnInterval = BasicSpacing,
Platform.MileagePattern mileagePattern = Platform.MileagePattern.SafeLine,
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
string title = "",
string message = "",
Platform.ItemPattern itemPattern = Platform.ItemPattern.None) {
return Step(
Platform.PlatformPattern.Empty,
mileagePattern,
SlideObstaclePattern.SlideLayout.Random,
guideType,
yPosition,
spawnInterval,
title,
message,
itemPattern,
PlatformSpawner.CoursePlatformType.Basic);
}
private static PlatformSpawner.TutorialStep Jump(
Platform.PlatformPattern platformPattern = Platform.PlatformPattern.LowMid,
float spawnInterval = ActionSpacing,
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
string title = "",
string message = "") {
return Step(
platformPattern,
Platform.MileagePattern.JumpArc,
SlideObstaclePattern.SlideLayout.Random,
guideType,
GroundY,
spawnInterval,
title,
message,
Platform.ItemPattern.None,
PlatformSpawner.CoursePlatformType.Jump);
}
private static PlatformSpawner.TutorialStep Jump(
GameManager.TutorialGuideType guideType,
string title,
string message) {
return Jump(Platform.PlatformPattern.LowMid, ActionSpacing, guideType, title, message);
}
private static PlatformSpawner.TutorialStep Aerial(
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
string title = "",
string message = "") {
return Aerial(AerialY, AerialSpacing, guideType, title, message);
}
private static PlatformSpawner.TutorialStep Aerial(
float yPosition,
float spawnInterval,
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
string title = "",
string message = "") {
return Step(
Platform.PlatformPattern.Empty,
Platform.MileagePattern.SafeLine,
SlideObstaclePattern.SlideLayout.Random,
guideType,
GroundY,
spawnInterval,
title,
message,
Platform.ItemPattern.None,
PlatformSpawner.CoursePlatformType.Basic);
}
private static PlatformSpawner.TutorialStep Slide(
SlideObstaclePattern.SlideLayout slideLayout = SlideObstaclePattern.SlideLayout.CenterPair,
float spawnInterval = ActionSpacing,
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.None,
string title = "",
string message = "") {
return Step(
Platform.PlatformPattern.Slide,
Platform.MileagePattern.SlideLine,
slideLayout,
guideType,
GroundY,
spawnInterval,
title,
message,
Platform.ItemPattern.None,
PlatformSpawner.CoursePlatformType.Slide);
}
private static PlatformSpawner.TutorialStep Slide(
GameManager.TutorialGuideType guideType,
string title,
string message) {
return Slide(SlideObstaclePattern.SlideLayout.CenterPair, ActionSpacing, guideType, title, message);
}
private static PlatformSpawner.TutorialStep ForceHit(
GameManager.TutorialGuideType guideType = GameManager.TutorialGuideType.Damage,
string title = "",
string message = "",
float spawnInterval = ActionSpacing) {
return Step(
Platform.PlatformPattern.ForceHit,
Platform.MileagePattern.None,
SlideObstaclePattern.SlideLayout.WidePair,
guideType,
GroundY,
spawnInterval,
title,
message,
Platform.ItemPattern.None,
PlatformSpawner.CoursePlatformType.ForceHit);
}
private static PlatformSpawner.TutorialStep Step(
Platform.PlatformPattern platformPattern,
Platform.MileagePattern mileagePattern,
SlideObstaclePattern.SlideLayout slideLayout,
GameManager.TutorialGuideType guideType,
float yPosition,
float spawnInterval,
string title = "",
string message = "",
Platform.ItemPattern itemPattern = Platform.ItemPattern.None,
PlatformSpawner.CoursePlatformType coursePlatformType = PlatformSpawner.CoursePlatformType.Basic) {
return new PlatformSpawner.TutorialStep {
coursePlatformType = coursePlatformType,
platformPattern = platformPattern,
mileagePattern = mileagePattern,
slideLayout = slideLayout,
itemPattern = itemPattern,
guideType = guideType,
yPosition = yPosition,
spawnInterval = spawnInterval,
title = title,
message = message
};
}
private static MapDefinition CloneMap(MapDefinition source) {
return new MapDefinition {
mapId = source.mapId,
displayName = source.displayName,
routeName = source.routeName,
isTutorial = source.isTutorial,
platformSkin = source.platformSkin,
backgroundResourcePath = source.backgroundResourcePath,
finishGateStyle = source.finishGateStyle,
targetDistance = source.targetDistance,
timeLimit = source.timeLimit,
clearMileageReward = source.clearMileageReward,
hasNextMap = source.hasNextMap,
nextMapId = source.nextMapId,
openingSteps = CloneSteps(source.openingSteps),
loopSteps = CloneSteps(source.loopSteps)
};
}
public static PlatformSpawner.TutorialStep[] CloneSteps(PlatformSpawner.TutorialStep[] source) {
if(source == null)
{
return new PlatformSpawner.TutorialStep[0];
}
PlatformSpawner.TutorialStep[] steps = new PlatformSpawner.TutorialStep[source.Length];
for(int i = 0; i < source.Length; i++)
{
PlatformSpawner.TutorialStep sourceStep = source[i];
steps[i] = Step(
sourceStep.platformPattern,
sourceStep.mileagePattern,
sourceStep.slideLayout,
sourceStep.guideType,
sourceStep.yPosition,
sourceStep.spawnInterval,
sourceStep.title,
sourceStep.message,
sourceStep.itemPattern,
sourceStep.coursePlatformType);
}
return steps;
}
}