Menu
CoddyTech

Stoß dir den Kopf

Teil des Abschnitts Spielwelten der Pygame-Journey von Coddy. Lektion 17 von 35.

Springe unter eine Plattform, und die Spielfigur bewegt sich durch sie hindurch nach oben und landet dann oben darauf. Eine feste Plattform sollte den Kopf aufhalten. Beim Aufwärtsbewegen ist vel_y negativ, also füge den anderen Fall zur vertikalen Schleife hinzu:

vel_y = min(vel_y + GRAVITY, MAX_FALL)
player.y += vel_y
on_ground = False
for wall in walls:
    if player.colliderect(wall):
        if vel_y > 0:
            player.bottom = wall.top
            on_ground = True
        elif vel_y < 0:
            player.top = wall.bottom
        vel_y = 0

Der Kopf wird an die Unterkante der Wand gesetzt, und die Geschwindigkeit wird in beiden Fällen auf 0 gesetzt. Nach einem Aufprall setzt die Schwerkraft sofort den Fall in Gang. Ohne vel_y = 0 versucht die Spielfigur weiterhin, sich nach oben zu bewegen, und bleibt unter der Plattform hängen, bis die Schwerkraft den Sprung aufgebraucht hat.

Das Vorzeichen von vel_y gibt an, von welcher Seite die Spielfigur kam, so wie es dx bei Wänden tat: Beim Fallen traf sie auf die Oberkante der Wand, beim Steigen auf ihre Unterkante.

challenge icon

Aufgabe

Einfach
  1. Füge in der Schleife für vertikale Kollisionen den Fall vel_y < 0 hinzu: player.top = wall.bottom.
  2. Setze vel_y = 0 nach beiden Fällen, damit ein Anstoßen den Aufstieg stoppt.

Die Spielfigur startet unter einer Plattform; springe, um es auszuprobieren.

Probier es selbst

import pygame

TILE = 36
SPEED = 4
GRAVITY = 1
JUMP = -15
MAX_FALL = 12

LEVEL = [
    "................",
    "................",
    "................",
    "..........###...",
    "................",
    "................",
    "...#####........",
    "............#...",
    "#....P......#..#",
    "################",
]

pygame.init()
screen = pygame.display.set_mode((576, 360))
pygame.display.set_caption("Head Bump")
clock = pygame.time.Clock()

background = pygame.image.load("assets/backgrounds/clouds.png").convert_alpha()
block_img = pygame.image.load("assets/images/block.png").convert_alpha()
player_img = pygame.image.load("assets/images/player.png").convert_alpha()

walls = []
for row, line in enumerate(LEVEL):
    for col, char in enumerate(line):
        if char == "#":
            walls.append(pygame.Rect(col * TILE, row * TILE, TILE, TILE))
        elif char == "P":
            start = (col * TILE + TILE // 2, row * TILE + TILE)

player = player_img.get_rect(midbottom=start)
vel_y = 0
on_ground = False

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 in (pygame.K_SPACE, pygame.K_UP):
            if on_ground:
                vel_y = JUMP
        elif event.type == pygame.KEYUP and event.key in (pygame.K_SPACE, pygame.K_UP):
            if vel_y < -4:
                vel_y = -4

    keys = pygame.key.get_pressed()
    dx = 0
    if keys[pygame.K_LEFT]:
        dx -= SPEED
    if keys[pygame.K_RIGHT]:
        dx += SPEED

    player.x += dx
    for wall in walls:
        if player.colliderect(wall):
            if dx > 0:
                player.right = wall.left
            elif dx < 0:
                player.left = wall.right

    vel_y = min(vel_y + GRAVITY, MAX_FALL)
    player.y += vel_y
    on_ground = False
    for wall in walls:
        if player.colliderect(wall):
            if vel_y > 0:
                player.bottom = wall.top
                vel_y = 0
                on_ground = True

    for y in range(0, 360, 72):
        for x in range(0, 576, 72):
            screen.blit(background, (x, y))
    for wall in walls:
        screen.blit(block_img, wall)
    screen.blit(player_img, player)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Alle Lektionen in Spielwelten

Übe selbstständig: Pygame-Playground