htmltypescriptphaser-frameworkspine

Loading a Spine .atlas .png and .json from base64 in phaser


js from phaser. I am trying to embed my spine animation files into the bundle and load them but I am having trouble as SpinePlugin is looking for a url not a base64 string.

I have this working with audio and spritesheets can someone help point me in the correct direction

My spritesheet loading code

  spritesheets.forEach( ( data: SpriteSheetData ) => {
            let image = new Image();
            image.src = data.image;
            image.onload = this.onSpriteSheetLoaded.bind( this, data, image, onLoadingComplete );
        } );
 protected onSpriteSheetLoaded( data: SpriteSheetData, image: HTMLImageElement, onLoadingComplete: Function ): void {
        this.textures.addAtlasJSONArray( data.name, image, data.src );
        this.filesLoaded++;
        if ( this.filesLoaded >= this.filesToLoad ) {
            onLoadingComplete();
        }
    }

Here is my attempt at loading the spine files

        spineAnimations.forEach( ( data: SpineAnimationData ) => {
            let image = new Image();
            image.src = data.image;
            image.onload = this.onSpineAnimationLoaded.bind( this, data, image, onLoadingComplete );
        } );
    protected onSpineAnimationLoaded( data: SpineAnimationData, image: HTMLImageElement, onLoadingComplete: Function ): void {
        this.textures.addImage( data.name, image );
        ( this.load as any ).spine( data.name, data.src, data.atlas );
        this.filesLoaded++;
        if ( this.filesLoaded >= this.filesToLoad ) {
            onLoadingComplete();
        }
    }

image and atlas are in base64 but the json file is not, when I pass it in here its the actual json object. How can I pass a url to this instead of the actual object?

Edit

Okay so the files are loading and into the correct cache now, but It seems it doesn't like the .atlas as a base64.

    protected onSpineAnimationLoaded( data: SpineAnimationData, image: HTMLImageElement, onLoadingComplete: Function ): void {
        let texture = this.textures.addImage( data.name, image );
        this.cache.custom.spineTextures.add( data.name, texture );
        this.cache.custom.spine.add( data.name, data.atlas );
        this.cache.json.add( data.name, data.src );
        ( this.load as any ).spine( data.name, undefined, undefined );
        this.filesLoaded++;
        if ( this.filesLoaded >= this.filesToLoad ) {
            onLoadingComplete();
        }
    }

How to convert back?

EDIT #2

Okay so its converting properly now but im stuck on how to create a spine.webgl.GLTexture as that is undefined.

 protected onSpineAnimationLoaded( data: SpineAnimationData, image: HTMLImageElement, onLoadingComplete: Function ): void {
        let texture = new Spine.webgl.GLTexture( this.game.context as any, image )
        this.cache.custom.spineTextures.add( data.name, texture );
        let splitAtlasBase64 = data.atlas.split( ',' );
        let atlasBase64 = splitAtlasBase64[ splitAtlasBase64.length - 1 ];
        this.cache.custom.spine.add( data.name, { data: atob( atlasBase64 ) } );
        this.cache.json.add( data.name, data.src );
        ( this.load as any ).spine( data.name, undefined, undefined );
        this.filesLoaded++;
        if ( this.filesLoaded >= this.filesToLoad ) {
            onLoadingComplete();
        }
    }

Edit 3

Found my solution, needed to also import Spine

import Spine from '../../node_modules/phaser/plugins/spine/src/runtimes/spine-both.js';

Final Loading code

   protected onSpineAnimationLoaded( data: SpineAnimationData, image: HTMLImageElement, onLoadingComplete: Function ): void {
        let texture = new Spine.webgl.GLTexture( this.game.context as any, image )
        this.cache.custom.spineTextures.add( data.name, texture );
        let splitAtlasBase64 = data.atlas.split( ',' );
        let atlasBase64 = splitAtlasBase64[ splitAtlasBase64.length - 1 ];
        this.cache.custom.spine.add( data.name, { data: atob( atlasBase64 ) } );
        this.cache.json.add( data.name, data.src );
        ( this.load as any ).spine( data.name, undefined, undefined );
        this.filesLoaded++;
        if ( this.filesLoaded >= this.filesToLoad ) {
            onLoadingComplete();
        }
    }

Solution

  • protected onSpineAnimationLoaded( data: SpineAnimationData, image: HTMLImageElement, onLoadingComplete: Function ): void {
        let texture = new Spine.webgl.GLTexture( this.game.context as any, image )
        this.cache.custom.spineTextures.add( data.name, texture );
    
        let splitAtlasBase64 = data.atlas.split( ',' );
        let atlasBase64 = splitAtlasBase64[ splitAtlasBase64.length - 1 ];
    
        this.cache.custom.spine.add( data.name, { data: atob( atlasBase64 ) } );
        this.cache.json.add( data.name, data.src );
    
        ( this.load as any ).spine( data.name, undefined, undefined );
        this.filesLoaded++;
    
        if ( this.filesLoaded >= this.filesToLoad ) {
            onLoadingComplete();
        }
    }