/// <summary> /// Add a new node to the build-end of of the branch. /// New nodes automatically become the new InNode unless the NODE_DIRECTION /// passed is a multi-direction. In this case the branch is "closed" and no /// more nodes can be added. /// </summary> /// <param name="direction"></param> public NODE_DIRECTION[] Add(NODE_DIRECTION direction) { if (Open) { if (direction.IsMulti()) { // close the branch Open = false; InNode.InDirection = direction; return(direction.GetDirections().ToArray()); } else { Vector2Int newLocation = InNode.Next(direction); Node nextNode = new Node(newLocation.x, newLocation.y, this); InNode.InNode = nextNode; nextNode.OutNode = InNode; InNode = nextNode; _nodeDirectory.Add(nextNode.VectorLocation, nextNode); if (Parent != null) { Parent.SetNodeDirectoryData(nextNode); } return(new NODE_DIRECTION[] { direction }); } } else { throw new BranchException(BRANCH_EXCEPTION_TYPE.BRANCH_NOT_OPEN); } }
/// <summary> /// Get the location of a neighboring node by direction. /// </summary> /// <param name="direction"></param> /// <returns></returns> public Vector2Int Next(NODE_DIRECTION direction) { Vector2Int location = VectorLocation; switch (direction) { case NODE_DIRECTION.UP: location.y++; break; case NODE_DIRECTION.DOWN: location.y--; break; case NODE_DIRECTION.LEFT: location.x--; break; case NODE_DIRECTION.RIGHT: location.x++; break; default: throw new DirectionException(DIRECTION_EXCEPTION_TYPE.MULTI_RESTRICTED); } return(location); }
public void Test_Node_NextException_NONE() { Node A = new Node(2, 2); NODE_DIRECTION dir = NODE_DIRECTION.NONE; Assert.Throws(typeof(DirectionException), () => A.Next(dir)); }
public void Test_Path_GetNodesAt_NoNodeExists() { NODE_DIRECTION initDir = NODE_DIRECTION.UP; Path path = new Path(origin, initDir); Assert.That(path.GetNodesAt(0, 0).Length, Is.EqualTo(0)); }
public void Test_Node_NextException_MULTI() { Node A = new Node(2, 2); NODE_DIRECTION dir = NODE_DIRECTION.UP_DOWN_LEFT_RIGHT; Assert.Throws(typeof(DirectionException), () => A.Next(dir)); }
// Use this for initialization public void Start() { // Build the path out to the Init Widths in the init directions. _path = new Path(new Node(Origin.x, Origin.y), InitDirection); // Create the initial bounding rect Vector2Int offset = new Vector2Int(InitXWidth, InitYWidth); Rect bound = new Rect(Origin - offset, offset + offset + Vector2Int.one); bool building = true; while (building) { building = false; foreach (int i in _path.OuterBranchIDs) { Branch b = _path.Branches[i]; if (bound.Contains(b.InNode.VectorLocation)) { // if the branch in-node is in the bounding rect, set the building flag to true and add another node. // This logic will cause the termination of the outer while loop when all outer branches have in-nodes // outside of the bounding rect. building = true; NODE_DIRECTION dir = b.InNode.OutNode.DirectionOf(b.InNode); b.Add(dir); } } } }
public void Test_Path_Init_GetNodesAt() { NODE_DIRECTION initDir = NODE_DIRECTION.UP_LEFT_RIGHT; Path path = new Path(origin, initDir); foreach (int id in path.OuterBranchIDs) { Branch outerBranch = path.Branches[id]; switch (origin.DirectionOf(outerBranch.InNode)) { case NODE_DIRECTION.LEFT: outerBranch.Add(NODE_DIRECTION.UP); outerBranch.Add(NODE_DIRECTION.RIGHT); break; case NODE_DIRECTION.RIGHT: outerBranch.Add(NODE_DIRECTION.UP); outerBranch.Add(NODE_DIRECTION.LEFT); break; default: break; } } Assert.That(path.GetNodesAt(2, 3).Length, Is.EqualTo(initDir.GetDirections().ToArray().Length)); }
public void Test_Node_Next_DOWN() { Node A = new Node(2, 2); NODE_DIRECTION dir = NODE_DIRECTION.DOWN; Vector2Int ex = new Vector2Int(2, 1); Assert.AreEqual(ex, A.Next(dir)); }
public void Test_Node_Next_RIGHT() { Node A = new Node(2, 2); NODE_DIRECTION dir = NODE_DIRECTION.RIGHT; Vector2Int ex = new Vector2Int(3, 2); Assert.AreEqual(ex, A.Next(dir)); }
public void Test_Branch_Constructor_NodeDirectory_InitialNode() { Node o = new Node(2, 2); NODE_DIRECTION branchDir = NODE_DIRECTION.RIGHT; Branch_Test b = new Branch_Test(1, o, branchDir); Assert.That(b._nodeDirectory, Contains.Key(o.Next(branchDir))); }
public void Test_Path_OriginNodeShouldBeUDLR() { Path path = new Path(origin, NODE_DIRECTION.UP_DOWN_LEFT_RIGHT); NODE_DIRECTION originDirection = path.GetNodesAt(2, 2).First().InDirection; Assert.That(originDirection, Is.EqualTo(NODE_DIRECTION.UP_DOWN_LEFT_RIGHT)); }
public void Test_VerifyFlagEnumFunc() { NODE_DIRECTION testDir = NODE_DIRECTION.UP; testDir |= NODE_DIRECTION.LEFT; Assert.That(testDir, Is.EqualTo(NODE_DIRECTION.UP_LEFT)); }
public void Test_Path_Branch_OpenException() { NODE_DIRECTION initDir = NODE_DIRECTION.UP, branchDir = NODE_DIRECTION.UP_LEFT_RIGHT; Path path = new Path(origin, initDir); int initBranchId = path.OuterBranchIDs[0]; Assert.Throws <PathException>(() => path.Branch(initBranchId)); }
/// <summary> /// Test a direction to see if it is a multi-direction or not. /// </summary> /// <param name="d"></param> /// <returns></returns> public static bool IsMulti(this NODE_DIRECTION d) { return(!( d == NODE_DIRECTION.NONE || d == NODE_DIRECTION.UP || d == NODE_DIRECTION.DOWN || d == NODE_DIRECTION.LEFT || d == NODE_DIRECTION.RIGHT)); }
public override void Jump(NODE_DIRECTION _dir) { Node previousNode = currentNode; currentNode = currentNode.GetLink(_dir); StartCoroutine(previousNode.GetComponent <Node>().Scatter(OppositeDirection(_dir))); lastDirection = _dir; DecrementRemainingStones(); }
public void Test_Path_Init_GetNodeAt() { NODE_DIRECTION initDir = NODE_DIRECTION.UP; Path path = new Path(origin, initDir); Branch outerBranch = path.Branches[path.OuterBranchIDs[0]]; Vector2Int upLoc = origin.Next(initDir); Assert.That(path.GetNodeAt(upLoc.x, upLoc.y, path.OuterBranchIDs[0]).VectorLocation, Is.EqualTo(upLoc)); }
/// <summary> /// Bug flees when player leaves the bug /// </summary> /// <param name="_dir"></param> /// <returns></returns> public IEnumerator Scatter(NODE_DIRECTION _dir) { float acceleration = Random.Range(-scatterAcceleration, scatterAcceleration); Vector3 direction = Vector3.zero; switch (_dir) { case NODE_DIRECTION.UP: direction.y += scatterSpeed; break; case NODE_DIRECTION.DOWN: direction.y -= scatterSpeed; break; case NODE_DIRECTION.LEFT: direction.x -= scatterSpeed; break; case NODE_DIRECTION.RIGHT: direction.x += scatterSpeed; break; case NODE_DIRECTION.MAX_DIRECTION: break; default: break; } scattering = true; animator.SetBool("Flying", true); while (scattering && Mathf.Abs(transform.position.y) < Camera.main.orthographicSize && Mathf.Abs(transform.position.x) < Camera.main.orthographicSize * (10.0f / 16.0f)) { transform.up = direction; transform.position += direction; if (RandomBool()) { direction.x += acceleration * Time.deltaTime; } if (RandomBool()) { direction.y += acceleration * Time.deltaTime; } yield return(null); } //transform.position = startPos; if (scattering) { gameObject.SetActive(false); } animator.SetBool("Flying", false); renderer.sprite = sprites[spriteIndex]; }
/// <summary> /// Compile entrances and exits for all nodes in this list. /// </summary> /// <param name="nodeList"></param> /// <returns></returns> public static NODE_DIRECTION GetPathEntrancesAndExits(this Node[] nodeList) { NODE_DIRECTION entrancesAndExits = NODE_DIRECTION.NONE; foreach (Node node in nodeList) { entrancesAndExits |= node.GetPathEntrancesAndExits(); } return(entrancesAndExits); }
/// <summary> /// Activate this minion. /// All this does is begin moving down the path and animating the walk cycle. /// It's intended to be called right after instantiation, and is basically here to /// give us time to initialize the minion. /// Also does some light lifting, like moving the minion automatically to the passed node location. /// </summary> /// <param name="location"></param> public void Activate(Node location) { Location = location; float minionRot = GetDirectionRotation(location.OutDirection); transform.SetPositionAndRotation(location.VectorLocation.ToVector3(), Quaternion.Euler(0, 0, 0)); modelTransform = transform.GetChild(0); modelTransform.localRotation = Quaternion.Euler(0, minionRot, 0); facing = location.OutDirection; Active = true; }
public void Test_Path_Branch_PostOuterBranchIDGone() { NODE_DIRECTION initDir = NODE_DIRECTION.UP, branchDir = NODE_DIRECTION.UP_LEFT_RIGHT; Path path = new Path(origin, initDir); int initBranchId = path.OuterBranchIDs[0]; Branch initBranch = path.Branches[initBranchId]; initBranch.Add(branchDir); path.Branch(initBranchId); Assert.That(path.OuterBranchIDs, !Contains.Item(initBranchId)); }
/// <summary> /// Move player to the node in the specified _dir /// </summary> /// <param name="_dir"></param> /// <returns></returns> bool AIJump(NODE_DIRECTION _dir) { if (currentNode.GetLink(_dir) != null && currentNode.GetLink(_dir).gameObject.activeSelf) { AdjustLink(currentNode); Node previousNode = currentNode; currentNode = currentNode.GetLink(_dir); previousNode.gameObject.SetActive(false); lastDirection = _dir; remainingStones--; return(true); } return(false); }
/// <summary> /// Break a multi-direction into individual NODE_DIRECTIONs. /// </summary> /// <param name="multiDirection"></param> /// <returns></returns> public static IEnumerable <NODE_DIRECTION> GetDirections(this NODE_DIRECTION multiDirection) { NODE_DIRECTION[] basicDirectionSet = { NODE_DIRECTION.UP, NODE_DIRECTION.DOWN, NODE_DIRECTION.LEFT, NODE_DIRECTION.RIGHT }; foreach (NODE_DIRECTION direction in basicDirectionSet) { if (multiDirection.CheckFlag(direction)) { yield return(direction); } } yield break; }
public void Test_Path_Branch_PostOuterBranchIDCount() { NODE_DIRECTION initDir = NODE_DIRECTION.UP, branchDir = NODE_DIRECTION.UP_LEFT_RIGHT; Path path = new Path(origin, initDir); int initBranchId = path.OuterBranchIDs[0]; Branch initBranch = path.Branches[initBranchId]; initBranch.Add(branchDir); path.Branch(initBranchId); Assert.That(path.OuterBranchIDs.Count, Is.EqualTo(3)); }
public Branch(int id, Node outNode, NODE_DIRECTION direction, Path parent = null) { ID = id; Parent = parent; OutNode = outNode; Vector2Int initLoc = outNode.Next(direction); InNode = new Node(initLoc.x, initLoc.y, this); InNode.OutNode = OutNode; _nodeDirectory = new Dictionary <Vector2Int, Node>(); _nodeDirectory.Add(InNode.VectorLocation, InNode); Open = true; }
/// <summary> /// Move player to the node in the specified _dir /// </summary> /// <param name="_dir"></param> /// <returns></returns> bool Jump(NODE_DIRECTION _dir) { if (levelManager.CurrentNode.GetLink(_dir) != null && levelManager.CurrentNode.GetLink(_dir).gameObject.activeSelf) { levelManager.Jump(_dir); sfx.PlaySoundRandomPitch(SoundManager.SOUNDS.JUMP); jumping = true; animationController.SetJumpPose(_dir); animationController.SetWaiting(false); animationController.ResetIdleTimer(); distanceFromNextRock = Vector2.Distance(transform.position, levelManager.CurrentNode.transform.position); return(true); } return(false); }
/// <summary> /// Compare another node to this node and get the UP, DOWN, LEFT, RIGHT direction from this node to that node. /// </summary> /// <param name="other"></param> /// <returns></returns> public NODE_DIRECTION DirectionOf(Node other) { if (XLocation == other.XLocation) { //return YLocation > o.YLocation ? NODE_DIRECTION.DOWN : NODE_DIRECTION.UP; NODE_DIRECTION outd = YLocation > other.YLocation ? NODE_DIRECTION.DOWN : NODE_DIRECTION.UP; return(outd); } else if (YLocation == other.YLocation) { return((NODE_DIRECTION)(6 - ((XLocation - other.XLocation) * 2))); } else { return(NODE_DIRECTION.NONE); } }
// Update is called once per frame public void Update() { if (Active) { currentInterval += Time.deltaTime; // We're at or past the beginning of the next node. if (currentInterval > MoveInterval && !turning) { currentInterval -= MoveInterval; Location = Location.OutNode; // Detect turning if (Location.OutNode != null && Location.OutDirection != facing) { turning = true; } } else if (currentInterval > TurnInterval && turning) { currentInterval -= TurnInterval; facing = Location.OutDirection; turning = false; } // Figure out the proper minion location based on the movement interval and handle arriving at the origin if (!turning && Location.OutNode != null) { Vector3 lerpedLocation = Vector3.Lerp(Location.VectorLocation.ToVector3(), Location.OutNode.VectorLocation.ToVector3(), currentInterval); Quaternion currentRotation = transform.rotation; transform.SetPositionAndRotation(lerpedLocation, currentRotation); } else if (turning) { Vector3 location = Location.VectorLocation.ToVector3(); float rotation = Mathf.LerpAngle(GetDirectionRotation(facing), GetDirectionRotation(Location.OutDirection), currentInterval); modelTransform.localRotation = Quaternion.Euler(0, rotation, 0); } else { Active = false; } } }
public Path(Node origin, NODE_DIRECTION initialDirections) { Origin = origin; Branches = new Dictionary <int, Branch>(); OuterBranchIDs = new List <int>(); _branchId = 1; _nodeDirectory = new Dictionary <Vector2Int, List <Node> >(); SetNodeDirectoryData(Origin); // Set in-direction of the Origin Origin.InDirection = initialDirections; // Create initial outer branches foreach (NODE_DIRECTION direction in initialDirections.GetDirections()) { Branch outerBranch = new Branch(_branchId++, origin, direction, this); Add(outerBranch); } }
/// <summary> /// Get the rotation mapping to the passed direction. /// </summary> /// <param name="direction"></param> /// <returns></returns> public static float GetDirectionRotation(NODE_DIRECTION direction) { // Get Direction switch (direction) { case NODE_DIRECTION.LEFT: return(LEFT_ROT); case NODE_DIRECTION.UP: return(UP_ROT); case NODE_DIRECTION.RIGHT: return(RIGHT_ROT); case NODE_DIRECTION.DOWN: return(DOWN_ROT); default: throw new MovementControllerException(MOVEMENT_CONTROLLER_EXCEPTION_TYPES.BAD_ROTATION_DIRECTION); } }
/// <summary> /// Get the opposite direction of passed in _dir /// </summary> /// <param name="_dir"></param> /// <returns></returns> public NODE_DIRECTION OppositeDirection(NODE_DIRECTION _dir) { switch (_dir) { case NODE_DIRECTION.UP: return(NODE_DIRECTION.DOWN); case NODE_DIRECTION.DOWN: return(NODE_DIRECTION.UP); case NODE_DIRECTION.LEFT: return(NODE_DIRECTION.RIGHT); case NODE_DIRECTION.RIGHT: return(NODE_DIRECTION.LEFT); default: break; } return(NODE_DIRECTION.MAX_DIRECTION); }