Player Movement - UQdeco2800/2021-studio-6 GitHub Wiki
Descriptions
In order to control the player character while in the game world, the user is able to move along all the main axis. Additionally to these basic conventional controls the player is able to use a dash which will allow them to move quickly in order to dodge enemies or move around areas.
Dash
If the player presses the left shift key, grabbed in KeyboardPlayerInputComponent, the game will run the dash event. This event is picked up by PlayerActions which is hooked into the games internal clock, which it uses to apply a locked direction, speed boost, to the player over time.
If the player is moving and not currently in a delay period, the player will be put into a dashing state. The dash will make the player move faster, in a specific direction, for a set amount of time (applied to the game within the updateDash function, which is triggered on every update if the player is currently in a dashing state). During this time the player will be unable to attack (in KeyboardPlayerInputComponent or change the direction of movement (as the dashing state is prioritised over the walking state in PlayerActions) until the dash is over. During the dash invincibility is also triggered in PlayerCombatStatsComponent, so that for the duration of the dash the player cannot take damage.
In order to ensure the distance travelled when dashing diagonally is equivalent to that when horizontal/vertical, within the setDash() function (which is responsible for starting the dash state, setting direction/speed and setting invincibility), the diagonal speed scaler is set to half that of the setting for horizontal/vertial, so when scaling both axis' the same distance is travelled.
Public Methods
boolean isDashing(): returns whether or not the player is currently dashing
boolean canDash(): returns whether or not the player is able to dash (i.e. false if currently in dash cooldown)
long getDelayTimeRemaining(): returns the time remaining until the player can dash again
These methods were implemented to allow other classes to be aware of the dashing state, primarily for stopping functions during the dash or to link into later HUD elements.
Design Justifications:
The dash function implements the games internal timer to ensure the time between dashes is kept consistent and the logic behind the code is coherent, avoiding having multiple concurrently running timers to keep track of. Additionally, multiple time variables were used to ensure the dash timing was consistent and that the game only checked if it could dash when attempting to do so (reducing the number of concurrently running processes). Additionally by setting dash end in player movement it ensures that the player automatically is set to no longer dashing without extra overhead tracking.
Additionally, this arrangement leaves the variables controlling delay between dashes, speed of dash & dash length (in PlayerActions) as variables within components, leading to easy future adaption if they are later wanted to be set in a configuration file. This gives the option for more specific player customisation and modification in later development.
Iterations:
Originally the dash was implemented using a timer in KeyboardInputPlayerComponent which gated whether the dash event could be triggered, this was to ensure all events occurred simultaneously or not at all. Additionally, the dash was a single movement to avoid using a second timer in the PlayerActions class.
However, this resulted in issues with the dash occasionally not triggering at higher frame rates, therefore a method of locking the player and applying the dash over a longer period of time was used. Additionally, by moving the timer into PlayerActions this allows there to be only one hook into the games internal clock, rather than having a secondary one in KeyboardInputPlayerComponent.
Additionally, following implementation of the abilities the dash function was abstracted into a setter (setDash()) and an activator (dash()), which allowed the common code for setting a dash (such as direction locking) to be reused through a secondary activator for the dash ability (see more in Player Abilities)
UML
To represent the main changes when switching to the dash sate a sequence diagram describes the function (abstracting out certain elements such as animation triggering which are irrelevant to the coding sequence). The purpose of this diagram is demonstrate the change in speed as well as the lack of effect when a user further attempts to move directionally when the dash state is currently active.