/// <summary> /// Entry point to create a new level /// </summary> public void Init(int level, float animationSpeed = 1f, float delayScale = 1f, bool restart = false) { if (level < 0 || level > _puzzleSpawner.LevelCount) { Debug.LogWarning("Requested level is outside of bounds, ignoring request"); return; } // Destroy the previous level _puzzleSpawner.DestroyBoard(); _saveState.Started = true; // Spawn the new level _puzzle = _puzzleSpawner.SpawnBoard(level, animationSpeed, delayScale, restart); _playerState = _puzzle.PlayerState; CurrentLevel = level; // Reset the puzzle view state _arcMap.Reset(_puzzleSpawner.ArcMap); _fieldMap.Reset(_puzzleSpawner.FieldMap); _nodeMap = _puzzleSpawner.NodeMap; // Init all scripts that require additional information on startup _boardAction.Init(); _puzzleView.Init(_puzzle.StartNode.Position, _puzzle.BoardSize); _boardInput.Init(_puzzleSpawner.NodeMap); gameObject.name = $"PuzzleGame ({level})*"; TimeElapsed += Metadata.TimeElapsed; // Start with a pulled node if defined if (Metadata.StartPull == Direction.None) { return; } var startNode = _nodeMap[_puzzle.StartNode.Position]; Play(startNode, Metadata.StartPull); _puzzleView.Rotate(startNode, PulledArcView, Metadata.StartPull, true); _boardAction.HighlightAll(); LevelStateChanged?.Invoke(LevelState(), _puzzle.Win); }
public void Play(NodeView nodeView, Direction dir) { if (!enabled) { return; } if (_viewUpdating || LeanTween.isTweening(nodeView.gameObject)) { // If the animations are running, queue up the move if (_moveQueue.Count < MaxMovesInQueue) { _moveQueue.Enqueue(new Tuple <NodeView, Direction>(nodeView, dir)); } return; } // If this level has a tutorial, and this is not the expected move, don't play it if (_puzzleState.IsTutorial) { var move = _puzzleState.TutorialMove; if (!nodeView.Node.Position.Equals(move.Point) || move.Direction != dir) { return; } } _viewUpdating = true; // Try to play the move var movePlayed = _puzzleState.Play(nodeView, dir); // Modify the game view accordingly if (!movePlayed) { // Even though no move has been played, if there are no arcs parallel // to the swipe, we can have the nodes/arcs rotate for effect // (but not in the case where there is a pulled arc on the node) var canRotate = !_puzzleState.HasArcAt(nodeView.Position, dir) && !_puzzleState.HasArcAt(nodeView.Position, dir.Opposite()); var pushMove = _puzzleState.IsPulled && nodeView.Position.Equals(_puzzleState.PullPosition); if (pushMove) { // In the case of an invalid push move, shake the node _puzzleView.Shake(nodeView, dir); _gameAudio.Play(GameClip.InvalidRotate); } else if (canRotate) { _puzzleView.Rotate(nodeView, dir, true); _gameAudio.Play(GameClip.NodeRotate90); } else { _puzzleView.Shake(nodeView, dir); _gameAudio.Play(GameClip.InvalidRotate); } } else if (_puzzleState.IsPulled) { // Pull move _puzzleView.Rotate(nodeView, _puzzleState.PulledArcView, dir, true); _puzzleState.PulledArcView.PullSound(); _puzzleView.Shake(dir); _puzzleView.FloatIsland(true); HighlightAll(); } else { // Push move // If a push move has been played, move the arc to the node, then rotate it _puzzleView.MoveRotate(_puzzleState.PushNodePath, _puzzleState.PulledArcView, dir, () => _puzzleView.FloatIsland(false)); _puzzleView.Shake(dir); HighlightAll(); } _numActions++; }