Skip to content

Instantly share code, notes, and snippets.

@jmschrack
Last active October 5, 2024 02:52
Show Gist options
  • Select an option

  • Save jmschrack/54dc70fda8a8821d555b2907a5837e51 to your computer and use it in GitHub Desktop.

Select an option

Save jmschrack/54dc70fda8a8821d555b2907a5837e51 to your computer and use it in GitHub Desktop.
EZSpritesheet handler for PIXI.JS
import { Assets, Spritesheet } from 'pixi.js'
/**
*
* @param {EZAtlasData} EZAtlasData
* @returns {SpritesheetDataExt}
*/
export function ConvertEZDataToPIXIData(EZAtlasData) {
/**@type {SpritesheetDataExt} */
const atlasData = {
frames: {},
meta: {
image: EZAtlasData.sheet[0].source,
format: 'RGBA8888',
size: {
w: EZAtlasData.sheet[0].width,
h: EZAtlasData.sheet[0].height
},
scale: 1
},
animations: {}
};
EZAtlasData.animation.forEach(a => {
atlasData.animations[a.name] = a.frame.map(f => `${a.name}_${f.index}`);
a.frame.forEach(f => {
atlasData.frames[`${a.name}_${f.index}`] = {
frame: { x: f.x, y: f.y, w: f.w, h: f.h },
sourceSize: { w: f.w, h: f.h },
spriteSourceSize: { x: 0 - f.ox, y: 0 - f.oy, w: f.w, h: f.h },
time: f.ms
}
})
})
return atlasData;
}
/**
*
* @param {Spritesheet} spritesheet
* @param {string} animationName
* @returns {import('pixi.js').FrameObject[]}
*/
export function GetFrameObjects(spritesheet, animationName) {
/**@type {SpritesheetDataExt} */
const atlasData = spritesheet.data;
return atlasData.animations[animationName].map(f => ({ texture: spritesheet.textures[f], time: atlasData.frames[f].time }));
}
/**
* @example
* const atlasData=await (await fetch('spritesheet.json')).json();
* const spritesheet = new EZSpritesheet(atlasData);
* await spritesheet.loadTextures();
* await spritesheet.parse();
*
* const animatedSprite = new AnimatedSprite(spritesheet.getAnimation("animationName"));
*/
export class EZSpritesheet {
/**
*
* @param {EZAtlasData} atlasData The json file data from the z64me/EzSpriteSheet tool
* @param {string?} [hostname=''] The hostname to prepend to the source paths,
*
*/
constructor(atlasData, hostname = '') {
this.data = atlasData;
this.hostname = hostname;
this._textures = []
/**@type {SpritesheetDataExt[]} */
this._atlases = []
}
/**
* Loads all textures referenced by the atlasData
*/
async loadTextures() {
this._textures = await Promise.all(this.data.sheet.map(async s => {
const t = await Assets.load(`${this.hostname}${s.source}`);
return t;
}));
}
/**
* Parses the atlasData into PIXI SpritesheetData and Spritesheet objects
*/
async parse() {
if(this._textures.length===0) await this.loadTextures();
this._atlases = this.data.sheet.map(s => ({
frames: {},
meta: {
image: s.source,
format: 'RGBA8888',
size: { w: s.width, h: s.height },
scale: 1
},
animations: {}
}))
this.data.animation.forEach((anim, i) => {
anim.frame.forEach((f, j) => {
this._atlases[f.sheet].frames[`${anim.name}_${j}`] = { frame: { x: f.x, y: f.y, w: f.w, h: f.h }, sourceSize: { w: f.w, h: f.h }, spriteSourceSize: { x: 0 - f.ox, y: 0 - f.oy, w: f.w, h: f.h } }
})
})
this._spritesheets = this._atlases.map((a, i) => new Spritesheet(this._textures[i], a))
await Promise.all(this._spritesheets.map(async s => await s.parse()))
}
/**
* Returns an array of FrameObjects for the given animation name to be used to create an AnimatedSprite
* @param {string} name
* @returns {import('pixi.js').FrameObject[]}
*
* @example
* const animatedSprite = new AnimatedSprite(spritesheet.getAnimation("animationName"));
*/
getAnimation(name) {
const animData = this.data.animation.find(a => a.name === name);
return animData.frame.map((f, i) => ({ texture: this._spritesheets[f.sheet].textures[`${name}_${i}`], time: f.ms }))
}
}
/**
* @typedef {import('pixi.js').SpritesheetData} SpritesheetDataPixi
*
* @typedef {import('pixi.js').SpritesheetData} SpritesheetFrameDataPixi
*/
/**
* @typedef {Object} EZAtlasData
* @property {number} sheets
* @property {number} animations
* @property {Sheet[]} sheet
* @property {EZAnimation[]} animation
*/
/**
* @typedef {Object} Sheet
* @property {number} index
* @property {number} width
* @property {number} height
* @property {string} source
*/
/**
* @typedef {Object} EZAnimation
* @property {string} name
* @property {number} frames
* @property {number} ms
* @property {Frame[]} frame
*/
/**
* @typedef {Object} Frame
* @property {number} index
* @property {number} sheet
* @property {number} x
* @property {number} y
* @property {number} w
* @property {number} h
* @property {number} ox
* @property {number} oy
* @property {number} ms
* @property {number} rot
*/
/**
* @typedef {Object} SpritesheetDataExt
* @extends SpritesheetDataPixi
* @property {Dict<SpritesheetFrameDataExt>} frames
*/
/**
* @typedef {SpritesheetFrameDataPixi} SpritesheetFrameDataExt
* @property {number} time
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment