Worker Movement - UQdeco2800/2022-studio-3 GitHub Wiki

Overview

When a worker unit is selected, it can be moved to a new position within the game by scrolling the mouse thereto and right-clicking. Any selected workers will begin to move to that location and will continue to move until they either reach their current target or get stuck.

When a worker unit is still in transit to a target, the player can change their destination to a new target by right-clicking thereat.

If a worker unit is un-selected, then right-clicking at a new location will not move them.

Technical breakdown

Triggering movement

If the player presses the right-click button, then this input is handled by the touchDown function in the WorkerInputComponent (see Worker Selection for more details).

The world position of the cursor is slightly translated so that the centre of the worker unit aims to be where the mouse event took place.

Then, a workerWalk event is triggered which is handled by the startMoving function in the WorkerIdleTask.

public boolean touchDown(int screenX, int screenY, int pointer, int button) {
        // Find the world coordinates of the cursor
        Vector2 cursorWorldPos = screenToWorldPosition(screenX, screenY);
        if (button == Input.Buttons.RIGHT) {
            if (isSelected) {
                // Worker is selected. Prepare to move to cursor location.
                // Find the difference between the entity position and its central point
                Vector2 entityDeltas = entity.getPosition().sub(entity.getCenterPosition());
                // Find target vector such that when the entity reaches the target, it's
                // central point will align with the cursor
                Vector2 centerTarget = cursorWorldPos.add(entityDeltas);
                // Trigger WorkerMovementTask
                entity.getEvents().trigger("workerWalk", centerTarget);
            }
        } else if (button == Input.Buttons.LEFT) {
            ...
        return false;
    }

Movement

The worker movement itself is performed through use of a WorkerMovementTask. This task makes use of the movement component in the PhysicsMovementComponent class which include methods for setting the target and toggling movement.

On each update, the isAtTarget function is checked to see if the unit is yet to reach the designated target. If the function returns true, then the unit stops moving and the status set to FINISHED. Otherwise, if the unit is not yet at the target, the checkIfStuck function is called. If it is found that the entity is stuck, then the unit stops moving and the status set to FAILED.

Movement animation

In order to animate the direction of the worker movement, a case is included in WorkerIdleTask in order to play different animations. The direction will be based on (X, Y) point.

9F13B181B17AC1EE74BC5024207026C7E5CACC2F