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

Случайные движущиеся объекты в Pygame

5 min read Разработка игр Обновлено 11 Apr 2026
Случайные движущиеся объекты в Pygame
Случайные движущиеся объекты в Pygame

Добавление случайно движущихся объектов в игру на Pygame делает её динамичнее и интереснее. В статье показаны базовая настройка, варианты движения (горизонтальное, случайные повороты, движение к игроку), активация по близости, обнаружение коллизий и идеи для дальнейшего развития. Приведённый код можно адаптировать и оптимизировать под разные типы игр.

игрок играет в игру с контроллером

Pygame — популярная библиотека Python для разработки игр. Добавление случайно движущихся объектов (препятствия, враги, усиления и т. п.) добавляет в мир игры непредсказуемость и игровой интерес. Эта статья шаг за шагом показывает, как внедрить такие объекты, как они ведут себя и какие лучшие практики применить.

Создайте простую игру

Начните с базового окна Pygame, добавьте объект игрока и платформы. Реализуйте простое управление игроком через стрелки или тач. Основная цель на этом этапе — рабочий цикл игры: отрисовка, обработка ввода, обновление состояния и ограничение FPS.

Код, используемый в статье, доступен в репозитории на GitHub и лицензирован под MIT. Создайте файл simple-game.py и поместите туда базовый код игры.

объект игрока и две платформы

Добавление нескольких движущихся объектов

Теперь, когда базовая игра готова, добавьте несколько случайных движущихся объектов. Ниже — пример простого массива объектов, которые движутся горизонтально с разной скоростью.

object_width, object_height = 30, 30  
object_speed_range = (2, 7)  
objects = []  
  
def\u00a0create_random_object():  
\u00a0\u00a0\u00a0return {  
\u00a0\u00a0\u00a0\u00a0\u00a0'x': random.randint(0, screen_width - object_width),  
\u00a0\u00a0\u00a0\u00a0\u00a0'y': random.randint(0, screen_height - object_height),  
\u00a0\u00a0\u00a0\u00a0\u00a0'speed': random.randint(*object_speed_range)  
\u00a0\u00a0\u00a0}  
  
for _ in range(5):   
\u00a0\u00a0objects.append(create_random_object())  
  
def\u00a0draw_object(obj):  
\u00a0\u00a0obj_dim = (obj['x'], obj['y'], object_width, object_height)  
\u00a0\u00a0pygame.draw.rect(screen, WHITE, obj_dim)  
  
# Game loop  
while running:  
\u00a0\u00a0screen.fill((0, 0, 0))  
  
\u00a0\u00a0# ... (previous code)  
  
\u00a0\u00a0for obj in objects:  
\u00a0\u00a0\u00a0\u00a0obj['x'] += obj['speed']  
\u00a0\u00a0\u00a0\u00a0if obj['x'] > screen_width:  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0obj['x'] = -object_width  
  
\u00a0\u00a0\u00a0\u00a0draw_object(obj)  
  
\u00a0\u00a0pygame.display.update()  
\u00a0\u00a0clock.tick(60)  
  
pygame.quit()

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

несколько случайно движущихся объектов с игроком и платформой

Реализация алгоритма случайного движения

Горизонтального движения бывает недостаточно. Чтобы объекты вели себя непредсказуемее, добавьте случайные изменения направления.

# Random Movement Algorithm  
def\u00a0update_random_movement(obj):  
\u00a0\u00a0# Change the direction randomly  
\u00a0\u00a0if random.random() < 0.01:    
\u00a0\u00a0\u00a0\u00a0obj['speed'] = -obj['speed']  
  
# Game loop  
while running:  
\u00a0\u00a0# ... (previous code)  
  
\u00a0\u00a0for obj in objects:  
\u00a0\u00a0\u00a0\u00a0obj['x'] += obj['speed']  
\u00a0\u00a0\u00a0\u00a0if obj['x'] > screen_width:  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0obj['x'] = -object_width  
  
\u00a0\u00a0\u00a0\u00a0update_random_movement(obj)  
\u00a0\u00a0\u00a0\u00a0draw_object(obj)  
  
\u00a0\u00a0pygame.display.update()  
\u00a0\u00a0clock.tick(60)  
  
pygame.quit()

Важно: вероятность изменения направления и диапазон скоростей — ключевые настройки. Малые значения дают предсказуемое поведение, большие — хаос.

Сделать объекты, которые движутся к игроку

