/// <summary> /// Helper function for NewPlayerLocation function. Determines the player's new location when moving. /// </summary> /// <param name="loc">Vector containing the location of the player (x, y component) and the distance it will travel (z component).</param> /// <param name="dx">Change in x value when travelling.</param> /// <param name="dy">Change in y value when travelling.</param> /// <returns></returns> private IntVector.IntVector3 NewPlayerLocationHelper(IntVector.IntVector3 loc, int dx, int dy) { while (loc.x + dx >= 0 && loc.x + dx < width && loc.y + dy >= 0 && loc.y + dy < height) // check if new location is on the grid { if (gridTiles[loc.x + dx][loc.y + dy].Type == Tile.TileType.Default || // stop on default and dark tiles gridTiles[loc.x + dx][loc.y + dy].Type == Tile.TileType.Dark) { loc.x += dx; loc.y += dy; loc.z += 1; break; } else if (gridTiles[loc.x + dx][loc.y + dy].Type == Tile.TileType.Ice) // slide on ice tiles { loc.x += dx; loc.y += dy; loc.z += 1; IntVector.IntVector2 tmp = new IntVector.IntVector2(loc.x, loc.y); if (gridTools.ContainsKey(tmp) && gridTools[tmp].CanRedirect()) { break; } } else // stop before going onto blank tiles { break; } } return(loc); }
/// <summary> /// Determines the location of the player after moving in a certain direction. /// </summary> /// <param name="d">Direction the player wants to move in.</param> /// <returns>A vector containing the expected new position of the player (x, y components), /// and the number of units the player has to move to get there (z component). </returns> public IntVector.IntVector3 NewPlayerLocation(Direction d) { // default return vector is the current location with distance of 0 IntVector.IntVector3 newLoc = new IntVector.IntVector3(playerCurrentLocation.x, playerCurrentLocation.y, 0); // check if the player can move and update the vector if (d == Direction.Up) { newLoc = NewPlayerLocationHelper(newLoc, 0, 1); } else if (d == Direction.Down) { newLoc = NewPlayerLocationHelper(newLoc, 0, -1); } else if (d == Direction.Left) { newLoc = NewPlayerLocationHelper(newLoc, -1, 0); } else if (d == Direction.Right) { newLoc = NewPlayerLocationHelper(newLoc, 1, 0); } return(newLoc); }
/// <summary> /// Checks if the player can move in a certain direction. If they can, move them there. /// </summary> /// <param name="d">Direction the player will move in.</param> private void CheckMovement(Grid.Direction d) { IntVector.IntVector3 newLoc = grid.NewPlayerLocation(d); if (newLoc.z > 0) { isMoving = true; lastMove = d; StartCoroutine(Move(newLoc, d)); } }
/// <summary> /// Smoothly moves the player to the given position. /// </summary> /// <param name="newLoc">Contains the new location for the player (x, y component) and the distance the player must travel (z component).</param> /// <param name="d">Direction the player is moving in.</param> private IEnumerator Move(IntVector.IntVector3 newLoc, Grid.Direction d) { Vector2 startPos = transform.localPosition; // start location Vector2 endPos = new Vector2((float)newLoc.x, (float)newLoc.y); // end location float moveTimer = 0.0f; // time elapsed during move float moveTimeLimit = 0.12f * ((float)newLoc.z + 1); // total time to finish movement float ratio = 0.0f; // lerp ratio float unitCounter = 0.0f; // checks if player has moved a unit // move player while (ratio < 1.0f) { if (!paused) { if (reset) // check if reset button was pressed { reset = false; break; } float prev = ratio; moveTimer += Time.deltaTime; ratio = moveTimer / moveTimeLimit; transform.localPosition = Vector2.Lerp(startPos, endPos, ratio); // check if we've moved a unit unitCounter += (ratio - prev) * ((float)newLoc.z); if (unitCounter >= 1.0f) { grid.MovePlayer(d); unitCounter -= 1.0f; } } yield return(null); } // player no longer moving isMoving = false; // check if the puzzle is completed if (!extraMove) { moveCount.Increment(); } grid.CheckForFinishedPuzzle(); }