Menu
CoddyTech

Следовать за игроком

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

Плывущая камера оставляет игрока позади. Вместо этого каждый кадр устанавливай положение камеры относительно игрока после того, как тот переместился:

camera_x = player.centerx - WIDTH // 2

Середина окна — это WIDTH // 2, то есть 288 пикселей от его левого края. Когда камера находится на 288 пикселей левее центра игрока, игрок отображается посередине окна. Иди вправо — и уровень будет сдвигаться влево под игроком, который остаётся на месте на экране.

Устанавливай положение камеры после обработки столкновений, чтобы она учитывала, где игрок оказался в этом кадре, а не где он был до этого. В начале в окне видно пустое пространство слева от уровня: это исправит следующий урок.

challenge icon

Задание

Легко
  1. Устраните смещение.
  2. После обработки столкновений каждый кадр задавайте camera_x = player.centerx - WIDTH // 2.

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

import pygame

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

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

pygame.init()
screen = pygame.display.set_mode((WIDTH, 360))
pygame.display.set_caption("Camera")
clock = pygame.time.Clock()

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)

level_width = len(LEVEL[0]) * TILE
player = player_img.get_rect(midbottom=start)
vel_y = 0
on_ground = False
camera_x = 0

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
                on_ground = True
            elif vel_y < 0:
                player.top = wall.bottom
            vel_y = 0

    if camera_x < level_width - WIDTH:
        camera_x += 2

    screen.fill((140, 200, 240))
    for wall in walls:
        screen.blit(block_img, (wall.x - camera_x, wall.y))
    screen.blit(player_img, (player.x - camera_x, player.y))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

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

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