Гид по технологиям

Параллакс-скроллинг в Arcade (Python)

5 min read Разработка игр Обновлено 20 Dec 2025
Параллакс-скроллинг в Arcade
Параллакс-скроллинг в Arcade

игрок на экране игры с эффектом параллакса

Зачем нужен параллакс-скроллинг

Параллакс-скроллинг помогает визуально отделить передний план, средний план и фон, делая сцену глубже и интереснее. Коротко:

  • Что это: несколько слоёв, двигающихся с разной скоростью.
  • Зачем: улучшает восприятие скорости и пространства, добавляет «профессиональную» отделку игре.
  • Когда не применять: если игра требует минимальной задержки ввода (например, соревновательные тайм-траблгеймплейные режимы) или на очень слабых устройствах.

Быстрый план (микро-методология)

  1. Создать класс Layer, у которого есть scroll_speed.
  2. Заполнить слои спрайтами/изображениями/частицами.
  3. В update() смещать слои пропорционально движению игрока.
  4. В on_draw() сначала рисовать фоновые слои, затем платформы и игрока.
  5. Профилировать и оптимизировать: текстуры, atlases, culling.

Создаём простую игру (исходная структура)

Прежде чем начать, убедитесь, что у вас установлен pip и библиотека Arcade:

pip install arcade

Файл simple-game.py в статье определяет класс Player, наследуемый от arcade.Sprite, и класс Platform для прямоугольных платформ. Класс MyGame отвечает за настройку сцены, создание игрока и платформ, обработку рисования, обновления и ввода.

Ниже — упрощённый пример структуры Layer и настройки слоёв. В оригинале проект доступен в репозитории GitHub и лицензирован MIT.

class Layer(arcade.SpriteList):
    def __init__(self, scroll_speed):
        super().__init__()
        self.scroll_speed = scroll_speed

class MyGame(arcade.Window):
    def __init__(self, width, height):
        super().__init__(width, height)
        arcade.set_background_color(arcade.color.WHITE)
        self.player = None
        self.platforms = None
        self.layers = []

    def setup(self):
        self.player = Player()
        self.platforms = arcade.SpriteList()
        gray = arcade.color.GRAY
        red =  arcade.color.RED
        brown = arcade.color.BROWN
        yellow = arcade.color.YELLOW

        w = SCREEN_WIDTH // 2
        h = SCREEN_HEIGHT // 2

        self.platforms.append(Platform(w, h - 100, 200, 20, yellow))
        self.platforms.append(Platform(w, h + 100, 200, 20, yellow))

        layers_data = [
            (Layer(0.2), Platform(w, h, 800, 600, gray)),
            (Layer(0.5), Platform(w, h - 200, 400, 20, red)),
            (Layer(0.5), Platform(w, h + 200, 400, 20, red)),
            (Layer(1.0), Platform(w, h - 300, 200, 20, brown)),
            (Layer(1.0), Platform(w, h + 300, 200, 20, brown))
        ]

        for layer, platform in layers_data:
            layer.append(platform)
            self.layers.append(layer)

    # Остальные методы: on_draw, update, on_key_press и т.д.

Реализация параллакса — ключевые изменения

Чтобы слои двигались по-разному в зависимости от движения игрока, обновляйте координаты спрайтов внутри каждого слоя в методе update. Примерно так выглядит логика:

class MyGame(arcade.Window):
    # ...

    def on_draw(self):
        arcade.start_render()

        for layer in self.layers:
            layer.draw()

        self.platforms.draw()
        self.player.draw()

    def update(self, delta_time):
        self.player.update()

        for layer in self.layers:
            for sprite in layer:
                change = self.player.change_x * layer.scroll_speed
                sprite.center_x -= change

    # ...

Пояснение: self.player.change_x — горизонтальная скорость игрока. Умножая её на layer.scroll_speed, вы получаете смещение для слоя. Слабые (большая глубина) слои должны двигаться медленнее (меньшая scroll_speed), ближние — быстрее.

