Menu
CoddyTech

Bildschirmwackeln

Teil des Abschnitts Sound und Spielgefühl der Pygame-Journey von Coddy. Lektion 12 von 23.

Eine schwere Kiste schlägt auf dem Boden auf und die ganze Ansicht ruckelt einen Moment lang. Das ist Bildschirmerschütterung: Für ein paar Frames wird alles um einige Pixel versetzt gezeichnet, und zwar in jedem Frame anders.

Um alles auf einmal zu bewegen, zeichne die Welt auf eine eigene Surface statt auf den Bildschirm und blitte diese Surface dann mit einem Versatz auf den Bildschirm:

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

Verwende in der Schleife für die Zeichenaufrufe, die bisher screen verwendet haben, nun world. Wähle dann den Versatz:

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 zählt die verbleibenden Frames der Erschütterung. Bei einer Landung wird der Wert auf 12 gesetzt. Da amount shake // 3 entspricht, verschiebt sich das Bild in den ersten Frames um bis zu 4 Pixel, dann um 3, 2, 1 und schließlich gar nicht mehr: Der Ruck klingt ab, statt abrupt aufzuhören. Fülle den Bildschirm zuerst mit Schwarz, da eine um 4 Pixel verschobene Welt einen schmalen Streifen unbedeckt lässt.

challenge icon

Aufgabe

Mittel

Mit der Leertaste wird eine Kiste fallen gelassen, und bei ihrer Landung wird shake = 12 gesetzt, was bisher noch nichts bewirkt. Lass die Ansicht wackeln:

  1. Erstelle vor der Schleife world = pygame.Surface((480, 360)).
  2. Zeichne den Hintergrund, den Boden, den Pfosten und die Kisten auf world statt auf screen.
  3. Solange shake größer als 0 ist, wähle mit amount = shake // 3 und random.randint(-amount, amount) einen Versatz für x und y und verringere anschließend shake um 1.
  4. Fülle den Bildschirm schwarz und blitte world an der Versatzposition.

Probier es selbst

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()

Alle Lektionen in Sound und Spielgefühl

Übe selbstständig: Pygame-Playground