Menu
CoddyTech

画面揺れ

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

重い木箱が地面に当たると、画面全体が一瞬揺れます。これが画面揺れです。数フレームの間、すべてが数ピクセルずれた位置に、フレームごとに異なる形で描画されます。

すべてを一度に動かすには、画面ではなく専用の Surface にワールドを描画し、その Surface をオフセット位置に画面へ blit します。

world = pygame.Surface((480, 360))

ループ内では、screenを使っていた描画呼び出しをworldに変更します。次にオフセットを決めます。

offset = (0, 0)
if shake > 0:
    amount = shake // 3
    offset = (random.randint(-amount, amount), random.randint(-amount, amount))
    shake -= 1
screen.fill((0, 0, 0))
screen.blit(world, offset)

shakeは揺れが残っているフレーム数を数えます。着地時に12に設定します。amountはshake // 3なので、最初のフレームでは最大4ピクセル動き、その後3、2、1と減っていき、最後には動かなくなります。揺れは突然止まるのではなく、徐々に弱まります。ワールドを4ピクセル動かすと細い帯状の部分が覆われずに残るため、まず画面を黒く塗りつぶします。

challenge icon

チャレンジ

中級

スペースキーを押すと木箱が落ち、着地するとshake = 12が設定されますが、まだ何にも使われていません。画面を揺らしましょう。

  1. ループの前に、world = pygame.Surface((480, 360))を作成します。
  2. 背景、地面、支柱、木箱は、screenではなくworldに描画します。
  3. shakeが0より大きい間、xとyそれぞれについてamount = shake // 3とrandom.randint(-amount, amount)を使ってオフセットを選び、その後shakeを1減らします。
  4. 画面を黒で塗りつぶし、オフセット位置にworldをblitします。

自分で試してみよう

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Crate Drop")
clock = pygame.time.Clock()

thud_sound = pygame.mixer.Sound("assets/sounds/thud.ogg")
falling = []
landed = []
shake = 0

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
            falling.append(pygame.Rect(random.randint(140, 400), -40, 40, 40))

    for crate in falling:
        crate.y += 8
        if crate.bottom >= 300:
            crate.bottom = 300
            landed.append(crate)
            thud_sound.play()
            shake = 12
    falling = [crate for crate in falling if crate.bottom < 300]

    screen.fill((30, 30, 46))
    pygame.draw.rect(screen, (80, 80, 100), (0, 300, 480, 60))
    pygame.draw.rect(screen, (80, 160, 255), (60, 220, 30, 80))
    for crate in falling + landed:
        pygame.draw.rect(screen, (170, 110, 60), crate)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

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

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