registry_sprite_registry.js
import Sprite from "./sprite/sprite.js";
import Util from "../util/misc/util.js";
import Vec2 from "../game/vector/vec2.js";
import SpritePartition from "./sprite/sprite_partition.js";
import Bounds from "../game/vector/bounds.js";
import LayeredSprite from "./sprite/layered_sprite.js";
/**
* @module SpriteRegistry
* @fileoverview Contains SpriteRegistry class.
*/
/**
* @class
* Global registry for sprites.
*/
class SpriteRegistry {
/**
* Create a new sprite registry.
* @constructor
*/
constructor() {
this._sprites = new Map();
this._configs = new Map();
this._wp = "";
}
/**
* Set the working directory for importing sprites.
* @param {string} p New working path
*/
path(p) {
const l = p.length - 1;
if (p[l] !== '/' && p[l] !== '\\')
p = p + "/";
this._wp = p;
}
_processConfigs(sprite, configs) {
let size = new Vec2(1, 1);
if ("#size" in configs) {
const val = configs["#size"];
if (typeof val === "number")
size = new Vec2(val, val);
else if (val instanceof Vec2)
size = val.copy();
delete configs["#size"];
}
const result = {};
for (const id of Object.keys(configs)) {
const config = configs[id];
if (config instanceof Array) {
const from = new Vec2(config[0], config[1]);
const to = from.addv(1, 1);
result[id] = new SpritePartition({
sprite: sprite,
bounds: new Bounds(from.mul(size).floor(), to.mul(size).floor())
})
} else if ("from" in config && "to" in config) {
const from = Vec2.from(config["from"]);
const to = Vec2.from(config["to"]);
result[id] = new SpritePartition({
sprite: sprite,
bounds: new Bounds(from.div(size).floor(), to.div(size).floor()),
});
} else if ("bounds" in config) {
result[id] = new SpritePartition({
sprite: sprite,
bounds: config["bounds"]
});
}
}
return result;
}
/**
* Add a new Sprite to the registry.
* @param {string} id The unique ID of the Sprite
* @param {string} src The image src of the Sprite
* @param {Object.<string, Object>} configs Custom partition configurations
* @param {number|null} width Default width of the Sprite (optional)
* @param {number|null} height Default height of the Sprite (optional)
*/
load(id, src, configs= {}, width = null, height = null) {
$$.loadInc();
Util.loadImage(this._wp + src, image => {
if (width === null)
width = image.width;
if (height === null)
height = image.height;
const sprite= new Sprite(image, width, height);
this._sprites.set(id, sprite);
this._configs.set(id, this._processConfigs(sprite, configs));
$$.loadDec();
})
}
/**
* Get a sprite with specified identifier.
* @param {string} id Identifier of sprite
* @returns {LayeredSprite|null} Sprite with specified identifier, or null if it does not exist.
*/
get(id) {
const sprites = [];
for (const layer of id.split("/")) {
const parts = layer.split(".");
const partID = parts.splice(0, 1)[0];
if (!this._sprites.has(partID))
continue;
if (parts[0] in this._configs.get(partID)) {
sprites.push(this._configs.get(partID)[parts[0]].copy());
continue;
}
sprites.push(new SpritePartition({
sprite: this._sprites.get(partID)
}));
}
if (sprites.length === 0)
return null;
return new LayeredSprite({
sprites: sprites
});
}
has(id) {
return this._sprites.has(id);
}
}
export default SpriteRegistry;