Walls Left and Right
Part of the Worlds section of Coddy's Pygame journey. Lesson 15 of 35.
The blocks are drawn, but the player walks through them. A wall must stop the player. Move first, then fix the move: if the player now overlaps a wall, push it back out on the side it came from.
player.x += dx
for wall in walls:
if player.colliderect(wall):
if dx > 0:
player.right = wall.left
elif dx < 0:
player.left = wall.rightdx is this frame's sideways move: positive to the right. Moving right, the player hit the wall's left side, so its right edge goes there. Moving left, its left edge goes to the wall's right side.
The map is built into walls, a list of Rects, the same way as in Maps from Text. The floor is still the line at FLOOR, and the player can still fall into the top of a block: landing on walls comes next.
Challenge
Medium- After
player.x += dx, loop overwalls. - For each wall the player collides with: when
dx > 0, setplayer.right = wall.left; whendx < 0, setplayer.left = wall.right.
Try it yourself
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()
All lessons in Worlds
1Maps from Text
A Level in TextRows and ColumnsLetters With MeaningsWhere the Player StartsOne Screen at a Time4Platform Collisions
Walls Left and RightLanding on PlatformsBump Your HeadFalling Out of the LevelOne Axis at a Time3Gravity and Jumping
Falling With GravityJump From the GroundShort HopsA Top Falling SpeedJump BufferPractice on your own: Pygame playground