простая игра: игрок и две платформы

игра с игроком, двумя платформами и параллакс-фоном

Регулировка скоростей прокрутки

Экспериментируйте со значениями scroll_speed. Здесь пример, где значения увеличены, чтобы усилить эффект:

class MyGame(arcade.Window):
    # ...

    def setup(self):
        # ...
        layers_data = [
            (Layer(1.2), Platform(w, h, 800, 600, gray)),
            (Layer(2.5), Platform(w, h - 200, 400, 20, red)),
            (Layer(3.0), Platform(w, h + 200, 400, 20, red)),
            (Layer(4.0), Platform(w, h - 300, 200, 20, brown)),
            (Layer(5.0), Platform(w, h + 300, 200, 20, brown))
        ]
        # ...

Помните: слишком большие значения могут сделать сцену неестественной. Обычно используют 3–7 слоёв с плавно возрастающими значениями скорости.

Дополнительные эффекты и сочетания

Параллакс легко комбинируется с частицами и погодой. Ниже — пример добавления капли дождя как отдельного набора частиц в фоновой слоях.

class Raindrop(arcade.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.texture = arcade.make_soft_square_texture(3, blue, outer_alpha=100)
        self.center_x = x
        self.center_y = y

class BackgroundLayer(arcade.SpriteList):
    def __init__(self, scroll_speed):
        super().__init__()
        self.scroll_speed = scroll_speed
        self.raindrops = arcade.SpriteList()

    def update(self):
        for raindrop in self.raindrops:
            raindrop.center_y -= self.scroll_speed * 5
            if raindrop.center_y < -10:
                raindrop.remove_from_sprite_lists()

    def draw(self):
        super().draw()
        self.raindrops.draw()

class MyGame(arcade.Window):
    def __init__(self, width, height):
        super().__init__(width, height)
        arcade.set_background_color(arcade.color.WHITE)
        self.background_layer = BackgroundLayer(0.2)
        # ...

    def setup(self):
        # ...
        self.background_layer.raindrops.append(
            Raindrop(SCREEN_WIDTH // 2, SCREEN_HEIGHT + 10))

    def update(self, delta_time):
        self.player.update()
        self.background_layer.update()

    def on_draw(self):
        arcade.start_render()
        self.background_layer.draw()
        self.platforms.draw()
        self.player.draw()

игра с игроком, платформами, параллакс-фоном и падающей каплей дождя

Лучшие практики

Планирование слоёв

  • Определите роли слоёв: небо, далёкий фон, средний план (архитектура), объекты интерактива, эффекты частиц.
  • Внешние большие объекты (например, горы) должны двигаться медленнее.
  • Ближние детали — быстрее.

Оптимизация изображений и текстур

  • Используйте atlas/атласы спрайтов, где возможно, чтобы уменьшить переключения текстур.
  • Сжимайте изображения, но следите за артефактами (PNG для резких краёв, JPEG для фона).
  • По возможности используйте поточные текстуры с размером, кратным степени двойки для старых GPU.

Экономьте обработку

  • Отбрасывайте (cull) спрайты, которые находятся вне экрана.
  • Минимизируйте цикл перебора всех спрайтов на каждом кадре: для больших наборов храните только видимые объекты в отдельном списке.
  • Для фоновых неколеблющихся изображений используйте один большой спрайт вместо множества мелких.

Плавность движений

  • Используйте интерполяцию и сглаживание (easing), если камера перемещается по ступеням.
  • Обрабатывайте фиксированный timestep для физики и независимый для визуальных эффектов.

Отладка и профилирование

  • Измеряйте FPS и время, затрачиваемое на обновление и рисование (например, cProfile или встроенные таймеры).
  • Временно отключайте слои, чтобы найти узкие места.
  • Тестируйте на целевых устройствах (десктоп, ноутбук, слабые ПК, ПК с интегрированной графикой).

Когда параллакс не работает (контрпримеры)

  • Когда игровой дизайн требует абсолютной чёткости положения объектов (например, снайперская стрельба) — лишние визуальные слои отвлекают.
  • На очень маленьких экранах или при плохой оптимизации параллакс может ухудшить отзывчивость.
  • При динамической смене разрешения и неправильной нормализации скоростей слои могут «разъезжаться».

Альтернативные подходы

  • Камера (arcade.Camera): вместо смещения каждого слоя смещайте камеру, а фон рендерьте в мировых координатах с поправкой на парраллакс.
  • Шейдеры: для продвинутых эффектов используйте фрагментные шейдеры, которые смещают слои с субпиксельной точностью.
  • Tilemap: для больших сцен используйте тайлинговые карты с отдельными слоями.

Руководство по тестам и критериям приёмки

Критерии приёмки:

  • При движении игрока слои заднего плана смещаются медленнее, ближние — быстрее.
  • FPS остаётся стабильным в пределах допустимого для целевой платформы.
  • Переходы между зонами (например, телепорт, смена уровня) не приводят к визуальным «прыжкам» слоёв.
  • Элементы UI всегда рендерятся поверх сцен.

Тест-кейсы:

  1. Движение влево/вправо: визуально проверить относительную скорость слоёв.
  2. Стресс-тест: добавить 1000 спрайтов в дальний фон — проверить падение FPS.
  3. Мобильный режим: проверить на эмуляторе/устройстве с низкой производительностью.

Чек-листы ролей

Для программиста:

  • Реализовать класс Layer с scroll_speed.
  • Обновлять позиции слоёв в update().
  • Добавить тесты производительности и профилирование.

Для художника/дизайнера:

  • Подготовить слои с прозрачностью и корректным выравниванием.
  • Предоставить атласы и оптимизированные текстуры.

Для тестировщика:

  • Пройти тест-кейсы (см. выше).
  • Проверить на целевых конфигурациях.

Ментальные модели и эвристики

  • Правило трёх расстояний: передний план / средний план / фон — минимум три слоя для узнаваемого параллакса.
  • Малые смещения для дальних объектов, большие — для ближних.
  • Чем выше детализация объекта, тем ближе он должен «чувствоваться” к камере.

Совместимость и миграция

  • Arcade 2.x может менять API рендеринга; проверяйте совместимость методов SpriteList и Camera при обновлении библиотеки.
  • При миграции на OpenGL/GLSL-решение сохраняйте концепцию слоёв, но переносите логику смещения в шейдер.

Краткое резюме

Параллакс-скроллинг — простой и эффективный способ добавить глубину в 2D-игры. Начните с 3–5 слоёв, отлаживайте скорости и профиль производительности, а затем расширяйте эффект частицами и погодой.

Часто задаваемые вопросы

Нужно ли использовать равное количество объектов в каждом слое?

Нет. Главное — визуальная гармония. Дальний фон обычно содержит меньше интерактивных объектов, но больше крупных графических элементов.

Как перевести сцену на камеры вместо смещения каждого спрайта?

Можно использовать arcade.Camera: рендерьте фоны с поправкой на позицию камеры и множитель параллакса. Это уменьшит перебиратья спрайтов, но потребует расчёта мировых координат для каждого слоя.

Какие форматы изображений лучше использовать?

Для фона с плавными градиентами — JPEG (меньше вес), для слоёв с прозрачностью и резкими краями — PNG.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как сделать кроссоверный Ethernet‑кабель
Сети

Как сделать кроссоверный Ethernet‑кабель

Как вести заметки в Notion — практические приёмы
Productivity

Как вести заметки в Notion — практические приёмы

Отключить Popular Highlights на Kindle
Руководство

Отключить Popular Highlights на Kindle

Авторское право на YouTube: что такое strike
Видео

Авторское право на YouTube: что такое strike

Пропуск звонков через «Не беспокоить» на iPhone
iOS

Пропуск звонков через «Не беспокоить» на iPhone

Как добавить флажки в документы
Документы

Как добавить флажки в документы