Menu
CoddyTech

Moverse hacia un objetivo

Parte de la sección Sonido y sensaciones del juego del Journey de Pygame de Coddy. Lección 16 de 23.

Haz clic y el círculo se teletransporta allí. Algo que se desliza hasta su posición queda mejor: rápido al principio, después más lento, asentándose suavemente en su lugar. Una línea lo consigue. En cada fotograma, recorre una fracción de la distancia que queda:

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

target_x - x es la distancia que falta por recorrer. Al avanzar una décima parte, se recorren 20 píxeles de un trayecto de 200 píxeles en el primer fotograma. En el siguiente fotograma quedan 180 píxeles, así que avanza 18, después 16.2, y así sucesivamente. Los pasos se acortan a medida que el círculo se acerca: se desacelera al llegar, en lugar de detenerse en seco.

A esto se le suele llamar lerp, abreviatura de interpolación lineal. La fracción determina la sensación: 0.1 es suave, 0.3 es ágil, 0.02 es lento y flotante. Nunca llega exactamente al objetivo, pero después de un segundo está a menos de un píxel, algo que nadie puede ver.

Mantén x y y como números decimales en sus propias variables. Un Rect almacena números enteros, así que un paso de 0.4 píxeles se truncaría a 0 y el movimiento se detendría antes de alcanzar el objetivo.

challenge icon

Desafío

Fácil

El círculo salta a cada clic. Haz que se deslice: reemplaza x = target_x y y = target_y por líneas que muevan x y y una décima parte del camino hacia el objetivo en cada fotograma.

Pruébalo tú mismo

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

Todas las lecciones de Sonido y sensaciones del juego

Practica por tu cuenta: Playground de Pygame