Teleport - UQdeco2800/2022-studio-2 GitHub Wiki

Back to Skills

Teleport Code

Teleport Modified Movement

The dashing movement is modified by the following code. We can see that this involves a slowdown of TELEPORT_MOVEMENT_RESTRICTION constant (should always be between 0f and 1f) to give the effect of charging up the teleport. This movement is called in getModifiedMovement and can be combined with other skills which modify player movement.

if (isTeleporting()) {
    Vector2 reducedMovement = new Vector2(modifiedMovementVector.x * TELEPORT_MOVEMENT_RESTRICTION,
            modifiedMovementVector.y * TELEPORT_MOVEMENT_RESTRICTION);
    modifiedMovementVector = reducedMovement;
}

Checking for Teleport Charging

This allows for external functions to check the skill state of the teleport. Please note: this is only valid assuming the PlayerSkillComponent.update() has been called as this checks for the time stamps of the skill state.

/**
* Checks if the player is in the teleport skill state
* @return true - if the player is charging a teleport
*         false - otherwise
*/
public boolean isTeleporting() {
   return this.teleporting;
}

Calling the Teleport Skill

This function sets all the relevant variables for the skill state. This function was specifically designed to not break functionality on multiple calls even when already in the dash state, however please note this increases the charge time of the teleport before teleporting (this was done using time stamps of the skill end, so if called again the skill state is just updated and the teleport is delayed).

/**
* The functional start of the teleport skill.
* Should be called when player actions component registers teleport event.
*/
public void startTeleport() {
   this.teleporting = true;
   long teleportStart = System.currentTimeMillis();
   this.teleportEnd = teleportStart + TELEPORT_CHARGE_LENGTH;
}

The actual teleport (without charge)

The teleport does not allow the player to clip through walls or out of map bounds. This is achieved by using raycast() to check for collisions on the OBSTACLE physics layer. If a collision is detected then the player teleports just in front of the point where the collision occurred.

The walls on the level 2 map were made with a width of 0.1 which caused a lot of clipping issues and changed the way the function had to work. The raycast start point had to be moved back because the players hitbox can extend over a 0.1 wide wall, which allowed the player to teleport outside the map. The second raycast in the else if statement is only used in certain edge cases where the first raycast still doesn't detect a collision (only happens in left corners).

The function returns without changing the players position if the teleport length is less than 0.75. This is because it looks visually smoother but doesn't actually change how the skill functions.

The teleport is also controlled by the direction the player is facing at the time of teleport call, so during the charge, the player has an opportunity to adjust their direction before teleporting.

...
Vector2 from = new Vector2(playerEntity.getPosition().x - walkDirection.x * 0.2f,
        playerEntity.getPosition().y - walkDirection.y * 0.2f);
Vector2 fromCenter = playerEntity.getCenterPosition();
Vector2 fromCenterEdges = new Vector2(fromCenter.x - walkDirection.x * 0.2f,
        fromCenter.y - walkDirection.y * 0.2f);
Vector2 to = new Vector2(teleportPositionX, teleportPositionY);

if (physics.raycast(from, to, PhysicsLayer.OBSTACLE, hit)) {
    if (Math.abs(hit.point.x - fromCenter.x) < 0.75f && Math.abs(hit.point.y - fromCenter.y) < 0.75f) {
        return;
    }
    playerEntity.setPosition(hit.point.x - walkDirection.x, hit.point.y - walkDirection.y);
} else if (walkDirection.x == 0 && physics.raycast(fromCenterEdges, to, PhysicsLayer.OBSTACLE, hit)) {
    playerEntity.setPosition(hit.point.x - walkDirection.x, hit.point.y - walkDirection.y);
} else {
    playerEntity.setPosition(to);
}