//Vector3 -> Mu Vector3 public static Vector3 Vector3ToVector3(Vector3 coords) { MuCoord c = Vector3ToCoords(coords); Vector3 v = CoordsToVector3(c); return(v); }
//MuCoord -> Vector3 public static Vector3 CoordsToVector3(MuCoord c) { Vector3 v = Vector3.zero; v.x = c.x*Config.TileSize+Config.TileSize/2; v.z = c.y*Config.TileSize+Config.TileSize/2; return v; }
public void CreateMoveTarget(Vector3 point, MuCoord coord) { if (!global.settings.ShowMoveTarget) { return; } Transform move = go.transform.Find("MoveTarget"); if (move != null) { Destroy(move.gameObject); } Vector3 terrainHeight = world.map.terrain.GetHeight(coord); terrainHeight.y += 3; if (Config.AccurateMoveTarget) { terrainHeight.x = point.x; terrainHeight.z = point.z; } GameObject target = Util.GO.CreateAdvancedObject("MoveTarget", go.transform, "Effect/MoveTargetPosEffect", "Effect/Animations/MoveTargetPosController", terrainHeight, Vector3.zero, Util.GO.Layer.Effects, 0.7f); target.AddComponent <MuEffects.MoveTarget>(); }
//Vector3 -> MuCoord public static MuCoord Vector3ToCoords(Vector3 v) { MuCoord coord = new MuCoord(); coord.x = (int)Mathf.Floor(v.x / Config.TileSize); coord.y = (int)Mathf.Floor(v.z / Config.TileSize); return(coord); }
//MuCoord -> Vector3 public static Vector3 CoordsToVector3(MuCoord c) { Vector3 v = Vector3.zero; v.x = c.x * Config.TileSize + Config.TileSize / 2; v.z = c.y * Config.TileSize + Config.TileSize / 2; return(v); }
//изменение координат игрока public void ChangeCoord(MuCoord coord) { if ((object)lastUpdatedPoint==null) { //если последний точки небыло, значит карта еще не создана lastUpdatedPoint = coord; RuntimeAround(coord); } else if (NeedUpdate(coord)) { RuntimeAround(coord); } }
public override bool Equals(System.Object obj) { if ((object)obj == null) { return(false); } MuCoord c = obj as MuCoord; return((x == c.x) && (y == c.y)); }
public byte[,] zones; //ссылка на зоны #endregion Fields #region Methods public void CreateCharacter(MuCoord coord) { GameObject player = Util.Player.CreatePlayersGameObject("Me", go.transform); Util.GO.SetTag ( player, Util.GO.Tag.Character ); me = player.AddComponent<Character>(); me.Init(); //обязательно инициализация me.State.map = global.map; //определяем зону для плавания me.SetClass(Util.Player.Class.DL); //указываем обязательно класс me.SetCoord(coord); }
//создает объекты вокруг точки private void RuntimeAround(MuCoord coord) { ArrayList added = new ArrayList(); ArrayList removed = new ArrayList(); Loom.RunAsync(() => { // НАЧАЛО НОВОГО ПОТОКА //создание for (int x = coord.x - bufferLength; x <= coord.x + bufferLength; ++x) { for (int y = coord.y - bufferLength; y <= coord.y + bufferLength; ++y) { if (x < 0 || y < 0 || x >= Config.MapLength || y >= Config.MapLength) { continue; } else { if (data[x, y] != null) { string xy = GetXY(x, y); if (!nums.Contains(xy)) { nums.Add(xy); } added.Add(xy); } } } } //удаление ArrayList list = (ArrayList)nums.Clone(); foreach (string n in list) { if (!added.Contains(n)) { //удаляем из списка видимых nums.Remove(n); removed.Add(n); } } list = null; // КОНЕЦ ГЛАВНОГО ПОТОКА Loom.QueueOnMainThread(() => { StartCoroutine(UpdateLOD(added, removed)); added = null; removed = null; }); }); }
public void CreateCharacter(MuCoord coord) { GameObject player = Util.Player.CreatePlayersGameObject("Me", go.transform); Util.GO.SetTag(player, Util.GO.Tag.Character); me = player.AddComponent <Character>(); me.Init(); //обязательно инициализация me.State.map = global.map; //определяем зону для плавания me.SetClass(Util.Player.Class.DL); //указываем обязательно класс me.SetCoord(coord); }
//изменение координат игрока public void ChangeCoord(MuCoord coord) { if ((object)lastUpdatedPoint == null) { //если последний точки небыло, значит карта еще не создана lastUpdatedPoint = coord; RuntimeAround(coord); } else if (NeedUpdate(coord)) { RuntimeAround(coord); } }
//возвращает угол по 2м координатам public static float GetDirectionFloat(MuCoord s, MuCoord e) { if (s.x == e.x && s.y == e.y) { return(Config.DefaultPlayerDirection); } float f = 0f; if (e.y > s.y) { if (e.x > s.x) { f = 45f; } else if (e.x < s.x) { f = 315f; } else { f = 0f; } } else if (e.y < s.y) { if (e.x > s.x) { f = 135f; } else if (e.x < s.x) { f = 225f; } else { f = 180f; } } else if (e.y == s.y) { if (e.x > s.x) { f = 90f; } else if (e.x < s.x) { f = 270f; } } return(f); }
IEnumerator SwitchActiveObject(string xy, bool isActive) { Transform find = go.transform.Find(xy); if (find != null) { find.gameObject.SetActive(isActive); } else if (isActive) { MuCoord coord = GetCoordXY(xy); yield return(StartCoroutine(CreateXY(coord))); } yield break; }
public void CreateMoveTarget( Vector3 point, MuCoord coord ) { if (!global.settings.ShowMoveTarget) return; Transform move = go.transform.Find ( "MoveTarget" ); if (move!=null) Destroy(move.gameObject); Vector3 terrainHeight = world.map.terrain.GetHeight(coord); terrainHeight.y += 3; if (Config.AccurateMoveTarget) { terrainHeight.x = point.x; terrainHeight.z = point.z; } GameObject target = Util.GO.CreateAdvancedObject ( "MoveTarget", go.transform, "Effect/MoveTargetPosEffect", "Effect/Animations/MoveTargetPosController", terrainHeight, Vector3.zero, Util.GO.Layer.Effects, 0.7f ); target.AddComponent<MuEffects.MoveTarget>(); }
void Parse(byte[] bytes) { //int count = (bytes.Length-3)/30; uint j = 0; for (int i = 3; i < bytes.Length; i += 30) { MapObject obj = new MapObject(); int id = BitConverter.ToUInt16(bytes, i) + 1; Vector3 position = new Vector3( BitConverter.ToSingle(bytes, i + 2), BitConverter.ToSingle(bytes, i + 10) + Config.TileHeight * Config.HoleHeight + Config.FixHeightObject, BitConverter.ToSingle(bytes, i + 6) ); Vector3 rotate = new Vector3( BitConverter.ToSingle(bytes, i + 14), 180f - BitConverter.ToSingle(bytes, i + 22), BitConverter.ToSingle(bytes, i + 18) ); float scale = BitConverter.ToSingle(bytes, i + 26); MuCoord coord = Util.Map.Vector3ToCoords(position); //если объект выходит за пределами карты пропускаем его if (coord.x < 0 || coord.x >= Config.MapLength || coord.y < 0 || coord.y >= Config.MapLength) { continue; } obj.id = id; obj.position = position; obj.rotate = rotate; obj.scale = scale; obj.isSpecial = isSpecial(obj.id); obj.num = j; j++; if (data[coord.x, coord.y] == null) { data[coord.x, coord.y] = new ArrayList(); } data[coord.x, coord.y].Add(obj); } }
//проверка на обновление и запись последней точки обновления private bool NeedUpdate(MuCoord coord) { bool status = false; int dist = (int)Mathf.Ceil(Util.Map.DistanceBetweenTwoPoints(lastUpdatedPoint, coord)); if (dist >= bufferLength - Config.MinRadiusViewTiles) { status = true; } if (status) //обновляем точку { lastUpdatedPoint = coord; } return(status); }
//клик по земле void EventContollerClickTerrain(Vector3 point) { Loom.RunAsync(() => { MuCoord coord = Util.Map.Vector3ToCoords(point); MuCoord[] coords = PathFinder.Get(Data.Coord, coord, world.players.zones); Loom.QueueOnMainThread(() => { if (coords.Length > 0) //если путь найден отправляем в главный поток //ставим конечную точку { world.effects.CreateMoveTarget(point, coord); //указываем игроку путь SetPath(coords); } }); }); }
//функция возвращает координаты вокруг точки public static MuCoord[] CoordsAround( MuCoord coord, int step = 0 ) { if (step==0) { MuCoord[] _coords = new MuCoord[1]; _coords[0] = coord; return _coords; } int length = step*2+1; int c = length*4-4; MuCoord[] coords = new MuCoord[c]; int x, y, i = 0; //top if (CorrectXY(coord.y-step)==coord.y-step) { for (x=CorrectXY(coord.x-step); x<CorrectXY(coord.x+step); x++) { coords[i] = new MuCoord(){ x = x, y = coord.y-step }; i++; } } //right if (CorrectXY(coord.x+step)==coord.x+step) { for (y=CorrectXY(coord.y-step); y<CorrectXY(coord.y+step); y++) { coords[i] = new MuCoord(){ x = coord.x+step, y = y }; i++; } } //bottom if (CorrectXY(coord.y+step)==coord.y+step) { for (x=CorrectXY(coord.x+step-1); x>=CorrectXY(coord.x-step); x--) { coords[i] = new MuCoord(){ x = x, y = coord.y+step }; i++; } } //left if (CorrectXY(coord.x-step)==coord.x-step) { for (y=CorrectXY(coord.y+step-1); y>=CorrectXY(coord.y-step); y--) { coords[i] = new MuCoord(){ x = coord.x-step, y = y }; i++; } } Array.Resize(ref coords, i); return coords; }
private IEnumerator CreateXY(MuCoord coord) { int x = coord.x; int y = coord.y; string x_y = GetXY(x, y); GameObject xy = new GameObject(x_y); xy.transform.parent = go.transform; foreach (MapObject obj in data[x, y]) { yield return(StartCoroutine(CreateWorldObject(xy, obj))); } if (xy.transform.childCount == 0) { //если объектов 0, то он нам не нужен Destroy(xy); } yield break; }
//проверяет диагональ по 2м координатам public static bool isDiagonal(MuCoord s, MuCoord e) { return (Mathf.Abs(e.x-s.x) == 1 && Mathf.Abs(e.y-s.y) == 1); }
//возвращает угол по 2м координатам public static float GetDirectionFloat(MuCoord s, MuCoord e) { if (s.x==e.x && s.y==e.y) return Config.DefaultPlayerDirection; float f = 0f; if (e.y>s.y) { if (e.x>s.x) f = 45f; else if (e.x<s.x) f = 315f; else f = 0f; } else if (e.y<s.y) { if (e.x>s.x) f = 135f; else if (e.x<s.x) f = 225f; else f = 180f; } else if (e.y==s.y) { if (e.x>s.x) f = 90f; else if (e.x<s.x) f = 270f; } return f; }
//устанавливает пользователя на карту public virtual void SetCoord(MuCoord coord) { Coord = coord; gameObject.transform.localPosition = Data.Position; }
//переопределения установки координат public override void SetCoord(MuCoord coord) { base.SetCoord(coord); CurrentCamera.Apply(); }
public static MuCoord[] Get(MuCoord start, MuCoord end, byte[,] zones) { return(FindPath(start.x, start.y, end.x, end.y, zones)); }
//возвращает высоту в точке public Vector3 GetHeight(MuCoord coord) { Vector3 v = Util.Map.CoordsToVector3(coord); return(GetHeight(v)); }
//возвращает высоту в точке public Vector3 GetHeight(MuCoord coord) { Vector3 v = Util.Map.CoordsToVector3(coord); return GetHeight(v); }
//растояние между двумя точками public static float DistanceBetweenTwoPoints(MuCoord coord1, MuCoord coord2) { return(Vector2.Distance(coord1.ToVector(), coord2.ToVector())); }
public static MuCoord[] Get(MuCoord start, MuCoord end, byte[,] zones) { return FindPath(start.x, start.y, end.x, end.y, zones); }
//функция возвращает координаты вокруг точки public static MuCoord[] CoordsAround(MuCoord coord, int step = 0) { if (step == 0) { MuCoord[] _coords = new MuCoord[1]; _coords[0] = coord; return(_coords); } int length = step * 2 + 1; int c = length * 4 - 4; MuCoord[] coords = new MuCoord[c]; int x, y, i = 0; //top if (CorrectXY(coord.y - step) == coord.y - step) { for (x = CorrectXY(coord.x - step); x < CorrectXY(coord.x + step); x++) { coords[i] = new MuCoord() { x = x, y = coord.y - step }; i++; } } //right if (CorrectXY(coord.x + step) == coord.x + step) { for (y = CorrectXY(coord.y - step); y < CorrectXY(coord.y + step); y++) { coords[i] = new MuCoord() { x = coord.x + step, y = y }; i++; } } //bottom if (CorrectXY(coord.y + step) == coord.y + step) { for (x = CorrectXY(coord.x + step - 1); x >= CorrectXY(coord.x - step); x--) { coords[i] = new MuCoord() { x = x, y = coord.y + step }; i++; } } //left if (CorrectXY(coord.x - step) == coord.x - step) { for (y = CorrectXY(coord.y + step - 1); y >= CorrectXY(coord.y - step); y--) { coords[i] = new MuCoord() { x = coord.x - step, y = y }; i++; } } Array.Resize(ref coords, i); return(coords); }
public void SetPath(MuCoord[] path) { //подпрограмма шагов if (path.Length>0) { CurrentPath = path; CurrentStateOfPath = -1; //если пользователь не движется то запускаем подпрограмму if (!State.isMove) StartCoroutine("StepByStep"); } }
//возвращает тестовые стартовые координаты public static MuCoord TestMyCoord(Util.Map.Location map) { MuCoord coord = new MuCoord(); switch (map) { case Util.Map.Location.Lorencia: coord = new MuCoord(){ x = 135, y = 128 }; break; case Util.Map.Location.Devias: coord = new MuCoord(){ x = 218, y = 34 }; break; case Util.Map.Location.Noria: coord = new MuCoord(){ x = 173, y = 110 }; break; case Util.Map.Location.Dungeun: coord = new MuCoord(){ x = 109, y = 247 }; break; case Util.Map.Location.Atlans: coord = new MuCoord(){ x = 21, y = 14 }; break; case Util.Map.Location.LostTower: coord = new MuCoord(){ x = 165, y = 168 }; break; case Util.Map.Location.Stadium: coord = new MuCoord(){ x = 60, y = 108 }; break; case Util.Map.Location.Tarcan: coord = new MuCoord(){ x = 130, y = 50 }; break; case Util.Map.Location.BloodCastle: coord = new MuCoord(){ x = 15, y = 15 }; break; case Util.Map.Location.DevilSquare: coord = new MuCoord(){ x = 70, y = 100 }; break; } return coord; }
//создает объекты вокруг точки private void RuntimeAround(MuCoord coord) { ArrayList added = new ArrayList(); ArrayList removed = new ArrayList(); Loom.RunAsync(()=>{ // НАЧАЛО НОВОГО ПОТОКА //создание for (int x = coord.x-bufferLength; x<=coord.x+bufferLength; ++x) { for (int y = coord.y-bufferLength; y<=coord.y+bufferLength; ++y) { if (x<0 || y<0 || x>=Config.MapLength || y>=Config.MapLength) continue; else { if (data[x,y]!=null) { string xy = GetXY(x, y); if (!nums.Contains(xy)) { nums.Add(xy); } added.Add(xy); } } } } //удаление ArrayList list = (ArrayList)nums.Clone(); foreach (string n in list) { if (!added.Contains(n)) { //удаляем из списка видимых nums.Remove(n); removed.Add(n); } } list = null; // КОНЕЦ ГЛАВНОГО ПОТОКА Loom.QueueOnMainThread(()=>{ StartCoroutine ( UpdateLOD(added, removed) ); added = null; removed = null; }); }); }
//Vector3 -> MuCoord public static MuCoord Vector3ToCoords(Vector3 v) { MuCoord coord = new MuCoord(); coord.x = (int)Mathf.Floor(v.x/Config.TileSize); coord.y = (int)Mathf.Floor(v.z/Config.TileSize); return coord; }
//возвращает тестовые стартовые координаты public static MuCoord TestMyCoord(Util.Map.Location map) { MuCoord coord = new MuCoord(); switch (map) { case Util.Map.Location.Lorencia: coord = new MuCoord() { x = 135, y = 128 }; break; case Util.Map.Location.Devias: coord = new MuCoord() { x = 218, y = 34 }; break; case Util.Map.Location.Noria: coord = new MuCoord() { x = 173, y = 110 }; break; case Util.Map.Location.Dungeun: coord = new MuCoord() { x = 109, y = 247 }; break; case Util.Map.Location.Atlans: coord = new MuCoord() { x = 21, y = 14 }; break; case Util.Map.Location.LostTower: coord = new MuCoord() { x = 165, y = 168 }; break; case Util.Map.Location.Stadium: coord = new MuCoord() { x = 60, y = 108 }; break; case Util.Map.Location.Tarcan: coord = new MuCoord() { x = 130, y = 50 }; break; case Util.Map.Location.BloodCastle: coord = new MuCoord() { x = 15, y = 15 }; break; case Util.Map.Location.DevilSquare: coord = new MuCoord() { x = 70, y = 100 }; break; } return(coord); }
//проверка на обновление и запись последней точки обновления private bool NeedUpdate(MuCoord coord) { bool status = false; int dist = (int)Mathf.Ceil(Util.Map.DistanceBetweenTwoPoints(lastUpdatedPoint, coord)); if (dist>=bufferLength-Config.MinRadiusViewTiles) status = true; if (status) //обновляем точку lastUpdatedPoint = coord; return status; }
protected IEnumerator StepByStep() { //если что-то не так, обр if (CurrentStateOfPath != -1 || CurrentPath == null || CurrentPath.Length == 0) { yield break; } else { CurrentStateOfPath = 0; } //длина пути int LengthPath = CurrentPath.Length; State.isMove = true; if (EventStartMove != null) { EventStartMove(Data); } //цикл пока путь не пройден while (CurrentStateOfPath < LengthPath) { MuCoord newcoord = CurrentPath[CurrentStateOfPath]; //устанавливает поворот SetDir(Util.Map.GetDirectionFloat(Coord, newcoord)); //устанавливает координату Coord = newcoord; float Speed = 300; while (Data.Position != transform.localPosition) { transform.localPosition = Vector3.MoveTowards(transform.localPosition, Data.Position, Time.deltaTime * Speed); yield return(null); } if (CurrentStateOfPath == -1) { CurrentStateOfPath = 0; } else { CurrentStateOfPath++; } //новая длина пути LengthPath = CurrentPath.Length; } State.isMove = false; SetDir(Data.Dir); //устанавливает поворот после остановки if (EventEndMove != null) { EventEndMove(Data); } yield break; }
static MuCoord[] FindPath(int startX, int startY, int targetX, int targetY, byte[,] zones) { int mapWidth = Config.MapLength, mapHeight = Config.MapLength; int onClosedList = 10; int found = 1, nonexistent = 2; int walkable = 0, unwalkable = 1; int[] openList = new int[mapWidth * mapHeight + 2]; //1 dimensional array holding ID# of open list items int[,] whichList = new int[mapWidth + 1, mapHeight + 1]; //2 dimensional array used to record int[] openX = new int[mapWidth * mapHeight + 2]; //1d array stores the x location of an item on the open list int[] openY = new int[mapWidth * mapHeight + 2]; //1d array stores the y location of an item on the open list int[,] parentX = new int[mapWidth + 1, mapHeight + 1]; //2d array to store parent of each cell (x) int[,] parentY = new int[mapWidth + 1, mapHeight + 1]; //2d array to store parent of each cell (y) int[] Fcost = new int[mapWidth * mapHeight + 2]; //1d array to store F cost of a cell on the open list int[,] Gcost = new int[mapWidth + 1, mapHeight + 1]; //2d array to store G cost for each cell. int[] Hcost = new int[mapWidth * mapHeight + 2]; //1d array to store H cost of a cell on the open list int onOpenList = 0, parentXval = 0, parentYval = 0, a = 0, b = 0, m = 0, u = 0, v = 0, temp = 0, corner = 0, numberOfOpenListItems = 0, addedGCost = 0, tempGcost = 0, path = 0, x = 0, y = 0, pathX, pathY, newOpenListItemID = 0; //если позиция та на которой стоишь if (startX == targetX && startY == targetY) { return(new MuCoord[0]); } //если туда нельзя пройти if (!isWay(zones[targetX, targetY])) { Debug.Log("zone: " + zones[targetX, targetY]); return(new MuCoord[0]); } for (x = 0; x < mapWidth; x++) { for (y = 0; y < mapHeight; y++) { whichList [x, y] = 0; } } onClosedList = 2; onOpenList = 1; Gcost[startX, startY] = 0; numberOfOpenListItems = 1; openList[1] = 1; openX[1] = startX; openY[1] = startY; do { if (numberOfOpenListItems != 0) { parentXval = openX[openList[1]]; parentYval = openY[openList[1]]; whichList[parentXval, parentYval] = onClosedList; numberOfOpenListItems = numberOfOpenListItems - 1; openList[1] = openList[numberOfOpenListItems + 1]; v = 1; do { u = v; if (2 * u + 1 <= numberOfOpenListItems) { if (Fcost[openList[u]] >= Fcost[openList[2 * u]]) { v = 2 * u; } if (Fcost[openList[v]] >= Fcost[openList[2 * u + 1]]) { v = 2 * u + 1; } } else { if (2 * u <= numberOfOpenListItems) { if (Fcost[openList[u]] >= Fcost[openList[2 * u]]) { v = 2 * u; } } } if (u != v) { temp = openList[u]; openList[u] = openList[v]; openList[v] = temp; } else { break; } } while (true); for (b = parentYval - 1; b <= parentYval + 1; b++) { for (a = parentXval - 1; a <= parentXval + 1; a++) { if (a != -1 && b != -1 && a != mapWidth && b != mapHeight) { if (whichList[a, b] != onClosedList) { if (isWay(zones[a, b])) { corner = walkable; if (a == parentXval - 1) { if (b == parentYval - 1) { if (!isWay(zones[parentXval - 1, parentYval]) || !isWay(zones[parentXval, parentYval - 1])) { corner = unwalkable; } } else if (b == parentYval + 1) { if (!isWay(zones[parentXval, parentYval + 1]) || !isWay(zones[parentXval - 1, parentYval])) { corner = unwalkable; } } } else if (a == parentXval + 1) { if (b == parentYval - 1) { if (!isWay(zones[parentXval, parentYval - 1]) || !isWay(zones[parentXval + 1, parentYval])) { corner = unwalkable; } } else if (b == parentYval + 1) { if (!isWay(zones[parentXval + 1, parentYval]) || !isWay(zones[parentXval, parentYval + 1])) { corner = unwalkable; } } } if (corner == walkable) { if (whichList[a, b] != onOpenList) { newOpenListItemID = newOpenListItemID + 1; m = numberOfOpenListItems + 1; openList[m] = newOpenListItemID; openX[newOpenListItemID] = a; openY[newOpenListItemID] = b; if (Math.Abs(a - parentXval) == 1 && Math.Abs(b - parentYval) == 1) { addedGCost = 18; } else { addedGCost = 10; } Gcost[a, b] = Gcost[parentXval, parentYval] + addedGCost; Hcost[openList[m]] = 10 * (Math.Abs(a - targetX) + Math.Abs(b - targetY)); Fcost[openList[m]] = Gcost[a, b] + Hcost[openList[m]]; parentX[a, b] = parentXval; parentY[a, b] = parentYval; while (m != 1) { if (Fcost[openList[m]] <= Fcost[openList[m / 2]]) { temp = openList[m / 2]; openList[m / 2] = openList[m]; openList[m] = temp; m = m / 2; } else { break; } } numberOfOpenListItems = numberOfOpenListItems + 1; whichList[a, b] = onOpenList; } else { if (Math.Abs(a - parentXval) == 1 && Math.Abs(b - parentYval) == 1) { addedGCost = 18; } else { addedGCost = 10; } tempGcost = Gcost[parentXval, parentYval] + addedGCost; if (tempGcost < Gcost[a, b]) { parentX[a, b] = parentXval; parentY[a, b] = parentYval; Gcost[a, b] = tempGcost; for (x = 1; x <= numberOfOpenListItems; x++) { if (openX[openList[x]] == a && openY[openList[x]] == b) { Fcost[openList[x]] = Gcost[a, b] + Hcost[openList[x]]; m = x; while (m != 1) { if (Fcost[openList[m]] < Fcost[openList[m / 2]]) { temp = openList[m / 2]; openList[m / 2] = openList[m]; openList[m] = temp; m = m / 2; } else { break; } } break; } } } } } } } } } } } else { path = nonexistent; break; } if (whichList[targetX, targetY] == onOpenList) { path = found; break; } } while (true); MuCoord[] coords = new MuCoord[mapWidth * mapHeight]; int j = 0; int tempx = 0; if (path == found) { pathX = targetX; pathY = targetY; coords[j] = new MuCoord() { x = pathX, y = pathY }; j++; do { tempx = parentX[pathX, pathY]; pathY = parentY[pathX, pathY]; pathX = tempx; if (pathX != startX || pathY != startY) { coords[j] = new MuCoord() { x = pathX, y = pathY }; j++; } } while (pathX != startX || pathY != startY); } Array.Resize(ref coords, j); Array.Reverse(coords); return(coords); }
//устанавливает пользователя на карту virtual public void SetCoord(MuCoord coord) { Coord = coord; gameObject.transform.localPosition = Data.Position; }
private IEnumerator CreateXY( MuCoord coord ) { int x = coord.x; int y = coord.y; string x_y = GetXY(x, y); GameObject xy = new GameObject(x_y); xy.transform.parent = go.transform; foreach (MapObject obj in data[x,y]) { yield return StartCoroutine ( CreateWorldObject(xy, obj) ); } if (xy.transform.childCount==0) //если объектов 0, то он нам не нужен Destroy(xy); yield break; }
//растояние между двумя точками public static float DistanceBetweenTwoPoints(MuCoord coord1, MuCoord coord2) { return Vector2.Distance(coord1.ToVector(), coord2.ToVector()); }
//проверяет диагональ по 2м координатам public static bool isDiagonal(MuCoord s, MuCoord e) { return(Mathf.Abs(e.x - s.x) == 1 && Mathf.Abs(e.y - s.y) == 1); }
static MuCoord[] FindPath(int startX, int startY, int targetX, int targetY, byte[,] zones) { int mapWidth = Config.MapLength, mapHeight = Config.MapLength; int onClosedList = 10; int found = 1, nonexistent = 2; int walkable = 0, unwalkable = 1; int[] openList = new int[mapWidth*mapHeight+2]; //1 dimensional array holding ID# of open list items int[,] whichList = new int[mapWidth+1,mapHeight+1]; //2 dimensional array used to record int[] openX = new int[mapWidth*mapHeight+2]; //1d array stores the x location of an item on the open list int[] openY = new int[mapWidth*mapHeight+2]; //1d array stores the y location of an item on the open list int[,] parentX = new int[mapWidth+1,mapHeight+1]; //2d array to store parent of each cell (x) int[,] parentY = new int[mapWidth+1,mapHeight+1]; //2d array to store parent of each cell (y) int[] Fcost = new int[mapWidth*mapHeight+2]; //1d array to store F cost of a cell on the open list int[,] Gcost = new int[mapWidth+1,mapHeight+1]; //2d array to store G cost for each cell. int[] Hcost = new int[mapWidth*mapHeight+2]; //1d array to store H cost of a cell on the open list int onOpenList=0, parentXval=0, parentYval=0, a=0, b=0, m=0, u=0, v=0, temp=0, corner=0, numberOfOpenListItems=0, addedGCost=0, tempGcost = 0, path = 0, x=0, y=0, pathX, pathY, newOpenListItemID=0; //если позиция та на которой стоишь if (startX == targetX && startY == targetY) return new MuCoord[0]; //если туда нельзя пройти if (!isWay (zones[targetX,targetY])) { Debug.Log("zone: "+zones[targetX,targetY]); return new MuCoord[0]; } for (x = 0; x < mapWidth; x++) { for (y = 0; y < mapHeight;y++) whichList [x,y] = 0; } onClosedList = 2; onOpenList = 1; Gcost[startX,startY] = 0; numberOfOpenListItems = 1; openList[1] = 1; openX[1] = startX ; openY[1] = startY; do { if (numberOfOpenListItems != 0) { parentXval = openX[openList[1]]; parentYval = openY[openList[1]]; whichList[parentXval,parentYval] = onClosedList; numberOfOpenListItems = numberOfOpenListItems - 1; openList[1] = openList[numberOfOpenListItems+1]; v = 1; do { u = v; if (2*u+1 <= numberOfOpenListItems) { if (Fcost[openList[u]] >= Fcost[openList[2*u]]) v = 2*u; if (Fcost[openList[v]] >= Fcost[openList[2*u+1]]) v = 2*u+1; } else { if (2*u <= numberOfOpenListItems) { if (Fcost[openList[u]] >= Fcost[openList[2*u]]) v = 2*u; } } if (u != v) { temp = openList[u]; openList[u] = openList[v]; openList[v] = temp; } else break; } while (true); for (b = parentYval-1; b <= parentYval+1; b++) { for (a = parentXval-1; a <= parentXval+1; a++) { if (a != -1 && b != -1 && a != mapWidth && b != mapHeight) { if (whichList[a,b] != onClosedList) { if (isWay(zones[a,b])) { corner = walkable; if (a == parentXval-1) { if (b == parentYval-1) { if (!isWay(zones[parentXval-1,parentYval]) || !isWay(zones[parentXval,parentYval-1])) corner = unwalkable; } else if (b == parentYval+1) { if (!isWay(zones[parentXval,parentYval+1]) || !isWay(zones[parentXval-1,parentYval])) corner = unwalkable; } } else if (a == parentXval+1) { if (b == parentYval-1) { if (!isWay(zones[parentXval,parentYval-1]) || !isWay(zones[parentXval+1,parentYval])) corner = unwalkable; } else if (b == parentYval+1) { if (!isWay(zones[parentXval+1,parentYval]) || !isWay(zones[parentXval,parentYval+1])) corner = unwalkable; } } if (corner == walkable) { if (whichList[a,b] != onOpenList) { newOpenListItemID = newOpenListItemID + 1; m = numberOfOpenListItems+1; openList[m] = newOpenListItemID; openX[newOpenListItemID] = a; openY[newOpenListItemID] = b; if (Math.Abs(a-parentXval) == 1 && Math.Abs(b-parentYval) == 1) addedGCost = 18; else addedGCost = 10; Gcost[a,b] = Gcost[parentXval,parentYval] + addedGCost; Hcost[openList[m]] = 10*(Math.Abs(a - targetX) + Math.Abs(b - targetY)); Fcost[openList[m]] = Gcost[a,b] + Hcost[openList[m]]; parentX[a,b] = parentXval ; parentY[a,b] = parentYval; while (m != 1) { if (Fcost[openList[m]] <= Fcost[openList[m/2]]) { temp = openList[m/2]; openList[m/2] = openList[m]; openList[m] = temp; m = m/2; } else break; } numberOfOpenListItems = numberOfOpenListItems+1; whichList[a,b] = onOpenList; } else { if (Math.Abs(a-parentXval) == 1 && Math.Abs(b-parentYval) == 1) addedGCost = 18; else addedGCost = 10; tempGcost = Gcost[parentXval,parentYval] + addedGCost; if (tempGcost < Gcost[a,b]) { parentX[a,b] = parentXval; parentY[a,b] = parentYval; Gcost[a,b] = tempGcost; for (x = 1; x <= numberOfOpenListItems; x++) { if (openX[openList[x]] == a && openY[openList[x]] == b) { Fcost[openList[x]] = Gcost[a,b] + Hcost[openList[x]]; m = x; while (m != 1) { if (Fcost[openList[m]] < Fcost[openList[m/2]]) { temp = openList[m/2]; openList[m/2] = openList[m]; openList[m] = temp; m = m/2; } else break; } break; } } } } } } } } } } } else { path = nonexistent; break; } if (whichList[targetX,targetY] == onOpenList) { path = found; break; } } while (true); MuCoord[] coords = new MuCoord[mapWidth*mapHeight]; int j = 0; int tempx = 0; if (path == found) { pathX = targetX; pathY = targetY; coords[j] = new MuCoord(){ x = pathX, y = pathY }; j++; do { tempx = parentX[pathX,pathY]; pathY = parentY[pathX,pathY]; pathX = tempx; if (pathX != startX || pathY != startY) { coords[j] = new MuCoord(){ x = pathX, y = pathY }; j++; } } while (pathX != startX || pathY != startY); } Array.Resize(ref coords, j); Array.Reverse(coords); return coords; }