How do i go about having my sprite move around a point at a specific speed

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Mi1k

I’m making a little space shooter/bullet hell type game and am now constructing the movement AI for the 1st enemy. They are supposed to rotate around the player for a few seconds and then move in for a burst rush towards the player.
I have the burst movement working, but I have no clue as to how I would go about having the enemy move in a circular motion around the target body.

This is my code for the movement so far:

extends "res://MOB.gd"

onready var parent = get_parent()
var is_moving = false
export (float) var turn_speed
export (int) var detect_radius
export (int) var spd
export (int) var dmg
export (int) var burst

var target = null
var is_atborder = false
var switch = false
var def = true

func _ready():
   burst = 0
   $Wait.wait_time = 2
   $Detection/CollisionShape2D.shape.radius = detect_radius

 func control(delta):
   moving()
   if target and def:
	default_move()
   chase_move()

func moving():
   if is_moving == true:
       	$AnimatedSprite.play("movement")
  else:
	$AnimatedSprite.play("default")

func _on_Detection_body_entered(body):
     	if can_target:
        	target = body

func _on_Detection_body_shape_exited(body_id, body, body_shape, area_shape):
       if body == target:
	        target = null

func default_move():
      look_at(target.position)
      #position = target.position + (position - target.position).rotated(90)

func chase_move():
   	    if target and can_target:
	     def = false
	      is_moving = true
	      var dir = global_position.direction_to(target.global_position)
	      velocity = Vector2(speed, speed) * dir
	      can_target = false
	      burst += burst
	      $Timer.start()
	      if burst % 3 == 0:
		    $Wait.start()

 func _on_Timer_timeout():
     can_target = true


 func _on_Wait_timeout():
      def =true
:bust_in_silhouette: Reply From: rustyStriker

This will be long, Movement in video games is simply teleporting the sprite like 60 times a second small amounts to make it look like its moving, so for a straight line its simple, just teleport the sprite speed / 60(equals to speed * delta) in the movement direction, yet for a rotation object ( that goes around a point ) things get a bit problematic.
First, you have the introduction of angular momentum and angular speed, basically what angle he moves every second, and of course you need to have a middle point.
Physically speaking when an object goes around a center point in a fixed velocity, his acceleration is towards the middle of the circle(really interesting go check it out).

BUT

since we just teleport it every time using the physics equations wont result in a good visual, what you can in fact do is have angular speed ( what angle he covers every second ) and the center point ( the player for you ), so you can predict at which angle he will be in the next frame ( equals to angular_speed * delta) and multiply the unit vector that comes out from the new angle in the radius.
** unit vector is a vector which length is exactly 1 and is calculated using the cos and sin functions

Hope it helps, sorry for the long explanation

:bust_in_silhouette: Reply From: njamster

Something like this?

onready var target = get_node("<PathToPlayer>")
var radius = Vector2(100, 0)

func _physics_process(delta):
	# 1 full circle (i.e. 2 * PI) every second, clockwise
	radius = radius.rotated(2 * PI * delta)

	# 1 full circle (i.e. 2 * PI) every 4 seconds, counter-clockwise
	# radius = radius.rotated(2 * PI * delta * -0.25)

	global_position = target.global_position + radius

However, It might look weird (and not really circular) if the player is moving too fast.