Плавная камера
Часть раздела Звук и игровые ощущения путешествия по Pygame на Coddy. Урок 17 из 23.
В этой дорожной игре камера прикреплена к игроку: что бы ни делал игрок, он остаётся в центре экрана, а мир движется под ним. Это работает, но каждый старт и остановка дёргают весь экран.
Пусть камера следует за игроком с тем же сглаживанием, что и круг. Цель камеры — позиция, в которой игрок окажется в центре:
camera_x += (player.centerx - 240 - camera_x) * 0.1
camera_x = max(0, min(camera_x, WORLD_WIDTH - 480))Игрок движется как и раньше; сглаживается только изображение. Когда игрок начинает бежать, камера немного отстаёт, поэтому игрок убегает вперёд от центра. Когда он останавливается, камера плавно догоняет его, и игрок снова оказывается посередине. Вторая строка по-прежнему удерживает камеру в пределах мира.
Мир отрисовывается в позиции -int(camera_x), как и раньше. Теперь camera_x — десятичное число; int() обеспечивает отрисовку по целым пикселям, а переменная сохраняет точное значение для следующего кадра.
Выезжающая панель меню, убывающая шкала здоровья, увеличивающийся счёт: сглаживать таким же образом можно всё, что меняется на новое значение.
Задание
СреднеСделай так, чтобы камера плавно следовала за игроком: замени camera_x = player.centerx - 240 строкой, которая каждый кадр перемещает camera_x на одну десятую расстояния в сторону player.centerx - 240. Оставь строку, которая ограничивает её значение.
Попробуйте сами
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Long Road")
clock = pygame.time.Clock()
WORLD_WIDTH = 1440
player = pygame.Rect(220, 240, 40, 40)
camera_x = 0
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= 6
if keys[pygame.K_RIGHT]:
player.x += 6
player.left = max(player.left, 0)
player.right = min(player.right, WORLD_WIDTH)
camera_x = player.centerx - 240
camera_x = max(0, min(camera_x, WORLD_WIDTH - 480))
screen.fill((30, 30, 46))
pygame.draw.rect(screen, (80, 80, 100), (0, 280, 480, 80))
for post_x in range(0, WORLD_WIDTH, 120):
pygame.draw.rect(screen, (80, 160, 255), (post_x - int(camera_x), 220, 20, 60))
pygame.draw.rect(screen, (90, 200, 120), player.move(-int(camera_x), 0))
pygame.display.flip()
clock.tick(60)
pygame.quit()
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Звук и игровые ощущения
4Тряска экрана и вспышка при попадании
Тряска экранаВспышка при попаданииОстановка при попаданииСоблюдайте умеренность5Плавное движение
Движение к целиПлавная камераРезкий эффект при подбореПлавность при любой частоте кадров6Доведём «Звёздный патруль» до блеска
Звуки «Звёздного патруля»Искры при каждом попаданииПотренируйтесь самостоятельно: Песочница Pygame