如何在设置为脊柱动画内部插槽的子项时,使Pixi Particles正常运行

问题描述 投票:0回答:1
protected createParticleAnimation ( data: IAnticipationParticle ): particles.Emitter {
    let particleResource = PIXI.loader.resources[ data.name ].data;
    let particleImages: Array<Texture> = new Array<Texture>();

    let container = new particles.ParticleContainer();
    container.scale.set( 1, -1 );
    let spineAnim = this.anticipationAnimations[ 0 ] as spine.Spine;

    spineAnim.slotContainers.forEach( ( slotContainer: Container ) => {
        if ( slotContainer.name == 'CoinParticles' ) {
            container.position.set( slotContainer.children[ 0 ].x * 2, slotContainer.children[ 0 ].y * 2 );
            slotContainer.addChild( container );
            return;
        }
    } );

    data.images.forEach( ( image: string ) => {
        particleImages.push( PIXI.Texture.fromImage( image ) );
    } );

    let animation = new PIXI.particles.Emitter(
        container,
        particleImages,
        particleResource
    );
    animation.emit = false;
    animation.autoUpdate = true;

    return animation;
}

所以我在另一个函数中创建我的脊椎动画,然后创建我的粒子效果,如上所示,并将其附加到我的脊椎动画内的slotContainer。但是当我的脊椎动画播放时,粒子总是跟随父母的位置并且不保持他们的世界坐标。

我相信这是因为脊柱,但有没有人有任何关于如何解决这个问题的想法?

因此,例如当发射器移动已经生成的粒子跟随发射器的x位置时

pixi.js particle-system pixijs spine
1个回答
0
投票

所以我最终需要覆盖pixi容器的updateTransform方法。

我将发射器传递给容器,以便更新其变换。当我这样做时,我需要计算精灵的原始点。这需要在创建发射器之后调用,因为容器需要传递给发射器的创建。

然后,您需要将容器变换回原来的位置,以便子项(粒子)可以正常运行。然后,您将发射器生成位置与父项一起移动。

import { particles, Point } from 'pixi.js';

/**
 * A container to be used when attaching a particle emitter to a spine animation
 */
export class SpineParticleContainer extends particles.ParticleContainer {

    /**The emitter that is drawning to the container */
    protected emitter: particles.Emitter;

    /**The original position of the sprite when the emitter is set */
    protected origin: Point;

    constructor () {
        super();
    }

    /**
     * Sets the containers emittter so it can update the emitters position
     * @param emiter The particle emitter to pass in, this should be the particle emitter assigned to this container already
     */
    public setEmitter ( emiter: particles.Emitter ): void {
        this.emitter = emiter;
        this.origin = new Point( this.parent.worldTransform.tx, this.parent.worldTransform.ty );
    }

    /**Override update transform to reposition the container at its origin position and move the emitter along with the animation */
    public updateTransform () {
        this._boundsID++;
        this.worldAlpha = this.alpha * this.parent.worldAlpha;

        let position = new Point( this.parent.worldTransform.tx, this.parent.worldTransform.ty );
        let newPosition = new Point( this.origin.x - position.x, this.origin.y - position.y );
        this.position.set( newPosition.x, newPosition.y );
        this.transform.updateTransform( this.parent.transform );
        for ( let i = 0, j = this.children.length; i < j; i++ ) {
            const child = this.children[ i ];

            if ( child.visible ) {
                child.updateTransform();
            }
        }

        this.emitter.spawnPos.set( this.parent.worldTransform.tx, this.parent.worldTransform.ty );
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.