Поиск объектов в иерархии

В PixiJS сцена строится как дерево объектов, где каждый элемент является наследником класса PIXI.Container. Контейнеры могут содержать другие контейнеры или спрайты, формируя иерархию. Эффективный поиск объектов внутри этой структуры позволяет реализовывать сложные интерфейсы и игровые механики.

Основные методы поиска

  1. getChildByName(name) Возвращает первый дочерний объект с указанным именем.

    const sprite = container.getChildByName("hero");

    Важно: поиск выполняется только среди непосредственных детей контейнера.

  2. getChildAt(index) Доступ к объекту по индексу в массиве children.

    const firstChild = container.getChildAt(0);

    Индексация соответствует порядку добавления в контейнер.

  3. children Массив всех непосредственных дочерних объектов контейнера. Позволяет выполнять фильтрацию или обход через циклы.

    container.children.forEach(child => {
        if (child.name === "enemy") {
            console.log("Найден враг:", child);
        }
    });

Рекурсивный поиск

Для поиска объектов глубоко в иерархии необходимо использовать рекурсию. Это особенно актуально для игровых сцен с множеством вложенных контейнеров.

function findChildByName(container, name) {
    for (const child of container.children) {
        if (child.name === name) return child;
        if (child instanceof PIXI.Container) {
            const found = findChildByName(child, name);
            if (found) return found;
        }
    }
    return null;
}

const boss = findChildByName(stage, "boss");

Особенности рекурсивного поиска:

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

Поиск по типу объекта

Иногда важно находить объекты не по имени, а по классу или типу. PixiJS позволяет использовать оператор instanceof:

function findAllSprites(container) {
    let sprites = [];
    for (const child of container.children) {
        if (child instanceof PIXI.Sprite) {
            sprites.push(child);
        } else if (child instanceof PIXI.Container) {
            sprites = sprites.concat(findAllSprites(child));
        }
    }
    return sprites;
}

const allSprites = findAllSprites(stage);

Фильтрация и комбинация условий

Массив children и рекурсия дают возможность применять сложные фильтры:

function findVisibleEnemies(container) {
    let result = [];
    for (const child of container.children) {
        if (child.name?.startsWith("enemy") && child.visible) {
            result.push(child);
        }
        if (child instanceof PIXI.Container) {
            result = result.concat(findVisibleEnemies(child));
        }
    }
    return result;
}

const visibleEnemies = findVisibleEnemies(stage);

Ключевые моменты:

  • Использование child.name?.startsWith("enemy") предотвращает ошибки при отсутствии имени.
  • Фильтрация по visible позволяет исключить скрытые объекты.

Поиск с помощью пользовательских свойств

В PixiJS к объектам можно добавлять свои свойства. Это упрощает группировку и поиск:

const sprite = new PIXI.Sprite(texture);
sprite.role = "player";
container.addChild(sprite);

function findByRole(container, role) {
    for (const child of container.children) {
        if (child.role === role) return child;
        if (child instanceof PIXI.Container) {
            const found = findByRole(child, role);
            if (found) return found;
        }
    }
    return null;
}

const player = findByRole(stage, "player");

Производительность поиска

  • Избегать избыточного рекурсивного обхода, если структура известна.
  • Для больших сцен лучше индексировать объекты при добавлении, например через словарь по именам или ролям.
  • Использование Map или Set ускоряет поиск при постоянных обновлениях.

Итоговые рекомендации

  • Использовать getChildByName для простых случаев с прямыми детьми.
  • Рекурсивный обход необходим при глубокой вложенности.
  • Фильтрация по типу, имени, видимости и пользовательским свойствам делает поиск гибким.
  • Индексация объектов при создании сцены улучшает производительность и упрощает поддержку.

Эффективное управление и поиск объектов в иерархии контейнеров является ключом к построению масштабируемых сцен и динамических интерфейсов в PixiJS.