-
Notifications
You must be signed in to change notification settings - Fork 4
Dodging Component
The DodgingComponent
is a component that works cohesively with the MobDodgeTask
and introduces a dodging mechanism based on the detection of another entity (such as a projectile). Ultimately, it adds a method to an event listener, dodgeIncomingEntity, and utilizes game's built-in raycast mechanism to detect another entity. If the entity is detected, the dodge task will trigger this event listener and will change the mob's vertical direction based on its location on the map.
For simplicity of explanation, the entity detected from now on will be referred to as a projectile since it was its intended functionality but note that the detected entity may be changed based on the target layer initialised.
To use this DodgingComponent
, make sure to add the MobDodgeTask
to the specified entity before adding the component itself with its desired configurations.
Entity entity = NPCFactory.createMeleeBaseNPC();
DodgingComponent dodgeComponent = new DodgingComponent(PhysicsLayer.PROJECTILE);
// Priority is 5 here, just ensure it is higher than the other tasks.
entity.getComponent(AITaskComponent.class).addTask(new MobDodgeTask(new Vector(2f, 2f), 2f, 5));
entity.addComponent(dodgeComponent);
This component allows flexibility in configuration of the dodging mechanism, with only the detected target layer deemed essential for its initialisation.
-
targetLayer
: The target layer to be detected from the raycast. i.e.PhysicsLayer.PROJECTILE
. -
rangeDetection
: A float value representing the horizontal range where the entity of thetargetLayer
is detected, activating the dodge event. If not specified, it is initialised to be 0.25f. -
dodgeSpeed
: The vertical speed of the targeted mob entity when dodging the projectile. If not specified, it is initialised to be 1.75f.
-
MobDodgeTask
to be added to the AITaskComponent with a higher priority level than the otherMobWanderTask
. - Although this component utilises the
MobDodgeTask
, the component should still have aMobWanderTask
with a lower priority level. The direction of this task should have an existing horizontal velocity that is > 0f. - Should have a
PhysicsMovementComponent
with a set target.
This component's logic simply detects another target layer within a certain range proximity and moves the entity upwards or downwards by providing a vertical target and velocity.
This proximity detection is constructed through creating a Vector2
max range based on the initialised rangeDetection
variable, and using the PhysicsService
raycast boolean identifier.
private boolean isTargetVisible(Vector2 mobPos) {
Vector2 maxRange = new Vector2(mobPos.x - rangeDetection, mobPos.y);
// check also the upper and lower boundaries of the mob with the offset y mob
// detection.
Vector2 upperYMaxRangePos = new Vector2(mobPos.x - 3, mobPos.y - Y_OFFSET_MOB_DETECTION);
Vector2 lowerYMaxRangePos = new Vector2(mobPos.x - 3, mobPos.y + Y_OFFSET_MOB_DETECTION);
// Raycast the upper, middle and lower detection range.
return physics.raycast(mobPos, maxRange, targetLayer, hit)
|| physics.raycast(mobPos, upperYMaxRangePos, targetLayer, hit)
|| physics.raycast(mobPos, lowerYMaxRangePos, targetLayer, hit);
}
The mobPos
is a Vector2 value retrieved from the center position of the mob entity.
The hit
variable is a RaycastHit
variable. For more info, confer the documentation.
The reason for raycasting based on the upperYMaxRangePos
and the lowerYMaxRangePos
is to accomodate for the collider sizes of the mob and projectile entity with respect to the raycast. If this is not accomplished, the raycast from the center position of the mob entity may not be able to detect the projectile entity, even if the entity ends up colliding with the projectile due to collider sizes.
This
Y_OFFSET_MOB_DETECTION
for the triple raycasting is initialised to be 0.35f -> Can be altered if desired.
The mob's vertical direction of dodge depends on its respective location on the map. If the mob is at the upper half quadrant, the mob will dodge downwards.
private void setVerticalAngleDirection(float y) {
entity.getComponent(PhysicsMovementComponent.class).setTarget(new Vector2(0, y));
}
setVerticalAngleDirection(mobPos.y > 3.5 ? mobPos.y - 15 : mobPos.y + 15);
In the time of writing this documentation, vertical half map size is 3.5. Please change this accordingly if the map / lane sizes changes.
As seen, the vertical target direction of the PhysicsMovementComponent is altered by 15 accordingly. This is what makes the mobs go upward or downward.
Please note: This dodging based on map location tend to make dodging mobs migrate to the middle of the map. Further extensions of this component could include a random direction identifier, encouraging sporadic dodging mechanisms instead of predictable patterns emerging.
In this case, we utilised a MobDodgeTask
to trigger the event of dodgingIncomingEntity
. This detection will activate after every set interval. In this case, the set interval is 500ms. Set interval is crucial as it prevents detection to be checked after every frame of the running game.
/**
* Run a frame of the task. In this extension of the update(), the
* "dodgeIncomingEntity" event will be detected and triggered on set intervals.
*/
@Override
public void update() {
super.update();
if (timeSource.getTime() >= endTime) {
owner.getEntity().getEvents().trigger("dodgeIncomingEntity",
owner.getEntity().getCenterPosition());
endTime = timeSource.getTime() + DELAY_INTERVAL; // update time
}
}
If this component was to be used outside of dodging mobs, please make another respective task with the same logic that has a higher priority than the other tasks.
Please ensure map boundaries with appropriate collision layers are put in place for the respective mob entity. As such, the mob entity should not be able to go of map bounds due to its dodging mechanisms. Does not particularly apply for the current mechanism but more so for the direction-randomiser extension.
If dodge speed is to be initialised normally, ensure it is an appropriate value - especially in coherence with the range detection variable. For instance, setting the dodge speed to be a very low value with a low detection range could make the mob still collide with the projectile, ultimately rendering the component useless.
The speed should always be > 0f.
The default range detection is 0.25f and is deemed to be an appropriate value for a dodging speed of >1.25f. Feel free to change this accordingly but going below this value may result in the mob still colliding with the projectile depending on the vertical and horizontal speed and its collider sizes. On the other hand, going above 1.25f results the projectile dodging the incoming projectile at a very far distance, defeating the purpose of the dodging aspect of the component.
That being said, feel free to experiment and use values desired that are outside the recommended range.
Visually, the mob with the MobDodgeTask
and DodgingComponent
dodges the incoming projectile appropriately based on its respective position on the map.
JUnit confirmed the existence of this component when added and the number of invocations for the event to be triggered based on the specified distance of the two entities' locations.