private void _BuildQueueWork(RayMap rayMap) { if (rayMap.startPoint == rayMap.endPoint) { return; } _PushOut(MovementStatus.Start); Queue <MyV2IPair> supplyQueue = new Queue <MyV2IPair>(); List <Vector2Int> avoidList = new List <Vector2Int>(); Stack <MovementStatus> tMovementStack = new Stack <MovementStatus>(); StorageTree storageTree = new StorageTree(); for (int i = 0; i < rayMap.size.x; i++) { for (int j = 0; j < rayMap.size.y; j++) { if (rayMap.buffer[i, j]) { avoidList.Add(new Vector2Int(i, j)); } } } avoidList.Remove(rayMap.startPoint);//you don't want to bury yourself supplyQueue.Enqueue(new MyV2IPair(rayMap.startPoint, new Vector2Int(-233, -666))); // (-233,-666) is a hooked start point XD if (_Search(ref rayMap, ref supplyQueue, ref avoidList, ref tMovementStack, ref storageTree)) { //moveArrowSpriteRenderer.color = Color.green; while (tMovementStack.Count > 0) { _PushOut(tMovementStack.Pop()); } } else { } _PushOut(MovementStatus.Completed); }
private IEnumerator _CoroutineWork(RayMap rayMap, Vector2Int sizeInt, Vector2Int centerPosInt) //generate raymap, no-frameBlock operation { System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); long counterTime = stopwatch.ElapsedMilliseconds; for (int i = 0; i < sizeInt.x; i++) { for (int j = 0; j < sizeInt.y; j++) { rayMap.buffer[i, j] = _ReturnRayResult(new Vector2(((i - centerPosInt.x) * tileSize.x) + centerPos.x, ((j - centerPosInt.y) * tileSize.y) + centerPos.y)); if (allowVisualStatus) { _TvisualizeObject(new Vector2(((i - centerPosInt.x) * tileSize.x) + centerPos.x, ((j - centerPosInt.y) * tileSize.y) + centerPos.y), rayMap.buffer[i, j], TempFather, (rayMap.endPoint.x == i && rayMap.endPoint.y == j), (rayMap.startPoint.x == i && rayMap.startPoint.y == j)); } } if (stopwatch.ElapsedMilliseconds - counterTime >= 1000 * Time.fixedDeltaTime) { counterTime = stopwatch.ElapsedMilliseconds; yield return(0); } } stopwatch.Stop(); if (rayMap.endPoint.x < rayMap.size.x && rayMap.endPoint.x >= 0 && rayMap.endPoint.y < rayMap.size.y && rayMap.endPoint.x >= 0 && !rayMap.buffer[rayMap.endPoint.x, rayMap.endPoint.y]) { _BuildQueueWork(rayMap); } else { // Unable to move //moveArrowSpriteRenderer.color = Color.red; } yield return(0); }
private bool _Search(ref RayMap inRayMap, ref Queue <MyV2IPair> supplyQueue, ref List <Vector2Int> avoidList, ref Stack <MovementStatus> revMovementStack, ref StorageTree storageTree) { //Queue<MyV2IPair> myV2IPairQueue_Saved = new Queue<MyV2IPair>(); while (supplyQueue.Count > 0) { MyV2IPair myV2IPair = supplyQueue.Dequeue(); Vector2Int currentPos = myV2IPair.current; if (avoidList.Contains(currentPos)) { continue; } else if (currentPos.x < 0 || currentPos.x > inRayMap.size.x || currentPos.y < 0 || currentPos.y > inRayMap.size.y) { continue; } else if (currentPos == inRayMap.endPoint) // founded { int tempIndexn = storageTree.Add(myV2IPair); StorageTreeNode iterator = storageTree.data[tempIndexn];// this point is not registered in the tree yet try { while (iterator.father != null) { if (iterator.data.x == iterator.father.data.x) { if (iterator.data.y == iterator.father.data.y + 1) { revMovementStack.Push(MovementStatus.MovingUp); } else if (iterator.data.y == iterator.father.data.y - 1) { revMovementStack.Push(MovementStatus.MovingDown); } else { //error } } else if (iterator.data.y == iterator.father.data.y) { if (iterator.data.x == iterator.father.data.x + 1) { revMovementStack.Push(MovementStatus.MovingRight); } else if (iterator.data.x == iterator.father.data.x - 1) { revMovementStack.Push(MovementStatus.MovingLeft); } else { //error } } else { //error } iterator = iterator.father; } return(true); } catch (System.Exception e) { EditorControl.EditorPause(); Debug.Log(e); return(false); } } else //normal Node { avoidList.Add(currentPos); storageTree.Add(myV2IPair); //myV2IPairQueue_Saved.Enqueue(myV2IPair); //enqueue switch (_IdentifyDirection(myV2IPair.current, myV2IPair.previous)) //trend to walk a straight line { case MovementStatus.MovingUp: if (currentPos.y < inRayMap.size.y - 1 && !avoidList.Contains(currentPos + new Vector2Int(0, 1))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(0, 1), currentPos)); } if (currentPos.x < inRayMap.size.x - 1 && !avoidList.Contains(currentPos + new Vector2Int(1, 0))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(1, 0), currentPos)); } if (currentPos.x > 0 && !avoidList.Contains(currentPos + new Vector2Int(-1, 0))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(-1, 0), currentPos)); } if (currentPos.y > 0 && !avoidList.Contains(currentPos + new Vector2Int(0, -1))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(0, -1), currentPos)); } break; case MovementStatus.MovingRight: if (currentPos.x < inRayMap.size.x - 1 && !avoidList.Contains(currentPos + new Vector2Int(1, 0))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(1, 0), currentPos)); } if (currentPos.y < inRayMap.size.y - 1 && !avoidList.Contains(currentPos + new Vector2Int(0, 1))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(0, 1), currentPos)); } if (currentPos.y > 0 && !avoidList.Contains(currentPos + new Vector2Int(0, -1))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(0, -1), currentPos)); } if (currentPos.x > 0 && !avoidList.Contains(currentPos + new Vector2Int(-1, 0))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(-1, 0), currentPos)); } break; case MovementStatus.MovingDown: if (currentPos.y > 0 && !avoidList.Contains(currentPos + new Vector2Int(0, -1))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(0, -1), currentPos)); } if (currentPos.x < inRayMap.size.x - 1 && !avoidList.Contains(currentPos + new Vector2Int(1, 0))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(1, 0), currentPos)); } if (currentPos.x > 0 && !avoidList.Contains(currentPos + new Vector2Int(-1, 0))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(-1, 0), currentPos)); } if (currentPos.y < inRayMap.size.y - 1 && !avoidList.Contains(currentPos + new Vector2Int(0, 1))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(0, 1), currentPos)); } break; case MovementStatus.MovingLeft: if (currentPos.x > 0 && !avoidList.Contains(currentPos + new Vector2Int(-1, 0))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(-1, 0), currentPos)); } if (currentPos.y < inRayMap.size.y - 1 && !avoidList.Contains(currentPos + new Vector2Int(0, 1))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(0, 1), currentPos)); } if (currentPos.y > 0 && !avoidList.Contains(currentPos + new Vector2Int(0, -1))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(0, -1), currentPos)); } if (currentPos.x < inRayMap.size.x - 1 && !avoidList.Contains(currentPos + new Vector2Int(1, 0))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(1, 0), currentPos)); } break; default: if (currentPos.y < inRayMap.size.y - 1 && !avoidList.Contains(currentPos + new Vector2Int(0, 1))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(0, 1), currentPos)); } if (currentPos.x < inRayMap.size.x - 1 && !avoidList.Contains(currentPos + new Vector2Int(1, 0))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(1, 0), currentPos)); } if (currentPos.y > 0 && !avoidList.Contains(currentPos + new Vector2Int(0, -1))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(0, -1), currentPos)); } if (currentPos.x > 0 && !avoidList.Contains(currentPos + new Vector2Int(-1, 0))) { supplyQueue.Enqueue(new MyV2IPair(currentPos + new Vector2Int(-1, 0), currentPos)); } break; } } } return(false); }
private void _GenerateRayMap(Vector2 outArrowPosition) { if (!_movementEndObject) { _movementEndObject = Instantiate(movementEndObject_Prefab); } _movementEndObject.transform.position = outArrowPosition; _movementEndObject.name = "movementEndObject"; if (coroutineWorkhandle_RayMap != null) { StopCoroutine(coroutineWorkhandle_RayMap); } centerPos = cT.position; Vector2Int sizeInt = new Vector2Int((int)(pictureSize.x / tileSize.x), (int)(pictureSize.y / tileSize.y)); rayMap = new RayMap(sizeInt); Vector2Int centerPosInt = new Vector2Int(sizeInt.x / 2, sizeInt.y / 2); rayMap.startPoint = centerPosInt; #region Vector2_to_Vector2Int if (outArrowPosition.x > (centerPos.x - tileSize.x / 2)) { int t_x = 0; for (; outArrowPosition.x > (centerPos.x + tileSize.x / 2); outArrowPosition -= new Vector2(tileSize.x, 0)) { t_x++; } rayMap.endPoint = new Vector2Int(t_x + centerPosInt.x, 0); } else { int t_x = 0; for (; outArrowPosition.x < (centerPos.x - tileSize.x / 2); outArrowPosition += new Vector2(tileSize.x, 0)) { t_x--; } rayMap.endPoint = new Vector2Int(t_x + centerPosInt.x, 0); } if (outArrowPosition.y > (centerPos.y - tileSize.y / 2)) { int t_y = 0; for (; outArrowPosition.y > (centerPos.y + tileSize.y / 2); outArrowPosition -= new Vector2(0, tileSize.y)) { t_y++; } rayMap.endPoint += new Vector2Int(0, t_y + centerPosInt.y); } else { int t_y = 0; for (; outArrowPosition.y < (centerPos.y - tileSize.y / 2); outArrowPosition += new Vector2(0, tileSize.y)) { t_y--; } rayMap.endPoint += new Vector2Int(0, t_y + centerPosInt.y); } //Debug.Log("centerPoint: " + rayMap.startPoint.x + " " + rayMap.startPoint.y); //Debug.Log("endPoint: " + rayMap.endPoint.x + " " + rayMap.endPoint.y); #endregion if (TempFather) { Destroy(TempFather); } TempFather = new GameObject("Father_TempObjects"); TempFather.transform.position = new Vector3(0, 0, 0); coroutineWorkhandle_RayMap = _CoroutineWork(rayMap, sizeInt, centerPosInt); StartCoroutine(coroutineWorkhandle_RayMap); }