Menu
CoddyTech

Paredes a izquierda y derecha

Parte de la sección Mundos del Journey de Pygame de Coddy. Lección 15 de 35.

Los bloques se dibujan, pero el jugador los atraviesa. Una pared debe detener al jugador. Primero muévelo y después corrige el movimiento: si el jugador ahora se superpone con una pared, empújalo hacia afuera por el lado por el que llegó.

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

dx es el desplazamiento lateral de este fotograma: positivo hacia la derecha. Al moverse hacia la derecha, el jugador chocó con el lado izquierdo de la pared, así que su borde derecho queda allí. Al moverse hacia la izquierda, su borde izquierdo queda en el lado derecho de la pared.

El mapa está integrado en walls, una lista de Rects, igual que en Maps from Text. El suelo sigue siendo la línea en FLOOR, y el jugador todavía puede caer sobre la parte superior de un bloque: lo siguiente será aterrizar sobre las paredes.

challenge icon

Desafío

Intermedio
  1. Después de player.x += dx, recorre walls.
  2. Por cada pared con la que choque el jugador: cuando dx > 0, establece player.right = wall.left; cuando dx < 0, establece player.left = wall.right.

Pruébalo tú mismo

import pygame

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

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

pygame.init()
screen = pygame.display.set_mode((576, 360))
pygame.display.set_caption("Walls")
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
    if player.bottom > FLOOR:
        player.bottom = FLOOR
        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()

Todas las lecciones de Mundos

Practica por tu cuenta: Playground de Pygame