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

Случайные движущиеся объекты в 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
Автор
Редакция

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

Как проверить, использовали ли ваш компьютер без разрешения
Безопасность

Как проверить, использовали ли ваш компьютер без разрешения

Передать буфер обмена на Android через ADB
Android.

Передать буфер обмена на Android через ADB

Золотой час: как делать идеальные селфи
Фотография

Золотой час: как делать идеальные селфи

Правый и средний клик на тачпаде ноутбука
Советы

Правый и средний клик на тачпаде ноутбука

Как выбрать недорогой Smart TV
Телевизоры

Как выбрать недорогой Smart TV

Как управлять группами и уведомлениями в Messenger
Мессенджер

Как управлять группами и уведомлениями в Messenger