2

I have an array of "food" and I have a for loop that gets the x and y of that food. The food is just a red dot that is placed randomly in the window. Having x and y, how do I move my circle to those coordinates with a certain speed?

pygame.draw.circle(win, (0, 255, 0), (round(x), round(y)), radius)
index = 0
for index in food_list:
    food_x, food_y = index[0], index[1]
    distance_x, distance_y = food_x - x, food_y - y
    stepx, stepy = distance_x * speed, distance_y * speed
    x = x + stepx
    y = y + stepy

With this code, my circle moves to the first food item nicely but only goes half way to the second one, and it keeps moving less and less until it doesn't move at all. Also, the circle starts slowing down when it almost reaches its food which I do not want.

tonypdmtr
  • 3,037
  • 2
  • 17
  • 29
Felix
  • 31
  • 4

1 Answers1

1

You have to calculate the Unit vector from the circle in the direction of the food (the length of a unit vector is 1). Scale the unit vector by the speed and add the result to the coordinate of the circle.
In pygame you can use pygame.math.Vector2 for the vector calculations, .normalize() calculates the unit vector:

p_food = pygame.math.Vector2(index[0], index[1])
p_circle = pygame.math.Vector2(x, y)
unit_dir = (p_food - p_circle).normalize()

x += unit_dir.x * speed
y += unit_dir.y * speed

Of course this can be simplified:

x, y = (pygame.math.Vector2(index) - (x, y)).normalize() * speed + (x, y)

If you want to step from on food to the next, then you can't do it in a loop like this, but you can step the the foods in the list one after the other. Use a index (food_i) to identify the next object of food_list to move to. Increment the index, when the food is reached:

Initialize the index of the next food before the main loop of the program:

food_i = 0

Compute the distance from the center of the circle to the food by .distance_to() in the application loop:

p_food = pygame.math.Vector2(food_list[food_i])
dist = p_food.distance_to((x, y))

Move the circle one step to the food. Ensure that the circle does not step over the food by computing the minimum of the remaining distance and the distance of one step (min(dist, speed)):

if dist > 0:
    x, y = (p_food - (x, y)).normalize() * min(dist, speed) + (x, y)

Switch to the next food, if the food is reached:

if dist < speed and food_i < len(food_list)-1:
    food_i += 1
Rabbid76
  • 202,892
  • 27
  • 131
  • 174