Menu
CoddyTech

Gerakan Halus pada Frame Rate Apa Pun

Termasuk bagian Suara dan Sensasi Bermain dalam perjalanan Pygame di Coddy. Pelajaran 19 dari 23.

x += (target_x - x) * 0.1 bergerak sepersepuluh jarak setiap frame. Pada 60 frame per detik, gerakannya 60 langkah per detik. Pada komputer lambat yang hanya mampu mencapai 30 frame, gerakannya 30 langkah, dan lingkaran membutuhkan waktu dua kali lebih lama untuk tiba. Tekan F untuk melihatnya: game berjalan pada 30 frame per detik dan semuanya bergerak lebih lambat.

Solusinya adalah mengukur waktu. clock.tick() menghasilkan jumlah milidetik sejak frame terakhir. Jika dibagi 1000, hasilnya adalah dt, durasi frame dalam detik: sekitar 0.017 pada 60 frame per detik, 0.033 pada 30 frame per detik.

dt = 1 / 60          # sebelum perulangan
...
step = min(1, 6 * dt)
x += (target_x - x) * step
...
dt = clock.tick(fps) / 1000

Frame yang lebih lama menghasilkan langkah yang lebih besar, jadi lingkaran menempuh jarak yang sama dalam waktu yang sama pada frame rate apa pun. Angka 6 menentukan kecepatannya: pada 60 frame per detik, 6 * dt bernilai sekitar 0.1, sama dengan sepersepuluh sebelumnya. min(1, ...) mencegah frame yang sangat lama melangkah melewati target.

Hal yang sama berlaku untuk pergerakan biasa: player_x += 240 * dt berarti 240 piksel per detik, berapa pun frame rate-nya. Kebanyakan game kecil menetapkan frame rate dengan tick(60) dan tidak memerlukan ini. Gunakan dt saat frame rate bisa berubah.

challenge icon

Tantangan

Sedang

F mengalihkan game antara 60 dan 30 frame per detik. Buat gerakan easing berlangsung selama waktu yang sama pada kedua kecepatan:

  1. Buat dt = 1 / 60 sebelum perulangan.
  2. Di akhir perulangan, tetapkan dt = clock.tick(fps) / 1000.
  3. Gerakkan dengan step = min(1, 6 * dt), bukan 0.1: x += (target_x - x) * step, dan lakukan hal yang sama untuk y.

Coba sendiri

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 iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Suara dan Sensasi Bermain

Latihan sendiri: Playground Pygame