Repository navigation
MapManager
김광수 edited this page Oct 11, 2023
·
5 revisions
Map을 생성하고 관리하는 Manager입니다.
-
maxXIndex
- Map 리스트의 2차원 크기입니다.
- 지도의 최대 x축
-
maxYIndex
- Map 리스트의 1차원 크기입니다.
- 지도의 최대 y축
-
minX
- 한 층에서 만들어질 location의 최소 개수 입니다.
-
maxX
- 한 층에서 만들어질 locaction의 최대 개수 입니다.
-
Map
- 지도의 정보를 리스트배열로 표현 합니다.
- 갈 수 없는 지역은 null로 처리하고 갈 수 있는 지역에는 LocationInfo로 해당 지역의 정보를 가지고 있습니다.
-
moveable
- 한 층을 이동할 때 이동가능한 x축의 범위 입니다.
-
GenerateMapStructure
- 외부에서 MapManager를 통해 맵을 생성하고자 할때 호출됩니다.
- 만약 이미 생성된 Map이 존재한다면 동작하지 않지 않습니다.
-
ClearMap
- 외부에서 더 이상 필요없어진 Map의 정보를 지우기위해 호출됩니다.
- ClearMap으로 Map이 null이 되면 GenerateMapStructure 메서드를 통해 새로운 Map을 생성할 수 있습니다
-
CheckDubugMap
- 맵이 제대로 생성되는지 테스트하기위한 코드입니다.
- 맵 List를 StringBuilder를 통해 문자열로 만들어 Debug.Log로 출력합니다
-
Init
- 맵 생성시 가장 처음 호출되는 메서드 입니다.
- 생성할 맵의 층 수 정보를 받아서 Map 리스트배열을 생성한 후 0층에 대한 정보를 생성합니다
-
RouteCountThisFloor
- 이번층에 대한 정보를 바탕으로 다음층에 이동가능한 영역을 표시해서 int[]로 리턴합니다.
- 이동 가능한 지역은 moveable 배열을 순회하며 판단합니다.
- int[]에는 갈수 없는 지역은 0, 갈수있는 지역은 중첩에 따라 1, 2, 3으로 표시됩니다.
-
SelectRoute
- RouteCountThisFloor에서 리턴해준 이동가능 배열의 정보를 바탕으로 각 location에서 이동할 지역을 선택해줍니다.
- 이번층에서 활성화된 location들을 순회하여 각각의 location에서 연결할 다음층의 location을 생성합니다.
- 다음층의 location이 Map에 어디에 저장되어 있는지 인덱스를 이번층의 LocationInfo.RouteIndexs에 저장하여 아래층에서 위층으로 접근할 수 있도록 해줍니다.
- EventType을 결정해서 LocationInfo에 저장합니다.
-
CheckPos
- 2차원의 인덱스 범위를 벗어나지 않기 위한 메서드입니다.
- 인덱스 범위를 벗어나면 false를 리턴합니다.
-
AddSelectList
- SelectRoute에서 사용하는 메서드로 이동가능배열의 중첩도에 따라서 selectList를 채워줍니다.
- 우선도가 높을수록 selectList에 해당 인덱스가 여러번들어가서 선택될 확률이 높아집니다.
using System.Collections.Generic;
using System.Text;
using UnityEngine;
public class LocationInfo
{
public LocationInfo(int x, int y, EventType type)
{
Init(x, y, type);
}
public void Init(int x, int y, EventType type)
{
Index = x;
Floor = y;
RouteIndexs = new List<int>();
EventType = type;
}
public int Index { get; private set; }
public int Floor { get; private set; }
public List<int> RouteIndexs { get; private set; }
public RectTransform rectTransform { get; set; }
public EventType EventType { get; private set; }
public EventInfoSO EventInfoSO { get; private set; }
}
public class MapManager : Singleton<MapManager>
{
int maxXIndex = 10;
int maxYIndex;
int minX = 3;
int maxX = 5;
public List<LocationInfo>[] Map { get; private set; }
public int[] moveable = { -1, 0, 1 };
public void GenerateMapStructure(int floorNumber)
{
if (Map != null) return;
Init(floorNumber);
for( int i =1; i< maxYIndex; i++)
{
Map[i] = new List<LocationInfo>();
int[] Possibility = RouteCountThisFloor(Map[i-1]);
foreach (LocationInfo location in Map[i-1])
{
SelectRoute(location, Possibility);
// 다음지역 중 하나를 선택한다.
}
}
}
public void ClearMap()
{
Map = null;
}
private void CheckDebugMap()
{
StringBuilder sb = new StringBuilder();
foreach (List<LocationInfo> floor in Map)
{
int start = 0;
foreach (LocationInfo location in floor)
{
for (int i = start; i < location.Index; i++)
{
sb.Append(-1);
}
sb.Append(location.Index);
start = location.Index + 1;
}
for (int i = start; i < maxXIndex; i++)
{
sb.Append(-1);
}
sb.AppendLine();
}
Debug.Log(sb.ToString());
}
private void Init(int floorNumber)
{
maxYIndex = floorNumber;
Map = new List<LocationInfo>[maxYIndex];
Map[0] = new List<LocationInfo>();
int choice = UnityEngine.Random.Range(minX, maxX+1);
foreach(int index in Util.SelectNumber(0, maxXIndex, choice))
{
EventType type = (EventType)Random.Range(0, (int)EventType.EndPoint);
Map[0].Add(new LocationInfo(index, 0, type));
}
}
private int[] RouteCountThisFloor(List<LocationInfo> floor)
{
// 이전층의 List를 floor로 받아왔음 지금
int[] possibleRoute = new int[maxXIndex];
foreach(LocationInfo location in floor)
{
int index = location.Index;
foreach (int move in moveable)
{
int nextX = index + move;
if (CheckXPos(nextX))
{
possibleRoute[nextX]++;
}
}
}
return possibleRoute;
}
private void SelectRoute(LocationInfo location, int[] possibility)
{
int index = location.Index;
int floor = location.Floor;
List<int> selectList = new List<int>();
foreach (int move in moveable)
{
int nextX = index + move;
if (CheckXPos(nextX))
{
AddSelectList(selectList, possibility, nextX);
}
}
int nextIndex = Util.SelectItemFromList(selectList);
EventType type = (EventType)Random.Range(0, (int)EventType.EndPoint);
Map[floor+1].Add(new LocationInfo(nextIndex, floor + 1,type));
// 이때 시작점에도 추가해준다.
location.RouteIndexs.Add(Map[floor+1].Count-1);
}
private bool CheckXPos(int x)
{
if (x < 0 || x >= maxXIndex)
{
return false;
}
return true;
}
private void AddSelectList(List<int> selectList, int[] possiblity, int x )
{
switch (possiblity[x])
{
case 1:
for(int i =0; i< 3; i++)
{
selectList.Add(x);
}
break;
case 2:
selectList.Add(x);
break;
default:
break;
}
}
}