public float getMoveTime(NodeVO node) { float moveTime = DifficultyModel.Instance().moveTime; if (node.HasFlag(NodeVO.SPECIALS_SPEEDUP_UP)) { if (directionIdx == NodeVO.DIRECTION_UP_IDX) { moveTime /= 2; } if (directionIdx == NodeVO.DIRECTION_DOWN_IDX) { moveTime *= 2; } } if (node.HasFlag(NodeVO.SPECIALS_SPEEDUP_RIGHT)) { if (directionIdx == NodeVO.DIRECTION_RIGHT_IDX) { moveTime /= 2; } if (directionIdx == NodeVO.DIRECTION_LEFT_IDX) { moveTime *= 2; } } if (node.HasFlag(NodeVO.SPECIALS_SPEEDUP_DOWN)) { if (directionIdx == NodeVO.DIRECTION_DOWN_IDX) { moveTime /= 2; } if (directionIdx == NodeVO.DIRECTION_UP_IDX) { moveTime *= 2; } } if (node.HasFlag(NodeVO.SPECIALS_SPEEDUP_LEFT)) { if (directionIdx == NodeVO.DIRECTION_LEFT_IDX) { moveTime /= 2; } if (directionIdx == NodeVO.DIRECTION_RIGHT_IDX) { moveTime *= 2; } } return(moveTime); }
override public PrefromResult Perform (float delta) { var player = PlayerModel.Instance (); IntPointVO pos = player.cellPosition; int directionIdx = player.directionIdx; NodeVO node = MazeModel.Instance ().GetNode (pos.x, pos.y); GameModel game = GameModel.Instance (); game.AddScore ((int)((float)node.score * game.timeBonus)); node.score = 0; game.movesLeft.Dec (1); if (game.state == GameModel.STATE_INITED || game.state == GameModel.STATE_STUCK) { game.state = GameModel.STATE_MOVING; game.score.Freeze(); game.timeBonus.Freeze(); } if (node.HasFlag (NodeVO.SPECIALS_EXIT)) { game.state = GameModel.STATE_ENDED; MazePaceNotifications.EXIT_REACHED.Dispatch (); } else { if (node.HasFlag (NodeVO.SPECIALS_HIDE_WALLS)) { MazePaceNotifications.TOGGLE_WALLS_VISIBILITY.Dispatch (false); } if (node.HasFlag (NodeVO.SPECIALS_SHOW_WALLS)) { MazePaceNotifications.TOGGLE_WALLS_VISIBILITY.Dispatch (true); } bool shouldRotate = node.HasWall (directionIdx) || player.moved; if (node.HasFlag (NodeVO.SPECIALS_ROTATOR_CW | NodeVO.SPECIALS_ROTATOR_CCW) && shouldRotate) { MazePaceNotifications.ROTATE_AT_NODE.Dispatch (node); player.moved = false; } else if (!node.HasWall (directionIdx)) { player.cellPosition.x += NodeVO.DIRECTIONS [player.directionIdx, 0]; player.cellPosition.y += NodeVO.DIRECTIONS [player.directionIdx, 1]; player.moved = true; MazePaceNotifications.PROCEED_FROM_NODE.Dispatch (node); } else { game.state = GameModel.STATE_STUCK; game.score.SetValue (game.score, 0, DifficultyModel.Instance ().scoreDrainTime); MazePaceNotifications.PLAYER_STUCK.Dispatch (); } } MazePaceNotifications.GAME_UPDATED.Dispatch (); return PrefromResult.COMPLETED; }
public void Recreate(int size, int startX, int startY) { this.size = size; _data = new NodeVO[size * size]; deadEnds = new List <NodeVO> (); crossRoads = new List <NodeVO> (); for (int j = 0; j < size; j++) { for (int i = 0; i < size; i++) { _data [i + j * size] = new NodeVO(i, j); } } //1. get starting point startingNode = GetNode(startX, startY); startingNode.AddFlag(NodeVO.PROCESSED); //2. init edge nodes from its neighbours List <NodeVO> edgeNodes = GetNotProcessedNeighboursOf(startingNode); foreach (NodeVO nodeData in edgeNodes) { Link(startingNode, nodeData); } //3. create branches from edge nodes while (edgeNodes.Count > 0) { //3.1 find a random edge node and remove it from array int idx = _rnd.Next(0, edgeNodes.Count); NodeVO edgeNode = edgeNodes [idx]; edgeNodes.RemoveAt(idx); if (!edgeNode.HasFlag(NodeVO.PROCESSED)) { //3.2 attach it to current tree NodeVO processedNeighbour = GetRandomNeighbour(edgeNode, true); if (processedNeighbour != null) { Merge(processedNeighbour, edgeNode); Link(processedNeighbour, edgeNode); if (!crossRoads.Contains(processedNeighbour)) { crossRoads.Add(processedNeighbour); } } //3.3 create the branch CreateBranch(edgeNode, edgeNodes); } } }
void RotateAt(NodeVO node) { int rotateBy = 0; if (node.HasFlag(NodeVO.SPECIALS_ROTATOR_CW)) { rotateBy = 1; } else if (node.HasFlag(NodeVO.SPECIALS_ROTATOR_CCW)) { rotateBy = -1; } else { Debug.LogError("RotateAt called on non rotation node"); } if (rotateBy != 0) { transform.DORotate(transform.rotation.eulerAngles + new Vector3( 0, 0, rotateBy * -90), 0.4f).OnComplete(OnRotateCompleted); PlayerModel.Instance().directionIdx += rotateBy; } }
/** * Gets all neighbours of specified node not processed by alghoritm. */ private List <NodeVO> GetNotProcessedNeighboursOf(NodeVO target) { List <NodeVO> neighbours = new List <NodeVO> (); for (int i = 0; i < 4; i++) { int x = target.pos.x + NodeVO.DIRECTIONS [i, 0]; int y = target.pos.y + NodeVO.DIRECTIONS [i, 1]; if (IsInBounds(x, y)) { NodeVO neighbour = GetNode(x, y); if (!neighbour.HasFlag(NodeVO.PROCESSED)) { neighbours.Add(neighbour); } } } return(neighbours); }
/** * Finds a random neighbour with specified param */ private NodeVO GetRandomNeighbour(NodeVO target, bool processedNeeded) { int offset = _rnd.Next(0, 4); for (int i = 0; i < 4; i++) { int dir = (offset + i) % 4; int x = target.pos.x + NodeVO.DIRECTIONS [dir, 0]; int y = target.pos.y + NodeVO.DIRECTIONS [dir, 1]; if (IsInBounds(x, y)) { NodeVO neighbour = GetNode(x, y); if ((neighbour.HasFlag(NodeVO.PROCESSED) && processedNeeded) || (!neighbour.HasFlag(NodeVO.PROCESSED) && !processedNeeded)) { return(neighbour); } } } return(null); }
public static void Apply(MazeModel mazeData) { if (DifficultyModel.Instance().speedUpsCount == 0) { return; } List <SpeedUpChain> chains = new List <SpeedUpChain> (); foreach (NodeVO deadEnd in mazeData.deadEnds) { NodeVO node = deadEnd; int currentDirection = -1; SpeedUpChain currentChain = new SpeedUpChain(); do { NodeVO previousNode = node.previousNode; bool nodeHasSpeedUp = false; foreach (SpeedUpChain chain in chains) { if (chain.nodes.Contains(node)) { nodeHasSpeedUp = true; break; } } if (nodeHasSpeedUp) //branch reached a point of another branch that has already been processed { break; } if (previousNode != null) { currentChain.nodes.Add(node); bool hasSpecial = previousNode.HasFlag( NodeVO.SPECIALS_ROTATOR_CW | NodeVO.SPECIALS_ROTATOR_CCW | NodeVO.SPECIALS_HIDE_WALLS | NodeVO.SPECIALS_SHOW_WALLS); int direction = previousNode.GetDirectionTowards(node); if ((currentDirection != direction) || hasSpecial) { if (currentChain != null && currentChain.nodes.Count > 1) { chains.Add(currentChain); } currentChain = new SpeedUpChain(); currentChain.direction = direction; } currentDirection = hasSpecial ? -1 : direction; } node = previousNode; } while (node != null); } chains.Sort(); for (int i = 0; i < chains.Count; i++) { if (i >= DifficultyModel.Instance().speedUpsCount) { break; } //mark nodes to contain according speedup flags foreach (NodeVO nodeData in chains[i].nodes) { switch (chains [i].direction) { case (NodeVO.DIRECTION_UP_IDX): nodeData.AddFlag(NodeVO.SPECIALS_SPEEDUP_UP); break; case (NodeVO.DIRECTION_RIGHT_IDX): nodeData.AddFlag(NodeVO.SPECIALS_SPEEDUP_RIGHT); break; case (NodeVO.DIRECTION_DOWN_IDX): nodeData.AddFlag(NodeVO.SPECIALS_SPEEDUP_DOWN); break; case (NodeVO.DIRECTION_LEFT_IDX): nodeData.AddFlag(NodeVO.SPECIALS_SPEEDUP_LEFT); break; } } } }
// Use this for initialization public void Redraw(NodeVO data, Color color) { foreach (GameObject existingObject in _objects) { Destroy(existingObject); } _objects.Clear(); _wallInstance = null; _tileRenderer = GetComponent <SpriteRenderer> (); _tileRenderer.color = color; //create a wall if (data.pos.x > 0 && data.HasWall(NodeVO.DIRECTION_LEFT_IDX)) { if (data.pos.y > 0 && data.HasWall(NodeVO.DIRECTION_DOWN_IDX)) { _wallInstance = (GameObject)Instantiate(PrefabLib.WALL_SOUTH_WEST); } else { _wallInstance = (GameObject)Instantiate(PrefabLib.WALL_WEST); } } else if (data.pos.y > 0 && data.HasWall(NodeVO.DIRECTION_DOWN_IDX)) { _wallInstance = (GameObject)Instantiate(PrefabLib.WALL_SOUTH); } if (_wallInstance) { _objects.Add(AddObject(_wallInstance)); } if (data.HasFlag(NodeVO.SPECIALS_EXIT)) { _objects.Add(AddObject((GameObject)Instantiate(PrefabLib.EXIT))); } if (data.HasFlag(NodeVO.SPECIALS_SPEEDUP_UP)) { _objects.Add(AddObject((GameObject)Instantiate(PrefabLib.SPEED_UP))); } if (data.HasFlag(NodeVO.SPECIALS_SPEEDUP_RIGHT)) { GameObject specInstance = (GameObject)Instantiate(PrefabLib.SPEED_UP); specInstance.transform.eulerAngles = new Vector3(0, 0, -90); _objects.Add(AddObject(specInstance)); } if (data.HasFlag(NodeVO.SPECIALS_SPEEDUP_DOWN)) { GameObject specInstance = (GameObject)Instantiate(PrefabLib.SPEED_UP); specInstance.transform.eulerAngles = new Vector3(0, 0, 180); _objects.Add(AddObject(specInstance)); } if (data.HasFlag(NodeVO.SPECIALS_SPEEDUP_LEFT)) { GameObject specInstance = (GameObject)Instantiate(PrefabLib.SPEED_UP); specInstance.transform.eulerAngles = new Vector3(0, 0, 90); _objects.Add(AddObject(specInstance)); } if (data.HasFlag(NodeVO.SPECIALS_ROTATOR_CW)) { _objects.Add(AddObject((GameObject)Instantiate(PrefabLib.ROTATOR_CW))); } if (data.HasFlag(NodeVO.SPECIALS_ROTATOR_CCW)) { _objects.Add(AddObject((GameObject)Instantiate(PrefabLib.ROTATOR_CCW))); } if (data.HasFlag(NodeVO.SPECIALS_HIDE_WALLS)) { _objects.Add(AddObject((GameObject)Instantiate(PrefabLib.HIDE))); } if (data.HasFlag(NodeVO.SPECIALS_SHOW_WALLS)) { _objects.Add(AddObject((GameObject)Instantiate(PrefabLib.SHOW))); } }