I made a code to make the item move towards the closest point on the circle.
Basically, I noticed that if you drew an imaginary line from the center of the circle to the item, the line eventually touches the closest point on the circle.
Since want to find the slope of that line, use arctan(y/x) to find the angle. With the slope, you can then find the x and y coordinates of the point on the circle. This is done by cos(angle)radius and sin(angle)radius.
Now that you have the desired x and y coordinates, simply move the item towards that direction.
Note that since Godot measures x and y from the top left corner, you have to go through weird conversions to make it work with trig:
extends Node2D
var radius = 250
var phase = 0
var speed = 100
var angular_speed = .2
var clockwise = -1 #-1 for clockwise, 1 for counter-clockwise
var x
var y
var angle
var xgoal
var ygoal
var movement
func _ready():
position = Vector2(randf_range(0,get_viewport_rect().size.x),randf_range(0,get_viewport_rect().size.y))
set_xy()
angle = atan2(y, x) #find the angle from the center of the circle to the position
xgoal = radius*cos(angle) #using that angle, find the coordinates of where that would be on the circle
ygoal = radius*sin(angle)
movement = Vector2(xgoal - x, -(ygoal - y)).normalized() #direction the item should travel
func set_xy(): #sets the x and y coordinates, then offsets the values so that (0, 0) is at the center of the screen (instead of the top left ocrner)
x = position.x - get_viewport_rect().size.x/2
y = -(position.y - get_viewport_rect().size.y/2)
Alright, I hope it makes sense and works for you. I also completed the second half of the code.
This part checks if the item is close enough to the edge, then activates the next phase.
In the second phase, the code simply increases the angle slowly, then converts the angle to the coordinates on the circle.
The code should work if you just add it on to the end of the first half:
func _process(delta):
if phase == 0:
phase0(delta)
if phase == 1:
phase1(delta)
func phase0(delta): #moving the item towards the edge of the circle. End this phase once close enough to the edge
position += movement * speed * delta
set_xy() #(next several lines) measuring how far it is from the edge, then go to next phase if it's close enough
var distance = Vector2(xgoal-x, -(ygoal-y)).length()
if distance<5:
phase = 1
func phase1(delta): #circling around after reaching the edge
angle += angular_speed * clockwise * delta #increase the angle slowly
xgoal = radius * cos(angle) #(next several lines) finding and converting the angle to coordinates.
ygoal = -radius * sin(angle)
xgoal += get_viewport_rect().size.x/2
ygoal += get_viewport_rect().size.y/2
position = Vector2(xgoal, ygoal)