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
Enemy Sprite/Object needs to be created with variable: orbitAngle
Player Sprite/Object needs to be created.
Solution contains one normal event, one javascript event.
Calculations went into math and use force vectors.
It keeps enemies rotating while trying to hold a orbit 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 enemy would exceed his speed limits.
Its lines with if (distanced > 2.87) that cap the maximum speed of the enemy when orbiting.
The following events can be copy&Pasted. Hope some of you find this useful.
{"000kind":"GDEVELOP_EventsAndInstructions_CLIPBOARD_KIND-jsBdHbLy912y8Rc","content":{"eventsList":[{"type":"BuiltinCommonInstructions::ForEach","object":"Enemy","conditions":[{"type":{"inverted":true,"value":"Distance"},"parameters":["Enemy","Player","194",""]}],"actions":[{"type":{"value":"AddForceVersPos"},"parameters":["Enemy","Player.X()","Player.Y()","90","0"]}]},{"type":"BuiltinCommonInstructions::JsCode","inlineCode":["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.01385;","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 > 2.87) {"," var scaleFactor = 2.87 / 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);"," }","});",""],"parameterObjects":"","useStrict":true,"eventsSheetExpanded":false}],"eventsCount":2,"actionsList":[],"actionsCount":0,"conditionsList":[],"conditionsCount":0}}