Menu
CoddyTech

Move Toward a Target

Part of the Sound and Game Feel section of Coddy's Pygame journey. Lesson 16 of 23.

Click and the circle teleports there. A thing that slides into place looks better: fast at first, then slower, settling gently on its spot. One line does that. Each frame, move a fraction of the distance that is left:

x += (target_x - x) * 0.1
y += (target_y - y) * 0.1

target_x - x is how far there is to go. Moving a tenth of it covers 20 pixels of a 200 pixel trip in the first frame. The next frame there are 180 pixels left, so it moves 18, then 16.2, and so on. The steps shrink as the circle gets close: it eases in instead of stopping dead.

This is often called lerp, short for linear interpolation. The fraction sets the feel: 0.1 is smooth, 0.3 is snappy, 0.02 is slow and floaty. It never lands exactly on the target, but after a second it is less than a pixel away, which nobody can see.

Keep x and y as decimal numbers in their own variables. A Rect stores whole numbers, so a step of 0.4 pixels would be cut to 0 and the move would stall short of its target.

challenge icon

Challenge

Easy

The circle jumps to every click. Make it glide: replace x = target_x and y = target_y with lines that move x and y a tenth of the way to the target each frame.

Try it yourself

import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Follow the Click")
clock = pygame.time.Clock()

x, y = 240, 180
target_x, target_y = 240, 180

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            target_x, target_y = event.pos

    x = target_x
    y = target_y

    screen.fill((30, 30, 46))
    pygame.draw.line(screen, (90, 90, 110), (target_x - 8, target_y), (target_x + 8, target_y), 2)
    pygame.draw.line(screen, (90, 90, 110), (target_x, target_y - 8), (target_x, target_y + 8), 2)
    pygame.draw.circle(screen, (80, 200, 220), (x, y), 12)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

All lessons in Sound and Game Feel

Practice on your own: Pygame playground