Menu
CoddyTech

どのフレームレートでも滑らかに

CoddyのPygameジャーニー「サウンドとゲームの手応え」セクションの一部。レッスン 19/23。

x += (target_x - x) * 0.1は、1フレームごとに10分の1ずつ移動します。1秒あたり60フレームなら1秒間に60回進みますが、30フレームしか処理できない低速なコンピューターでは30回となり、円が到着するまでに2倍の時間がかかります。Fキーを押して確認してみましょう。ゲームが30フレームで動作し、すべての動きがゆっくりになります。

解決策は、時間を計測することです。clock.tick()は、前のフレームからの経過時間をミリ秒単位で返します。それを1000で割った値がdt、つまりフレームの長さを秒単位で表した値です。1秒あたり60フレームなら約0.017、30フレームなら0.033です。

dt = 1 / 60          # ループの前
...
step = min(1, 6 * dt)
x += (target_x - x) * step
...
dt = clock.tick(fps) / 1000

フレームが長いほどステップが大きくなるため、フレームレートにかかわらず、円は同じ時間で同じ距離を進みます。6は速度を設定します。1秒あたり60フレームの場合、6 * dtは約0.1となり、前と同じ10分の1です。min(1, ...)は、非常に長いフレームで目標を通り過ぎないようにします。

通常の移動も同様です。player_x += 240 * dtなら、フレームレートにかかわらず1秒あたり240ピクセル移動します。小規模なゲームの多くはtick(60)でフレームレートを固定するため、この処理は必要ありません。フレームレートが変化する場合はdtを使いましょう。

challenge icon

チャレンジ

中級

F キーでゲームのフレームレートを 1 秒あたり 60 フレームと 30 フレームの間で切り替えます。どちらの場合も、イージングにかかる時間が同じになるようにします。

  1. ループの前に dt = 1 / 60 を設定します。
  2. ループの最後に dt = clock.tick(fps) / 1000 を設定します。
  3. 0.1 の代わりに step = min(1, 6 * dt) を使って移動させます。x += (target_x - x) * step とし、y も同様にします。

自分で試してみよう

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 icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

サウンドとゲームの手応えのすべてのレッスン

自分で練習してみよう: Pygameプレイグラウンド