В PixiJS каждая сцена представляет собой иерархическую структуру
объектов, где основной элемент — это
Container. Контейнер может содержать как другие
контейнеры, так и примитивные графические объекты (Sprite,
Graphics, Text и др.). Такая иерархия образует
дерево сцены, корнем которого обычно является экземпляр
PIXI.Application.stage.
Каждый объект в дереве сцены обладает свойствами
трансформации: position, scale,
rotation, pivot и skew. Эти
свойства наследуются вниз по дереву, что означает, что изменение
контейнера влияет на все его дочерние элементы.
PixiJS предоставляет несколько подходов для обхода дерева сцены и взаимодействия с его элементами:
childrenКаждый контейнер имеет массив children, который содержит
все его прямые потомки. Цикл по этому массиву позволяет получить доступ
к дочерним объектам.
const stage = app.stage;
stage.children.forEach(child => {
console.log(child.name, child.position);
});
Важно помнить, что children включает только
непосредственных потомков. Для работы с более глубокой
иерархией потребуется рекурсивный подход.
Для обхода всех объектов дерева сцены используют рекурсивную функцию. Она позволяет выполнить действие на каждом элементе независимо от глубины вложенности.
function traverse(container, callback) {
callback(container);
if (container.children) {
container.children.forEach(child => traverse(child, callback));
}
}
traverse(app.stage, obj => {
console.log(obj.name);
});
Этот метод универсален: можно выполнять любые действия, включая изменение свойств, удаление объектов или применение эффектов.
getChildByNameДля поиска конкретного объекта по имени можно использовать
getChildByName, однако стоит учитывать, что этот метод
ищет только среди прямых детей контейнера. Для поиска
во всем дереве сцены потребуется рекурсивный вызов:
function findByName(container, name) {
if (container.name === name) return container;
for (const child of container.children) {
const result = findByName(child, name);
if (result) return result;
}
return null;
}
const player = findByName(app.stage, 'player');
Обход дерева сцены часто используется для:
traverse(app.stage, obj => {
if (obj instanceof PIXI.Sprite) {
obj.tint = 0xff0000; // перекрасить все спрайты в красный
}
});
При большом количестве объектов в сцене важно учитывать производительность:
visible и interactive
свойства для игнорирования неактивных объектов.function traverseVisible(container, callback) {
if (!container.visible) return;
callback(container);
container.children.forEach(child => traverseVisible(child, callback));
}
Обход дерева сцены позволяет назначать события объектам без необходимости вручную подписываться на каждый элемент.
traverse(app.stage, obj => {
if (obj.interactive) {
obj.on('pointerdown', () => console.log(`${obj.name} clicked`));
}
});
Это особенно полезно в интерфейсах с динамически создаваемыми объектами, когда заранее неизвестно, какие элементы будут присутствовать на сцене.
Для сложных сцен часто требуется сочетать рекурсивный обход с фильтрацией по типу или состоянию объекта:
traverse(app.stage, obj => {
if (obj instanceof PIXI.Container && obj.name.startsWith('enemy')) {
obj.alpha = 0.5; // сделать всех врагов полупрозрачными
}
});
Фильтрация позволяет ограничить обработку только релевантными объектами, снижая нагрузку и упрощая код.
name для удобного поиска.uiContainer,
enemiesContainer).removeChild и addChild вместо скрытия через
visible, если требуется очистка памяти.Обход дерева сцены является фундаментальным инструментом в PixiJS для управления визуальными элементами, оптимизации работы и реализации сложной логики. Правильное использование рекурсивного подхода, фильтрации и методов поиска обеспечивает гибкость и масштабируемость графических приложений.