static public bool IsDirectionsParallel(OrthogonalDirection dir1, OrthogonalDirection dir2) { /* * Return true if dir2 is parallel to dir1 */ bool parallel = false; if (dir1.Equals(dir2) || dir1.Equals(OppositeDirection(dir2))) { parallel = true; } return(parallel); }
static public bool IsDirectionsPerpendicular(OrthogonalDirection dir1, OrthogonalDirection dir2) { /* * Return true if dir2 is perpendicular to dir1 */ bool perpendicular = false; if (dir1.Equals(NextDirection(dir2)) || dir1.Equals(PreviousDirection(dir2))) { perpendicular = true; } return(perpendicular); }
static public bool IsDirectionNegative(OrthogonalDirection direction) { /* * Return whether the given direction goes along the negative axis. * ie, up is along the positive Y axis, but down is along the negative Y axis. */ bool negativeDirection = false; if (direction.Equals(OrthogonalDirection.Down) || direction.Equals(OrthogonalDirection.Left)) { negativeDirection = true; } return(negativeDirection); }
static public bool IsDirectionsOpposites(OrthogonalDirection dir1, OrthogonalDirection dir2) { /* * Return true if the two given directions are opposites */ bool oppositeDirections = false; if (dir1.Equals(OppositeDirection(dir2))) { oppositeDirections = true; } return(oppositeDirections); }
public void MovePlayerRequest(OrthogonalDirection primary, OrthogonalDirection secondairy, ref float distance) { /* * Move the player along their line. How they are moved is determined by the player's * state, the inputs they are using and their current line. */ OrthogonalDirection direction = OrthogonalDirection.NULL; /* * Keep moving the player along the given direction until they run out of distance or are blocked */ bool blocked = false; int loopCount = 0; while (distance > 0 && !blocked) { /* Get the direction the player will move in relative to their state */ direction = UpdatePlayerInputDirection(state, primary, secondairy); if (direction != OrthogonalDirection.NULL) { /* * Travel in the given direction for up to the given distance or until * the player reaches a corner with no linked line in the given direction. */ if (state == PlayerStates.Travelling) { /* The given direction is parallel to the current line */ if (currentLine.IsDirectionParallel(direction)) { /* Scan ahead from the player's position to see how far the player is allowed to travel */ float travelDistance = 0; currentLine.PredeterminePlayerMovement(this, gamePosition, direction, ref travelDistance, distance, true, ref blocked); //Debug.Log("moving towards " + direction + " " + travelDistance); /* Move the player by the amount of distance to travel and update the remaining distance */ MovePlayer(direction, travelDistance); distance -= travelDistance; /* We reached a corner if we still have distance to travel and are not blocked */ if (distance > 0 && !blocked) { /* Check if either given directions will let the player pass the corner */ if (GetCorner().AttachedLineAt(primary) != null || GetCorner().AttachedLineAt(secondairy) != null) { //We can move onto the next line, ie repeat the loop } else { //The corner ends here - the player cannot leave the line blocked = true; Debug.Log("CANT LEAVE LINE"); } } } /* The given direction does not follow the line - stop the player from moving */ else { blocked = true; Debug.Log("Cannot go further"); } } /* * In the pre-drawing state, the direction controls where the player travels. * If direction is equal to what their primary input is, ie it was unchanged, * travel normally along the direction until a corner. * * If direction is NOT equal to the primary input because it was changed from UpdatePlayerInputDirection(), * then the player is trying to find the "drawing point" to start drawing from. * A drawing point is the edge of the gameArea's grid or any corner. * * If direction does not match primary, that means we are trying to enter the drawing * state but we are not on the grid. */ else if (state == PlayerStates.PreDrawing) { float shortestDistance = 0; /* If we are trying to find the nearest grid mark, update shortestDistance to reflect said distance */ if (direction != primary) { float forwardGrid = currentLine.DistanceToClosestGrid(gamePosition, direction, gameController.gridSize, true); float backwardGrid = currentLine.DistanceToClosestGrid(gamePosition, Corner.OppositeDirection(direction), gameController.gridSize, true); /* If the backwards grid is closer, flip the direction and use the grid behind */ if (backwardGrid < forwardGrid) { shortestDistance = backwardGrid; direction = Corner.OppositeDirection(direction); } /* Use the forward grid as it's closer */ else { shortestDistance = forwardGrid; } } /* If we are travelling along the line, update shortestDistance to reflect the upcomming corner */ else if (GetCorner() == null || GetCorner().AttachedLineAt(direction) != null) { shortestDistance = currentLine.DistanceToCorner(gamePosition, direction); } /* Prevent the player from travelling further than the remaining distance allows */ shortestDistance = Mathf.Min(shortestDistance, distance); /* If we have reached a corner that doesn't have a line in the given direction * OR we have reached a grid marker (indicated by shortestDistance = 0), * then we start drawing a line from the player's given position */ if (shortestDistance == 0 || (GetCorner() != null && GetCorner().AttachedLineAt(primary) == null)) { if (PreEnterDrawingCheck(primary)) { ChangeState(PlayerStates.Drawing); /* Catch if the player enters the drawing state without any distance left to travel. * This is so that we don't create a point line without travelling across it */ if (distance <= 0) { throw new Exception("!!ERROR!!: Changed into the drawing state without any distance left to move. This should not happen"); } } else { Debug.Log("FAILED???"); blocked = true; } } /* We can continue travelling along the lines */ else { float travelDistance = 0; currentLine.PredeterminePlayerMovement(this, gamePosition, direction, ref travelDistance, shortestDistance, true, ref blocked); MovePlayer(direction, travelDistance); distance -= travelDistance; } } /* * In the drawing state, simply move the player along their drawing line's direction * and update their drawing line's position to reflect the change. */ else if (state == PlayerStates.Drawing) { float travelDistance = 0; OrthogonalDirection lineDirection = currentLine.StartToEndDirection(); /* Let the player move forward normally */ if (direction.Equals(lineDirection)) { travelDistance = distance; } /* Turning the line requires the player to be on a grid mark */ else if (Corner.IsDirectionsPerpendicular(direction, lineDirection)) { float distanceToGrid = NearestGrid(lineDirection); /* If the player is on the grid mark, create a new line to change their direction */ if (distanceToGrid == 0) { /* Create a corner at the player's position and make a new drawing line off it */ NewDrawingLine(direction, true); } /* Change the travel distance to reach the grid mark */ else { travelDistance = Mathf.Min(distance, distanceToGrid); direction = lineDirection; } } /* Don't let the player move backwards along the line */ else { blocked = true; } /////////////////////TODO: Improve /* Move the player. If the player moves into a line, they will connect their drawing line */ if (travelDistance > 0) { Line playersMovementPath = Line.NewLine(gamePosition, gamePosition + travelDistance * Corner.DirectionToVector(direction)); /* Get a list of lines that the player's direction collides with */ List <Line> collidedLines = gameController.DoesLineCollide(playersMovementPath, GetTouchingLines()); Line closestLine = null; if (collidedLines.Count > 0) { /* Get the closest line and collision point along the line */ float ClosestCollisionDistance = ClosestCollisionAlongLine(playersMovementPath, collidedLines, ref closestLine); travelDistance = ClosestCollisionDistance; blocked = true; Debug.Log("HIT LINE"); } MovePlayer(direction, travelDistance); distance -= travelDistance; /* Update the player's line to reflect the player's position change */ currentLine.end = gamePosition; currentLine.GenerateVertices(gameController); /* If there was a collision, move the player onto the collided line and change their state */ if (collidedLines.Count > 0) { Debug.Log(closestLine + " ---- "); ChangeCurrentLine(closestLine); ChangeState(PlayerStates.Travelling); } } } } else { /* The given direction is NULL - stop the player in their current position */ blocked = true; } /* Prevent the loop from getting stuck */ loopCount++; if (loopCount > 100) { blocked = true; Debug.Log("----------------------"); Debug.Log("--- LOOP WAS STUCK ---"); Debug.Log("----------------------"); } } }