Menu
CoddyTech

Her Kare Hızında Akıcı Hareket

Coddy'nin Pygame Journey'sinin Ses ve Oyun Hissi bölümünün bir parçası. Ders 19 / 23.

x += (target_x - x) * 0.1, her karede yolun onda birini alır. Saniyede 60 karede bu, saniyede 60 adım demektir; yalnızca 30 kareyi başarabilen yavaş bir bilgisayarda ise 30 adım olur ve dairenin varması iki kat uzun sürer. Görmek için F'ye bas: oyun 30 kare hızında çalışır ve her şey daha yavaş yumuşar.

Çözüm, zamanı ölçmektir. clock.tick(), son kareden bu yana geçen milisaniyeleri döndürür. 1000'e bölündüğünde bu, karenin saniye cinsinden süresi olan dt'yi verir: saniyede 60 karede yaklaşık 0.017, 30 karede 0.033.

dt = 1 / 60          # döngüden önce
...
step = min(1, 6 * dt)
x += (target_x - x) * step
...
dt = clock.tick(fps) / 1000

Daha uzun bir kare daha büyük bir adım atar; böylece daire, kare hızı ne olursa olsun aynı sürede aynı mesafeyi kat eder. 6 değeri hızı belirler: saniyede 60 karede 6 * dt yaklaşık 0.1 olur; yani öncekiyle aynı onda birdir. min(1, ...), çok uzun bir karenin hedefi aşmasını engeller.

Aynı şey normal hareket için de geçerlidir: player_x += 240 * dt, kare hızı ne olursa olsun saniyede 240 pikseldir. Küçük oyunların çoğu hızlarını tick(60) ile sabitler ve buna hiç ihtiyaç duymaz; hız değişebiliyorsa dt kullan.

challenge icon

Görev

Orta

F, oyunu saniyede 60 ile 30 kare arasında değiştirir. Yumuşatmanın her iki hızda da aynı süreyi almasını sağla:

  1. Döngüden önce dt = 1 / 60 ayarla.
  2. Döngünün sonunda dt = clock.tick(fps) / 1000 ayarla.
  3. 0.1 yerine step = min(1, 6 * dt) ile hareket et: x += (target_x - x) * step ve y için de aynısını yap.

Kendin dene

import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Any Frame Rate")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 28)

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

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
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_f:
            fps = 30 if fps == 60 else 60

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

    screen.fill((30, 30, 46))
    pygame.draw.circle(screen, (80, 200, 220), (x, y), 12)
    label = font.render(f"{fps} FPS (F to change)", True, (240, 240, 240))
    screen.blit(label, (10, 10))
    pygame.display.flip()
    clock.tick(fps)

pygame.quit()
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Ses ve Oyun Hissi bölümündeki tüm dersler

Kendi başına pratik yap: Pygame playground