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.
Aufgabe
MittelMit der Leertaste wird eine Kiste fallen gelassen, und bei ihrer Landung wird shake = 12 gesetzt, was bisher noch nichts bewirkt. Lass die Ansicht wackeln:
- Erstelle vor der Schleife
world = pygame.Surface((480, 360)). - Zeichne den Hintergrund, den Boden, den Pfosten und die Kisten auf
worldstatt aufscreen. - Solange
shakegrößer als 0 ist, wähle mitamount = shake // 3undrandom.randint(-amount, amount)einen Versatz für x und y und verringere anschließendshakeum 1. - Fülle den Bildschirm schwarz und blitte
worldan 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