Menu
CoddyTech

화면 흔들림

Coddy Pygame 여정의 사운드와 게임의 손맛 섹션에 포함된 레슨. 23개 중 12번째.

무거운 상자가 바닥에 부딪히면 화면 전체가 잠시 흔들립니다. 이것이 바로 화면 흔들림입니다. 몇 프레임 동안 모든 요소가 프레임마다 조금씩 다른 방향으로 몇 픽셀씩 어긋나 그려집니다.

모든 요소를 한꺼번에 움직이려면 화면에 직접 그리는 대신 별도의 Surface에 월드 전체를 그린 다음, 오프셋을 적용해 그 Surface를 화면에 블리트합니다.

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보다 큰 동안 amount = shake // 3과 x 및 y에 대한 random.randint(-amount, amount)를 사용해 오프셋을 정한 다음, shake를 1 줄입니다.
  4. 화면을 검은색으로 채우고 오프셋 위치에 world를 블릿합니다.

직접 해보기

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 플레이그라운드