Is it possible to implement gradual movement of an object to given coordinates in Pygame?

You have to slight change the position in the application loop.

Define a start position (start), end position (end) and velocity (speed):

start = 10, 10
end = 40, 40
speed = 1

Init the current position. Compute the vector form the current position to the end position (dx, dy) in the application loop and change the current position by the speed in the direction to the target:

pos = start[:]
while run:
    # [...]

    dx = end[0] - pos[0]
    dy = end[1] - pos[1]
    dist = math.sqrt(dx*dx + dy*dy)
    if dist > speed:
        pos = pos[0] + dx*speed/dist, pos[1] + dy*speed/dist

Note, math.hypot computes the Euclidean distance and (dx/dist, dy/dist) is a Unit vector (a unit vector has length 1).

Draw the object at the current position (pos) in every frame:

pygame.draw.rect(win,(0,0,255),(round(pos[0]), round(pos[1]), width, height))

If you have a list of positions:

x = [60, 140, 140, 60]
y = [60, 140, 60,  140]

Then start and end have to be set from the positions in the list. Use a list index current_i to track the current start position. Increment the index, if the object has reached the current target position (end).
See the example:

import pygame
import math

pygame.init()
win = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()

x = [60, 140, 140, 60]
y = [60, 140, 60,  140]

width, height = 10, 10
speed = 1
current_i = 0
pos = x[current_i], y[current_i]

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    start = x[current_i], y[current_i]
    end = x[current_i % len(x)], y[current_i % len(y)], 
    dx = end[0] - pos[0]
    dy = end[1] - pos[1]
    dist = math.hypot(dx, dy)
    if dist > speed:
        pos = pos[0] + dx*speed/dist, pos[1] + dy*speed/dist
    else:
        pos = end[:]
        current_i = current_i + 1 if current_i < len(x)-1 else 0

    win.fill(0)
    pygame.draw.rect(win,(0,0,255),(round(pos[0]), round(pos[1]), width, height))
    pygame.display.flip()

Leave a Comment