Enemy orbiting the player at a distance

How do I…

Enemy that orbits the player at a distance and tries to keep the distance.

I have done a small showcase video https://youtu.be/8pEg3Zhk3tc

Implementation Details

Enemys need the object variable: orbitAngle

I came up with two code blocks.
One normal event:
grafik

One javascript event, as the calculations went into math.
This block keeps enemies rotating and trying to hold a distance to the player, if he moves. The second part was tricky, as we need to calculate target points and reduce the movement vector of the enemy, if the “distance would be too far”. As the enemy would exeed his speed limits.

Its lines with if (distanced > 1.77) that cap the maximum speed of the enemy when orbiting.


var player = runtimeScene.getObjects(“Player”)[0];
var playerX = player.getX();
var playerY = player.getY();

var enemies = runtimeScene.getObjects(‘Enemy’);
const ORBIT_RADIUS = 190;
const ROTATION_SPEED = 0.0085;
const ACTIVATION_DISTANCE = 196;

enemies.forEach(enemy => {
let vars = enemy.getVariables();
let angleVar = vars.get(“orbitAngle”);
var enemyX = enemy.getX();
var enemyY = enemy.getY();

const dx = enemyX - playerX;
const dy = enemyY - playerY;
const distance = Math.sqrt(dx * dx + dy * dy);

if (distance < ACTIVATION_DISTANCE) {
    // Initialize angle if not set
    if (angleVar.getAsNumber() === 0) {
        angleVar.setNumber(Math.atan2(dy, dx));
    }

    // Update rotation
    const currentAngle = angleVar.getAsNumber();
    angleVar.setNumber(currentAngle + ROTATION_SPEED);

    // Calculate desired new position
    var targetX = playerX + Math.cos(angleVar.getAsNumber()) * ORBIT_RADIUS;
    var targetY = playerY + Math.sin(angleVar.getAsNumber()) * ORBIT_RADIUS;

    // Calculate vector components
    var ndx = targetX - enemyX;
    var ndy = targetY - enemyY;

    // Calculate actual distance
    var distanced = Math.sqrt(ndx * ndx + ndy * ndy);
    runtimeScene.getGame().getVariables().get("distancet").setNumber(distanced);

    if (distanced > 1.77) {
        var scaleFactor = 1.77 / distanced;
        targetX = enemyX + ndx * scaleFactor;
        targetY = enemyY + ndy * scaleFactor;
    }

    // Apply final position
    enemy.setX(targetX);
    enemy.setY(targetY);
} else {
    // Reset angle when out of range for fresh calculation next activation
    angleVar.setNumber(0);
}

});

Could you have made use of the “Put Enemy around Player...” action? Or am I missing something here?

That was also my initial idea
But then i watched video he linked and that looks more like mix between put object around another and boids behavior
And idk how to do it with boids

My most stupid idea would be to push enemies away if they are too close to player and pull them if they are in some range
And between too close and too far keep some range where they orbit
But i assumed it would look way too robotic to suggest it