Player Abilities - UQdeco2800/2021-studio-6 GitHub Wiki
Description
Alongside attacking, movement and dodging the player has an additional ability, which is an act the player can do, offensive/passive, as a last resort. This ability is triggerable with the "E" key and depending on the players settings triggers their ability including; a longer dash, temporary invincibility (alongside an optional non-state allowing for no ability). All abilities have a static long cooldown between instances of them utilising the ability.
Trigger System
Uses PlayerAbilitiesComponent which handles the cooldown and triggering of abilities is attached to the player entity in PlayerFactory. This component holds the players current ability and on the pressing of "E", grabbed in KeyboardPlayerInputComponent, triggers the current ability alongside handling the delay so the player is unable to use the ability until the delay is over.
Public Methods
void setAbility(Abilities ability): Sets the players ability to the given ability enum value
- NONE
- LONG_DASH
- INVINCIBILITY
Abilities getAbility(): Returns the current ability (as above)
Trigger Method
void triggerAbility() Triggered on the event "tryAbility", in turn triggers the correct event corresponding to the ability the player currently has selected.
Design Justifications
The ability code and cooldown are within a component class due to needing to be attached to the player in order to trigger the various abilities, which are based on functionalities achieved by other player components. Additionally, it was given its own class to ensure separation between elements, reduce complexity of the KeyboardPlayerInputComponent and as it generally did not logically incorporate into any other components.
The implementation of the abilities relies on event triggering in order to have as much separation between components as possible as the ability functionality effects multiple separate player components. This overall system also allows new abilities to be easily added and extended through adding them to the enum, then adding the event trigger to the trigger function.
The selection of abilities was done through an enum both to increase legibility of the code (as the initial implementation of integer codes was not easily parse-able) and to better align it with the code for items, as the ability selection mechanism will be similar to that provided through items and therefore it better prepares it for this implementation.
Considering Design Patterns
Ended up looking at design patterns when investigating how to trigger different abilities through one button, based on different settings. The most relevant pattern found was "State" which was focussed on changing behaviours based on internal state (all other semi-relevant patterns revolved around all state behaviours being interconnected/similar). The state pattern was not used as the number of states to be created was quite small (due to game balancing), the state determiner was through player selection and therefore only needed to be dependent on a single variable and the states were dissimilar enough that there was no significant code/behaviour duplication between them (other than the delay timer, but that was handled in a separate event triggering class).
Overall it was instead chosen to simply utilise the pre-existing functions of the observer patterns which allowed reduced dependencies while still allowing the multiple ability functions to communicate through the same key.
Enhanced Dash
On top of the players regular dash is an extended dash that can be chosen as their ability. It is implemented on top of the pre-existing Dash System within PlayerActions, simply utilising a second trigger function for the updateDash which will set the directional velocity to double the original and feed through the longer time specified in PlayerAbilities.
void longDash(long endTime) { dashEndTime = endTime; setDash(dashSpeed*2); }
Design justifications
By implementing it through the pre-existing dash system multiple classes do not jointly effect the players movement controls, removed some duplication code (especially as the same methods are used with different parameters/variable settings) and allowed the methods to be exclusionary to one another without communications systems on top of the pre-existing code.
Additionally, as there is no logical way to further extend the dash implementation without making the gameplay more redundant and effecting the game poorly, there was no issue with including the integration in the PlayerActions class as it would not need to be further extended to include other possible dashes.
Temporary Invincibility
The player will be able to select temporary invincibility as their ability. It is implemented on top of the pre-existing Invincibility System within PlayerCombatStatsComponent, simply utilising a trigger function for the invincibility event, which will set the length of invincibility to that provided in PlayerAbilitiesComponent.
Design justifications
By implementing it through the pre-existing system no additional overhead is to be applied to ensure the player is undergoing the correct behaviour and no additional code duplication needs to be added.