代码之家  ›  专栏  ›  技术社区  ›  Derek Lawrence

如何使Pixi粒子在设置为脊椎动画中的槽的子对象时正常工作

  •  0
  • Derek Lawrence  · 技术社区  · 6 年前
    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位置

    1 回复  |  直到 5 年前
        1
  •  0
  •   Derek Lawrence    6 年前

    所以我最终需要重写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 );
        }
    }