UNPKG

@bscotch/stitch

Version:

Stitch: The GameMaker Studio 2 Asset Pipeline Development Kit.

105 lines 4.39 kB
import { SpritelySubimage } from '@bscotch/spritely'; import { SpriteType } from '@bscotch/yy'; import { assert } from '../../../utility/errors.js'; import { debug } from '../../../utility/log.js'; import paths from '../../../utility/paths.js'; import { Gms2ResourceBase, } from './Gms2ResourceBase.js'; import { syncSpineSource, syncSpriteSource, } from './Gms2Sprite.update.js'; export class Gms2Sprite extends Gms2ResourceBase { constructor(...setup) { super('sprites', ...setup); } get isSpine() { return this.spriteType === SpriteType.Spine; } get textureGroup() { return this.yyData.textureGroupId.name; } set textureGroup(name) { this.yyData.textureGroupId.name = name; this.yyData.textureGroupId.path = `texturegroups/${name}`; this.save(); } /** Get the array of current frameIds, in their frame order. */ get frameIds() { return this.yyData.frames.map((frame) => frame.name); } get spriteType() { return this.yyData.type; } set spriteType(type) { this.yyData.type = type; } /** Force a layerId. Only updates the YY file, and only if there is only 1 layer. */ setLayerId(layerId) { assert(this.yyData.layers.length === 1, 'Cannot force the layerId if only one layer present.'); this.yyData.layers[0].name = layerId; return this; } /** * Update a sprite frame from a source image. If the frame * already has an identical image, this will return `undefined`. */ async updateFrameImage(imagePath, frameGuid) { assert(!this.isSpine, 'Cannot update frame images for Spine sprites this way.'); const framePath = paths.join(this.yyDirAbsolute, `${frameGuid}.png`); const frameLayerFolder = paths.join(this.yyDirAbsolute, 'layers', frameGuid); const layerId = this.yyData.layers[0].name; const frameLayerImagePath = paths.join(frameLayerFolder, `${layerId}.png`); this.storage.ensureDirSync(frameLayerFolder); // Only clobber if the image is meaningfully different const sourceImage = new SpritelySubimage(imagePath); const frame = new SpritelySubimage(framePath); if (!(await frame.exists()) || !(await frame.equals(sourceImage))) { debug(`Content mismatching, replaced ${framePath} with source.`); this.storage.copyFileSync(imagePath, framePath); this.storage.copyFileSync(imagePath, frameLayerImagePath); return frame; } else { debug(`Content matched source, leaving ${framePath} untouched.`); return; } } /** * Force the frames of this sprite to match the images * within a folder (non-recursive) */ async syncWithSource(spriteDirectoryOrSpineJson, isNew) { if (this.isSpine) { return await syncSpineSource.bind(this)(spriteDirectoryOrSpineJson); } else { return await syncSpriteSource.bind(this)(spriteDirectoryOrSpineJson, isNew); } } /** * Create a new sprite * @param subimageDirectory Absolute path to a directory containing the * subimages for this sprite. Will non-recursively * search for png images within that directory * and sort them alphabetically. */ static async create(subimageDirectory, comms, spriteName, /** Mutated based on outcomes of the sync step. */ results) { const sprite = new Gms2Sprite(spriteName || paths.subfolderName(subimageDirectory), comms); await sprite.replaceYyFile({ name: sprite.name, }); Object.assign(results || {}, await sprite.syncWithSource(subimageDirectory, true)); return sprite; } static async createFromSpine(spineJsonFile, comms, spriteName, /** Mutated based on outcomes of the sync step. */ results) { const sprite = new Gms2Sprite(spriteName || paths.subfolderName(spineJsonFile.directory), comms); await sprite.replaceYyFile({ type: SpriteType.Spine, name: sprite.name, }); Object.assign(results || {}, await sprite.syncWithSource(spineJsonFile.absolute, true)); return sprite; } } //# sourceMappingURL=Gms2Sprite.js.map