3

I am trying to follow along with the Pixijs guide provided here:

https://pixijs.github.io/examples/#/demos/animatedsprite-demo.js - and after a bit of digging here is the sheet they use for their texture mapper https://github.com/pixijs/examples/blob/gh-pages/required/assets/mc.json

To get an example up of a simple animated sprite. The issue that I am having is that I am following along almost exactly and I am getting an error - I do not know what is causing the problem and I don't know how to proceed debugging on my own.

The example has:

var app = new PIXI.Application();
document.body.appendChild(app.view);

app.stop();

PIXI.loader
    .add('spritesheet', 'required/assets/mc.json')
    .load(onAssetsLoaded);

function onAssetsLoaded() {

    // create an array to store the textures
    var explosionTextures = [],
        i;

    for (i = 0; i < 26; i++) {
         var texture = PIXI.Texture.fromFrame('Explosion_Sequence_A ' + (i+1) + '.png');
         explosionTextures.push(texture);
    }

Where I have:

  componentDidMount(){
    this.renderer = PIXI.autoDetectRenderer(1366, 768);
    this.refs.gameCanvas.appendChild(this.renderer.view);
    this.stage = new PIXI.Container();
    this.stage.width = 400;
    this.stage.height = 400;

    console.log(littlemarioforwardwalkjson)

    PIXI.loader
        .add(littlemarioforwardwalkpng, littlemarioforwardwalkjson)
        .load(()=>this.spriteLoaded());

    // console.log(PIXI.utils.TextureCache);

  }

  spriteLoaded(){
    console.log('yolo');
    var frames = [];
    var index = 0;
    console.log('hello there sailor');
    console.log(PIXI.utils.TextureCache)
    for (var i = 0; i < 3; i++) {
          index = i+46;
          var texture = PIXI.Texture.fromFrame("mario_characters1_"+index+".png");
          marioTextures.push(texture);
     }
  }

The error I am getting is:

Error: the frameId “mario_characters1_46.png” does not exist in the texture cache

This is frustrating as my texturepacker json file is displaying correctly:

{"frames": {

"mario_characters1_46.png":
{
    "frame": {"x":0,"y":0,"w":12,"h":15},
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": {"x":0,"y":0,"w":12,"h":15},
    "sourceSize": {"w":12,"h":15},
    "pivot": {"x":0.5,"y":0.5}
},
"mario_characters1_47.png":
{
    "frame": {"x":12,"y":0,"w":11,"h":16},
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": {"x":0,"y":0,"w":11,"h":16},
    "sourceSize": {"w":11,"h":16},
    "pivot": {"x":0.5,"y":0.5}
},
"mario_characters1_48.png":
{
    "frame": {"x":23,"y":0,"w":15,"h":16},
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": {"x":0,"y":0,"w":15,"h":16},
    "sourceSize": {"w":15,"h":16},
    "pivot": {"x":0.5,"y":0.5}
}},
"meta": {
    "app": "http://www.codeandweb.com/texturepacker",
    "version": "1.0",
    "image": "littlemarioforwardwalk.png",
    "format": "RGBA8888",
    "size": {"w":38,"h":16},
    "scale": "1",
    "smartupdate": "$TexturePacker:SmartUpdate:ae9c1a55b9f5884f4a4c0182ea720ca9:80c341baf7877296bb8143f4c51a5998:383ea93646790c53db2201f0624e779e$"
}
}

If I console.log(PIXI.utils.TextureCache) I get:

{data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAQCAYAAAB6Hg0eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABUUlEQVRIx6VVPZqFIAxM/DwE1+B1WL5j0NrucWxtPcYr106uwS2yxQobMWB0aVSciTP5QYRikTVU7mGI+BT3lIdXJCmIFqcRVeP1fHN9xXzvrP/dCws46wG/FryLK9cdXpduvkegBE7Xg9vJE02etLhy/y6vE52F5eCMP2txkrg7POSOJDc1UVe4YT72rzZ+4qGU0mpjsj7Q4p7GF13lrGwG1leEYQakyVMiZvf7+1qWWnH5MEi8QwY0ZSsxrY+k7NQ4tUnNzZ8CcIKmRBk/vsFtBtxmxFI5689ZGd85RjbHDJxKc3Xw1coiYfOE7YZaByyPP8yAfesDYllZXznrAez+Yv60h+Xi1CdriJe1KzMg/U74M4aIJxNM1NNfUbn6v4aNhylaoTExISKBIdg+pwaGcJ7IFeKhIlx8TbRqvCVxUqYlPMfVjhO1MM3SiP+PuB9QuQ5f9MhyUAAAAABJRU5ErkJggg==: Texture}

So it would seem that the error is saying that the Texture Cache is only seeing one image blob - however, calling Texture.fromFrame is how the example on the website says to get it to work, and I think I am reproducing the code very closely.

If anyone has any ideas please let me know.

gman
  • 100,619
  • 31
  • 269
  • 393
Peter Weyand
  • 2,159
  • 9
  • 40
  • 72
  • The issue seems to be calling the function when executing the code, not after the spritesheet has loaded. Have you tried changing this: `load(()=>this.spriteLoaded())` for this `load(this.spriteLoaded)`?. the `load()` method just need the function you want to execute when the resources are ready, but you're calling the function at runtime right now. – Rodrigo Aug 13 '17 at 04:39
  • I've tried all different types of iterations on the load call as that is a common gotcha. Hasn't fixed the issue. – Peter Weyand Aug 13 '17 at 05:12
  • Answer was provided here https://github.com/pixijs/pixi.js/issues/4223 – Peter Weyand Aug 13 '17 at 22:49

2 Answers2

0

It was not easy to find an example with React, if that can help someone.

import React from "react";

import KingHuman from "./img/kinghuman/Idle/Idle.png";
import KingHumanJson from "./img/kinghuman/Idle/Idle.json";

import * as PIXI from 'pixi.js';
import { Stage, Container, AnimatedSprite } from '@inlet/react-pixi';


const PixiGame = () => {
    const willMount = useRef(true);
    const [textures, setTextures] = useState([]);

    const loadSpritesheet = () => {
        const baseTexture = PIXI.BaseTexture.from(KingHuman);
        const spritesheet = new PIXI.Spritesheet(baseTexture, KingHumanJson);
        spritesheet.parse(() => {
            setTextures( Object.keys(spritesheet.textures).map((t) => spritesheet.textures[t]));
        });
    }

    // Hooks way to do ComponentWillMount
    if (willMount.current) {
        loadSpritesheet();
        willMount.current = false;
    }

    return (
        <Stage width={300} height={300} options={{ backgroundColor: 0xeef1f5 }}>
            <Container position={[150, 150]}>
                <AnimatedSprite
                    anchor={0.5}
                    textures={textures}
                    isPlaying={true}
                    initialFrame={0}
                    animationSpeed={0.1}
                />
            </Container>
        </Stage>
    );
}


export default PixiGame;
0

Yes I also struggled to get information for react on this. Had a sprite sheet without a json and created a function to generate the frame data. Adding on to the other answer is my code snippet

import React, { useRef, useState } from "react";

import KingHuman from "../../assets/mc.png";

import * as PIXI from 'pixi.js';
import { Stage, Container, AnimatedSprite } from '@inlet/react-pixi';

const generateFrames = (animationWidth, animationHeight, rowSize, colSize, fileWidth, fileHeight, imageName) => {
    let generated = {
        "frames": {},
        "meta": {
            "app": "Splash Software Assessment",
            "version": "1.0",
            "image": imageName,
            "format": "RGBA8888",
            "size": { "w": fileWidth, "h": fileHeight },
            "scale": "1",
            "smartupdate": ""
        }
    };

    for (let i = 0; i < rowSize; i++) {
        for (let j = 0; j < colSize; j++) {
            const px = animationWidth * i;
            const py = animationHeight * j;

            const image = `${imageName}${px}${py}.png`
            generated.frames[image] = {
                "frame": { "x": px, "y": py, "w": animationWidth, "h": animationHeight },
                "rotated": false,
                "trimmed": false,
                "spriteSourceSize": { "x": px, "y": py, "w": animationWidth, "h": animationHeight },
                "sourceSize": { "w": animationWidth, "h": animationHeight }
            }
        }
    }

    return generated;
};

const PixiGame = () => {
    const willMount = useRef(true);
    const [textures, setTextures] = useState([]);
    const KingHumanJson = generateFrames(240, 240, 4, 8, 1024, 2048, "mc.png")
    const loadSpritesheet = async () => {
        const baseTexture = PIXI.BaseTexture.from(KingHuman);
        const spritesheet = new PIXI.Spritesheet(baseTexture, KingHumanJson);
        const textures = await spritesheet.parse();
        setTextures(Object.keys(textures).map((t) => textures[t]));
    }

    // Hooks way to do ComponentWillMount
    if (willMount.current) {
        loadSpritesheet();
        willMount.current = false;
    }


    return (
        <Stage width={300} height={300} options={{ backgroundColor: 0xeef1f5 }}>
            <Container position={[150, 150]}>
                <AnimatedSprite
                    anchor={0.5}
                    textures={textures}
                    isPlaying={true}
                    initialFrame={0}
                    animationSpeed={0.1}
                />
            </Container>
        </Stage>
    );
}


export default PixiGame;