Menu
CoddyTech

Стены слева и справа

Часть раздела Игровые миры путешествия по Pygame на Coddy. Урок 15 из 35.

Блоки нарисованы, но игрок проходит сквозь них. Стена должна останавливать игрока. Сначала переместите его, затем исправьте перемещение: если теперь игрок пересекается со стеной, вытолкните его обратно с той стороны, откуда он пришёл.

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 — это боковое перемещение за текущий кадр: положительное значение означает движение вправо. Двигаясь вправо, игрок ударился о левую сторону стены, поэтому его правый край устанавливается на эту сторону. Двигаясь влево, он устанавливается левым краем к правой стороне стены.

Карта встроена в walls — список Rects, так же, как в разделе «Карты из текста». Полом по-прежнему служит линия на уровне FLOOR, и игрок всё ещё может упасть на верхнюю часть блока: следующим шагом будет приземление на стены.

challenge icon

Задание

Средне
  1. После player.x += dx пройдись циклом по walls.
  2. Для каждой стены, с которой сталкивается игрок: если dx > 0, установи player.right = wall.left; если dx < 0, установи player.left = wall.right.

Попробуйте сами

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()

Все уроки раздела Игровые миры

Потренируйтесь самостоятельно: Песочница Pygame