public static Vector3 GetDrawLineOffset(NetworkNode node, Direction direction) { if (node is TransitionNode) { return(Vector3.zero); } // 用自身的quaternion去乘,以修正3D中节点被旋转的情况 if (direction == Direction.Up) { return(node.transform.localRotation * verticalOffset); } if (direction == Direction.Right) { return(node.transform.localRotation * horizontalOffset); } if (direction == Direction.Down) { return(node.transform.localRotation * -verticalOffset); } if (direction == Direction.Left) { return(node.transform.localRotation * -horizontalOffset); } return(Vector3.zero); }
private void VisitNode(NetworkNode node) { if (!visitedNode.ContainsKey(node)) { visitedNode.Add(node, true); } queue.Enqueue(node); }
public void SetNeighbor(Direction direction, NetworkNode value) { Neighbors[(int)direction] = value; Debug.Log(string.Format("{0}: {1}, {2}, {3}, {4}", gameObject.name, Neighbors[0] != null ? Neighbors[0].ToString() : "null", Neighbors[1] != null ? Neighbors[1].ToString() : "null", Neighbors[2] != null ? Neighbors[2].ToString() : "null", Neighbors[3] != null ? Neighbors[3].ToString() : "null")); }
private void RegisterEvents(NetworkNode node) { node.OnClick += OnNodeClick; node.OnFocus += OnNodeFocus; node.OnDataChanged += OnNodeDataChanged; if (node is EndNode) { (node as EndNode).OnPuzzleComplete += OnPuzzleComplete; } }
public override void OnInit(NetworkNode node) { base.OnInit(node); IsUnlocked = false; ShowLock(); for (int i = 0; i < NetworkNode.NeighborNum; i++) { InputLockSprites[i].gameObject.SetActive(InputLockSetting[i]); } }
public Direction GetNeighborDirection(NetworkNode neighbor) { for (int i = 0; i < NeighborNum; i++) { if (GetNeighbor(i) == neighbor) { return((Direction)i); } } throw new Exception("is not neighbor"); }
public bool IsReachableTo(NetworkNode neighbor) { if (networkNodeLock != null) { return(false); } int direction = (int)GetNeighborDirection(neighbor); return(Outputs[direction]); }
public override void OnInput(NetworkNode.Direction from, bool isActive) { base.OnInput(from, isActive); int i = (int)from; if (InputLockSetting[i]) { // OnLockChanged(from, isActive); NetworkNode.SetSpriteActiveColor(InputLockSprites[i], isActive); } CheckLocks(); }
public override void OnClear() { base.OnClear(); NetworkNode.SetSpriteActiveColor(LockBackgroundSprite, false); for (int i = 0; i < NetworkNode.NeighborNum; i++) { if (InputLockSetting[i]) { NetworkNode.SetSpriteActiveColor(InputLockSprites[i], false); } } }
private GameObject CreateFlowGameObject(NetworkNode first, NetworkNode second, NetworkNode.Direction direction) { Vector3 offset1 = NetworkNode.GetDrawLineOffset(first, direction); Vector3 offset2 = NetworkNode.GetDrawLineOffset(second, direction); GameObject flowGo = Instantiate(NetworkFlowPrefab, NetworkFlows); LineRenderer lineRenderer = flowGo.GetComponent <LineRenderer>(); lineRenderer.SetPositions(new Vector3[] { first.transform.localPosition + offset1, second.transform.localPosition - offset2 }); return(flowGo); }
private void CheckLocks() { IsUnlocked = true; for (int i = 0; i < NetworkNode.NeighborNum; i++) { if (InputLockSetting[i] && !node.Inputs[i]) { IsUnlocked = false; break; } } NetworkNode.SetSpriteActiveColor(LockBackgroundSprite, IsUnlocked); if (OnCheckAllLock != null) { OnCheckAllLock(IsUnlocked); } }
public void Deactivate(NetworkNode from, NetworkNode to) { if (from == FirstNode && to == SecondNode) { fromFirstNodeActive = false; } else if (from == SecondNode && to == FirstNode) { fromSecondNodeActive = false; } if (!fromFirstNodeActive && !fromSecondNodeActive) { IsActive = false; lineRenderer.startColor = lineRenderer.endColor = NetworkBypassController.DeactiveColor; lineRenderer.material.color = NetworkBypassController.DeactiveColor; } }
private void CreateFlowBetween(NetworkNode first, NetworkNode second, NetworkNode.Direction direction) { NetworkFlow existFlow = activeFlowList.Find(x => x.FirstNode == second && x.SecondNode == first); // 两条有向边共享同一个flow GameObject GameObject flowObject = existFlow == null? CreateFlowGameObject(first, second, direction) : existFlow.FlowObject; NetworkFlow newFlow = new NetworkFlow(flowObject) { FirstNode = first, SecondNode = second, Direction = direction }; first.SetFlow(direction, newFlow); activeFlowList.Add(newFlow); }
public virtual void OnInit(NetworkNode _node) { node = _node != null ? _node : GetComponent <NetworkNode>(); }
private void TraverseNetwork() { foreach (var node in activeNodeList) { if (!(node is StartNode)) { node.Clear(); } } foreach (var flow in activeFlowList) { flow.Clear(); } visitedNode.Clear(); visitedFlow.Clear(); // 广度优先遍历 VisitNode(startNode); while (queue.Count > 0) { NetworkNode node = queue.Dequeue(); // 不允许从结束节点访问邻居节点 if (node is EndNode) { continue; } for (int i = 0; i < NetworkNode.NeighborNum; i++) { var direction = (NetworkNode.Direction)i; var neighbor = node.GetNeighbor(direction); if (neighbor == null) { continue; } var flow = node.GetFlow(direction); // 特例:结束(带锁)节点是可以被重复访问的 if (visitedNode.ContainsKey(neighbor) && visitedFlow.ContainsKey(flow) && visitedFlow[flow] && !(neighbor is EndNode)) { continue; } // 激活或反激活邻居节点的输入 if (node.IsReachableTo(direction)) { flow.Activate(node, neighbor); neighbor.SetInput(NetworkNode.GetOppositeDirection(direction), true); } else { flow.Deactivate(node, neighbor); neighbor.SetInput(NetworkNode.GetOppositeDirection(direction), false); } VisitNode(neighbor); VisitFlow(flow); } } }
private void TraverseNetworkFlow() { // 清理工作:将所有节点和流都关闭 foreach (var node in activeNodeList) { if (!(node is StartNode)) { node.Clear(); } } foreach (var flow in activeFlowList) { flow.Clear(); } visitedFlowList.Clear(); // 从起点开始,查找周边的通路 for (int i = 0; i < NetworkNode.NeighborNum; i++) { var flow = startNode.GetFlow(i); if (flow != null && startNode.IsReachableTo(flow.Direction)) { flowQueue.Enqueue(flow); Log(string.Format("Enqueue: {0}", flow)); } } // 开始遍历网络图 while (flowQueue.Count > 0) { NetworkFlow flow = flowQueue.Dequeue(); NetworkNode node = flow.FirstNode; NetworkNode neighbor = flow.SecondNode; visitedFlowList.Add(flow); Log(string.Format("Visit {0}", flow)); // 激活流和输入状态 NetworkNode.Direction direction = node.GetNeighborDirection(neighbor); flow.Activate(node, neighbor); neighbor.SetInput(NetworkNode.GetOppositeDirection(direction), true); bool nextFlowFound = false; for (int i = 0; i < NetworkNode.NeighborNum; i++) { var nextFlow = neighbor.GetFlow(i); if (nextFlow == null || visitedFlowList.Contains(nextFlow) || flowQueue.Contains(nextFlow) || // 第一趟查找,不包含那些已经走过一遍的通路 IsVisitedFlowExist(nextFlow.SecondNode, nextFlow.FirstNode)) { continue; } if (neighbor.IsReachableTo(nextFlow.Direction)) { Log(string.Format("Enqueue: {0}", nextFlow)); flowQueue.Enqueue(nextFlow); nextFlowFound = true; } } // 第二趟查找,可能包含反向的通路 if (!nextFlowFound) { for (int i = 0; i < NetworkNode.NeighborNum; i++) { var nextFlow = neighbor.GetFlow(i); if (nextFlow == null || visitedFlowList.Contains(nextFlow) || flowQueue.Contains(nextFlow)) { continue; } if (neighbor.IsReachableTo(nextFlow.Direction)) { Log(string.Format("Enqueue2: {0}", nextFlow)); flowQueue.Enqueue(nextFlow); } } } } }
private bool IsVisitedFlowExist(NetworkNode first, NetworkNode second) { return(visitedFlowList.Find( x => x.FirstNode == first && x.SecondNode == second) != null); }
private void OnNodeClick(NetworkNode node) { debugGUIText = "Click " + node.name; node.Execute(); }
private void OnNodeFocus(NetworkNode node) { debugGUIText = node != null ? "Hover " + node.name : string.Empty; }
private void OnNodeDataChanged(NetworkNode node) { isPuzzleComplete = false; // TraverseNetwork(); TraverseNetworkFlow(); }