Auf ein Ziel zubewegen
Teil des Abschnitts Sound und Spielgefühl der Pygame-Journey von Coddy. Lektion 16 von 23.
Klicke, und der Kreis teleportiert sich dorthin. Etwas, das an seinen Platz gleitet, sieht besser aus: zuerst schnell, dann langsamer, bis es sanft an seinem Platz ankommt. Eine Zeile erledigt das. Bewege in jedem Frame einen Bruchteil der verbleibenden Strecke:
x += (target_x - x) * 0.1
y += (target_y - y) * 0.1target_x - x gibt an, wie weit es noch ist. Wenn man ein Zehntel davon zurücklegt, sind das im ersten Frame 20 Pixel einer Strecke von 200 Pixeln. Im nächsten Frame sind noch 180 Pixel übrig, also bewegt sich der Kreis 18, dann 16.2 und so weiter. Die Schritte werden kleiner, je näher der Kreis kommt: Er wird sanft abgebremst, statt abrupt anzuhalten.
Das wird oft lerp genannt, eine Kurzform für lineare Interpolation. Der Bruchteil bestimmt das Gefühl: 0.1 ist gleichmäßig, 0.3 ist flott, 0.02 ist langsam und schwebend. Der Kreis kommt nie genau am Ziel an, aber nach einer Sekunde ist er weniger als ein Pixel davon entfernt, was niemand sehen kann.
Speichere x und y als Dezimalzahlen in eigenen Variablen. Ein Rect speichert ganze Zahlen, daher würde ein Schritt von 0.4 Pixeln auf 0 abgerundet, und die Bewegung käme vor dem Ziel zum Stillstand.
Aufgabe
EinfachDer Kreis springt zu jedem Klick. Lass ihn gleiten: Ersetze x = target_x und y = target_y durch Zeilen, die x und y in jedem Frame ein Zehntel des Weges zum Ziel bewegen.
Probier es selbst
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()
Alle Lektionen in Sound und Spielgefühl
5Flüssige Bewegung
Auf ein Ziel zubewegenEine flüssige KamerabewegungBeim Aufsammeln aufspringenBei jeder Bildrate flüssigÜbe selbstständig: Pygame-Playground