void Update_Movement(float deltaTime) { if (currTile == destTile) { path = null; return; // we are where we want to be; } if (nextTile == null || nextTile == currTile) { //pathfind next tile if (path == null || path.Lenght() == 0) { path = new Path_AStar(currTile.World, currTile, destTile); if (path.Lenght() == 0) { //Debug.Log ("no path to dest"); //FIXME job maybe must be reenqued instead; AbandonJob(); //FIXME cancel Job; return; } } //grab next tile nextTile = path.DequeueNextTile(); if (nextTile == currTile) { //Debug.LogError ("Update movement - next tile is currtile"); } } //total distance float distToTravel = Mathf.Sqrt(Mathf.Pow(currTile.X - nextTile.X, 2) + Mathf.Pow(currTile.Y - nextTile.Y, 2)); // float distThisFrame = speed * deltaTime; float percThisFrame = distThisFrame / distToTravel; movementPercentage += percThisFrame; if (movementPercentage >= 1) { currTile = nextTile; movementPercentage = 0; // FIXME => overshotmovement????? } }
/// <summary> /// Update all movement related things of a character /// </summary> /// <param name="deltaTime">The time passed since last tick</param> void UpdateCharacter_Movement(float deltaTime) { // Is movement needed? Is character already at the correct location if (currentTile == DestinationTile) { // Reset the current A* path path_AStar = null; return; } // currentTile = The tile a character is currently standing on and might be in the process of leaving // nextTile = The tile a character is entering // destinationTile = The final destination -- a character never gets here directly, but it's used for pathfinding instead // Grab 'next' nextTile if (nextTile == null || nextTile == currentTile) { // Get next tile from the path (calculted path wiht A*) if (path_AStar == null || path_AStar.Length() == 0) { // Generate new A* path from currentTile to destinationTile path_AStar = new Path_AStar(currentTile.World, currentTile, DestinationTile); // Check if path isn't null if (path_AStar.Length() == 0) { Debug.LogError("Path_AStar: Returned no path to destination!"); // FIXME: Job should get added back to queue AbandonJob(); return; } // Grab the first tile and right away override it. // First tile is the file the character is standing on, this results in some problems. (tile might have a movementCost of 0, like a wall that was just build by the character) nextTile = path_AStar.DequeueNextTile(); } // Grab the next tile nextTile = path_AStar.DequeueNextTile(); // Check for error if (nextTile == currentTile) { Debug.LogError("UpdateCharacter_Movement: nextTile == currentTile? -- Only valid for startingTile."); } } // At this point there a valid nextTile to move to. // Total distance from A to B (pythagorean theorem) float totalDistanceToTravel = Mathf.Sqrt( Mathf.Pow(currentTile.X - nextTile.X, 2) + Mathf.Pow(currentTile.Y - nextTile.Y, 2)); /// Check if movementCost is 0, which it never should be. /// Set nextTile to null, so that the character won't move. /// Set path_AStart to null, this one is no longer valid. /// MovementCost can be 0 if something was build in the mean time if (nextTile.IsEnterable() == EnterAbility.Never) { Debug.LogError("FIXME: A charcter tried to enter an unwalkable tile!"); nextTile = null; path_AStar = null; return; } // Character can't enter right now, but will be in the near future. (like a door or something) else if (nextTile.IsEnterable() == EnterAbility.Soon) { // Temp return; } // Distance to travel in one tick (one frame) // nextTile.MovementCost can be 0 (which would throw an error) but it should never happen. // Moving to a tile with a movementCost of 0 is NOT allowed float distanceThisTick = (movementSpeed / nextTile.MovementCost) * deltaTime; // Progression in one tick float progressionThisTick = distanceThisTick / totalDistanceToTravel; // Increase the movement progression each tick movementProgression += progressionThisTick; // Has the character reached it's destination yet? if (movementProgression >= 1) { currentTile = nextTile; movementProgression = 0; } }