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()