Чтобы увеличить сложность, можно сделать часть объектов преследующими игрока. Для этого вычисляют угол между центрами и сдвигают объект в направлении игрока.

import math  
  
# Objects Moving Towards Player  
def\u00a0move_towards_player(obj):  
\u00a0\u00a0player_center_x = player_x + player_width // 2  
\u00a0\u00a0player_center_y = player_y + player_height // 2  
\u00a0\u00a0object_center_x = obj['x'] + object_width // 2  
\u00a0\u00a0object_center_y = obj['y'] + object_height // 2  
  
\u00a0\u00a0angle1 = player_center_y - object_center_y  
\u00a0\u00a0angle2 = player_center_x - object_center_x  
  
\u00a0\u00a0angle = math.atan2(angle1, angle2)  
\u00a0\u00a0obj['x'] += obj['speed'] * math.cos(angle)  
\u00a0\u00a0obj['y'] += obj['speed'] * math.sin(angle)  
  
# Game loop  
while running:  
\u00a0\u00a0# ... (previous code)  
  
\u00a0\u00a0for obj in objects:  
\u00a0\u00a0\u00a0\u00a0obj['x'] += obj['speed']  
\u00a0\u00a0\u00a0\u00a0if obj['x'] > screen_width:  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0obj['x'] = -object_width  
  
\u00a0\u00a0\u00a0\u00a0move_towards_player(obj)  
\u00a0\u00a0\u00a0\u00a0draw_object(obj)  
  
\u00a0\u00a0pygame.display.update()  
\u00a0\u00a0clock.tick(60)  
  
pygame.quit()

Такое поведение делает объекты целенаправленными и усиливает чувство угрозы. Можно комбинировать преследование с периодическими случайными манёврами для более естественного поведения.

Активировать объекты только при приближении игрока

Не обязательно заставлять все объекты двигаться с самого начала. Лучше активировать их, когда игрок приближается на определённое расстояние.

# Objects Start to Move When Player Enters Surroundings  
surrounding_distance = 150  
  
def\u00a0should_start_moving(obj):  
\u00a0\u00a0surrounded1 = abs(obj['x'] - player_x) < surrounding_distance  
\u00a0\u00a0surrounded2 = abs(obj['y'] - player_y) < surrounding_distance  
\u00a0\u00a0return  surrounded1 or surrounded2  
  
# Game loop  
while running:  
\u00a0\u00a0# ... (previous code)  
  
\u00a0\u00a0for obj in objects:  
\u00a0\u00a0\u00a0\u00a0if should_start_moving(obj):  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0obj['x'] += obj['speed']  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if obj['x'] > screen_width:  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0obj['x'] = -object_width  
  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0update_random_movement(obj)  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0move_towards_player(obj)  
  
\u00a0\u00a0\u00a0\u00a0draw_object(obj)  
  
\u00a0\u00a0pygame.display.update()  
\u00a0\u00a0clock.tick(60)  
  
pygame.quit()

Активация по близости помогает снизить нагрузку на процессор и делает поведение более контролируемым.

Обнаружение столкновений и взаимодействие

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

# Collision Detection and Interaction  
def\u00a0is_collision(obj):  
  
\u00a0\u00a0condition1 = player_x + player_width > obj['x']  
\u00a0\u00a0condition2 = player_x < obj['x'] + object_width  
\u00a0\u00a0condition3 = player_y + player_height > obj['y']  
\u00a0\u00a0condition4 = player_y < obj['y'] + object_height  
\u00a0\u00a0return ( condition1 and condition2  and condition3 and condition4)  
  
# Game loop  
while running:  
\u00a0\u00a0# ... (previous code)  
  
\u00a0\u00a0for obj in objects:  
\u00a0\u00a0\u00a0\u00a0if should_start_moving(obj):  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0obj['x'] += obj['speed']  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if obj['x'] > screen_width:  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0obj['x'] = -object_width  
  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0update_random_movement(obj)  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0move_towards_player(obj)  
  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if is_collision(obj):  
\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0objects.remove(obj)  
  
\u00a0\u00a0\u00a0\u00a0draw_object(obj)  
  
\u00a0\u00a0pygame.display.update()  
\u00a0\u00a0clock.tick(60)  
  
pygame.quit()

Обратите внимание: при удалении объектов в цикле итерации безопаснее сначала помечать объекты для удаления, а затем удалять вне цикла, чтобы избежать ошибок итерации.

Дополнительные возможности и идеи для развития

Ниже — идеи, которые расширят механику движущихся объектов и повысят вовлечённость игроков.

