Eine Achse nach der anderen
Teil des Abschnitts Spielwelten der Pygame-Journey von Coddy. Lektion 19 von 35.
Dein Kollisionscode bewegt und korrigiert zuerst x und dann y. Dieser Ausgangscode bewegt beide Achsen und korrigiert nur einmal. Führe ihn aus und gehe nach rechts: Der Spieler wird auf dem Boden rückwärts versetzt.
player.x += dx
vel_y = min(vel_y + GRAVITY, MAX_FALL)
player.y += vel_y
on_ground = False
for wall in walls:
if player.colliderect(wall):
if dx > 0:
player.right = wall.left
elif dx < 0:
player.left = wall.right
if vel_y > 0:
player.bottom = wall.top
on_ground = True
elif vel_y < 0:
player.top = wall.bottom
vel_y = 0Wenn der Spieler auf dem Boden steht, bewegt die Schwerkraft ihn in jedem Frame 1 Pixel nach unten in den Boden. Bewegt er sich im selben Frame nach rechts, überlappt der Spieler die Bodenkachel unter ihm, und der Code kann nicht erkennen, warum. Er sieht dx > 0 und setzt die rechte Seite des Spielers an die linke Seite dieser Kachel: rückwärts, entlang des Bodens.
Eine Überlappung, zwei Bewegungen, keine Möglichkeit zu erkennen, welche Bewegung sie verursacht hat. Bewegt man jeweils nur eine Achse, hat jede Überlappung eine einzige Ursache. Nach der Bewegung entlang der x-Achse ist der Spieler noch nicht im Boden, sodass ihn nur echte Wände aufhalten. Nach der Bewegung entlang der y-Achse kann die Überlappung nur durch die Bewegung entlang der y-Achse entstehen.
Aufgabe
Mittel- Teile die Bewegung auf:
player.x += dxund eine Schleife überwalls, die nur x korrigiert. - Dann die Schwerkraft,
player.y += vel_y,on_ground = Falseund eine zweite Schleife, die nur y korrigiert.
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("One Axis at a Time")
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
vel_y = min(vel_y + GRAVITY, MAX_FALL)
player.y += vel_y
on_ground = False
for wall in walls:
if player.colliderect(wall):
if dx > 0:
player.right = wall.left
elif dx < 0:
player.left = wall.right
if vel_y > 0:
player.bottom = wall.top
on_ground = True
elif vel_y < 0:
player.top = wall.bottom
vel_y = 0
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
1Karten aus Text
Ein Level in TextformZeilen und SpaltenBuchstaben mit BedeutungWo der Spieler startetEin Bildschirm nach dem anderen4Kollisionen mit Plattformen
Wände links und rechtsAuf Plattformen landenStoß dir den KopfAus dem Level fallenEine Achse nach der anderen3Schwerkraft und Springen
Fallen mit SchwerkraftVom Boden springenKurze SprüngeEine maximale FallgeschwindigkeitSprungpuffer6Patrouillierende Gegner
Ein patrouillierender BlobDrauftreten oder getroffen werdenEin GehzyklusGegner aus der KarteÜbe selbstständig: Pygame-Playground