Не удается запустить спрайт-анимацию в Pixijs на React
Я пытаюсь следовать руководству Pixijs, представленному здесь:
https://pixijs.github.io/examples/- и после небольшого рытья вот лист, который они используют для своего картографа текстур https://github.com/pixijs/examples/blob/gh-pages/required/assets/mc.json
Чтобы получить пример простого анимированного спрайта. Проблема, с которой я сталкиваюсь, заключается в том, что я почти точно следую и получаю сообщение об ошибке - я не знаю, что является причиной проблемы, и я не знаю, как продолжить отладку самостоятельно.
Пример имеет:
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);
}
Где у меня есть:
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);
}
}
Я получаю ошибку:
Error: the frameId “mario_characters1_46.png” does not exist in the texture cache
Это разочаровывает, так как мой json-файл texturepacker отображается правильно:
{"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$"
}
}
Если я console.log(PIXI.utils.TextureCache) я получаю:
{data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAQCAYAAAB6Hg0eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABUUlEQVRIx6VVPZqFIAxM/DwE1+B1WL5j0NrucWxtPcYr106uwS2yxQobMWB0aVSciTP5QYRikTVU7mGI+BT3lIdXJCmIFqcRVeP1fHN9xXzvrP/dCws46wG/FryLK9cdXpduvkegBE7Xg9vJE02etLhy/y6vE52F5eCMP2txkrg7POSOJDc1UVe4YT72rzZ+4qGU0mpjsj7Q4p7GF13lrGwG1leEYQakyVMiZvf7+1qWWnH5MEi8QwY0ZSsxrY+k7NQ4tUnNzZ8CcIKmRBk/vsFtBtxmxFI5689ZGd85RjbHDJxKc3Xw1coiYfOE7YZaByyPP8yAfesDYllZXznrAez+Yv60h+Xi1CdriJe1KzMg/U74M4aIJxNM1NNfUbn6v4aNhylaoTExISKBIdg+pwaGcJ7IFeKhIlx8TbRqvCVxUqYlPMfVjhO1MM3SiP+PuB9QuQ5f9MhyUAAAAABJRU5ErkJggg==: Texture}
Таким образом, может показаться, что ошибка говорит о том, что кэш текстуры видит только один блоб изображения - однако, вызывая Texture.fromFrame, как говорит пример на веб-сайте, чтобы заставить его работать, и я думаю, что я очень близко воспроизводлю код,
Если у кого-то есть идеи, пожалуйста, дайте мне знать.
2 ответа
Да, я также изо всех сил пытался получить информацию для реакции на это. Имел лист спрайтов без json и создал функцию для генерации данных кадра. Добавление к другому ответу - это мой фрагмент кода
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;
Было непросто найти пример с React, если это кому-то поможет.
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;