Счёт и прогрессия

  • Дайте разным объектам разный счёт за сбор или уничтожение.
  • Повышайте сложность по мере роста счёта: увеличивайте скорость, уменьшайте интервалы активации, увеличивайте количество врагов.

Усиления и бонусы

  • Добавьте объекты, дающие временные эффекты: ускорение, неуязвимость, замедление врагов.
  • Сделайте их редкими и заметными, чтобы игрок мог целенаправленно искать преимущества.

Искусственный интеллект врагов

  • Реализуйте паттерны движения: патрулирование, преследование, отступление при низком здоровье.
  • Комбинируйте поведение: преследование + случайные манёвры выглядит естественнее.

Коллективные предметы и награды

  • Разбросайте коллекционные предметы, дающие достижения и открывающие новые уровни или скины.

Важно: всегда тестируйте новые механики на слабых устройствах, если планируете мобильную версию.

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

Балансировка сложности

Скорость, частота и паттерны должны давать честный вызов. Чрезмерная случайность демотивирует; чрезмерная предсказуемость делает игру скучной.

Оптимизация производительности

  • Ограничьте количество активных объектов.
  • Используйте простые примитивы и батчинг отрисовки, когда возможно.
  • Применяйте пространственные структуры (grid, quad-tree) для ускорения поиска столкновений.

Тестирование и настройка

Проводите playtest с разными игроками. Собирайте фидбек по ощущению скорости, сложности и частоте столкновений. Настраивайте параметры динамически.

Контролируемая случайность

Определяйте диапазоны и вероятности вместо чистого случайного поведения. Это сохраняет разнообразие, но предотвращает критические баги и дисбаланс.

Когда это не работает

  • Если геймплей подразумевает только платформенную головоломку, случайные движущиеся объекты могут мешать ясности.
  • В играх с фокусом на историю и диалоги постоянная динамика может отводить внимание.

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

  • Анимации и триггеры уровня вместо постоянного движения.
  • Скриптованные враги с заранее заданными паттернами.
  • Событийная система, активирующая объекты только при достижении контрольных точек.

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

  • “Контролируемый хаос”: ограничьте случайность рамками (зоны, таймеры, вероятности).
  • “Порог тревоги”: увеличивайте агрессию врагов по достижении порога (счёт, время, здоровье игрока).
  • “Экономия ресурсов”: активируйте объекты только при потенциальном взаимодействии с игроком.

Факт-бокс

  • Рекомендованные размеры объектов: 16–64 пикселей в зависимости от разрешения.
  • Частота обновления логики движения: 30–60 обновлений в секунду.
  • Диапазон скоростей в простых играх: 1–8 пикселей за кадр.
    (Это ориентиры — тестируйте под свою игру.)

Мини-методология внедрения

  1. Добавьте базовые объекты и простую отрисовку.
  2. Реализуйте горизонтальное движение и отладьте рендер/производительность.
  3. Добавьте случайные изменения направления и контролируемую вероятность.
  4. Внедрите движение к игроку для части объектов.
  5. Добавьте активацию по близости и оптимизацию столкновений.
  6. Проведите playtest и отрегулируйте параметры.

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

  • Разработчик: протестировать производительность, реализовать удаление объектов безопасно, покрыть тестами.
  • Дизайнер: задать диапазоны скоростей, вероятности поведения, визуальную читабельность объектов.
  • QA: проверить крайние случаи (много объектов, быстрые объекты, одновременные столкновения).

Шпаргалка параметров

  • object_width/object_height: 16–64
  • object_speed_range: (1, 8)
  • surrounding_distance: 100–300
  • update probability (random flip): 0.005–0.02

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

  • Объекты корректно появляются и плавно двигаются.
  • Коллизии детектируются и приводят к ожидаемому результату.
  • Нет падений FPS при нормальном количестве объектов.
  • Удаление объектов не вызывает ошибок итерации.

Примеры отказов и отладка

  • Заметные подтормаживания: профилируйте цикл отрисовки и логику.
  • Объекты «залипают» на границе экрана: проверьте условия телепортации и величины координат.
  • Ошибки при удалении в цикле: сначала собирайте индекс/ссылку, затем удаляйте вне основного цикла.

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

Случайные движущиеся объекты — мощный инструмент для повышения динамики игры. Комбинируйте простые паттерны, контролируемую случайность и активацию по близости, чтобы получить интересную и оптимизированную механику. Тестируйте на реальных устройствах и настраивайте параметры по результатам playtest.

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

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

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

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро