From 8a063850a5f7e50522e8257ce0c889dd78e3ed88 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Sun, 19 Jan 2025 14:28:23 -0600 Subject: [PATCH] sprite --- scripts/sprite.js | 220 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 scripts/sprite.js diff --git a/scripts/sprite.js b/scripts/sprite.js new file mode 100644 index 00000000..50e09a2f --- /dev/null +++ b/scripts/sprite.js @@ -0,0 +1,220 @@ +globalThis.so_sprite_qt = os.make_rtree(); + var sprite = { + image: undefined, + get diffuse() { return this.image; }, + set diffuse(x) {}, + set color(x) { + this._sprite.color = x; + }, + get color() { return this._sprite.color; }, + anim_speed: 1, + play(str, loop = true, reverse = false, fn) { + if (!this.animset) { +// console.warn(`Sprite has no animset when trying to play ${str}`); + fn?.(); + return; +// return parseq.imm(); + } + + if (typeof str === 'string') { + if (!this.animset[str]) { + fn?.(); + return; + } + this.anim = this.animset[str]; + } + + var playing = this.anim; + + var stop; + + this.del_anim?.(); + self.del_anim = function () { + self.del_anim = undefined; + self = undefined; + advance = undefined; + stop?.(); + }; + + var f = 0; + if (reverse) f = playing.frames.length - 1; + + function advance(time) { + if (!self) return; + + var done = false; + if (reverse) { + f = (((f - 1) % playing.frames.length) + playing.frames.length) % playing.frames.length; + if (f === playing.frames.length - 1) done = true; + } else { + f = (f + 1) % playing.frames.length; + if (f === 0) done = true; + } + + self.image = playing.frames[f]; + + if (done) { + // notify requestor + fn?.(); + if (!loop) { + self?.stop(); + return; + } + } + + return playing.frames[f].time/self.anim_speed; + } + stop = self.delay(advance, playing.frames[f].time/self.anim_speed); + advance(); + }, + tex_sync() { + if (this.anim) this.stop(); + if (!this.image) return + this.play(); + this.transform.scale = [this.image.texture.width, this.image.texture.height]; + this._sprite.set_image(this.image); + }, + stop() { + this.del_anim?.(); + }, + set path(p) { + + var image = game.texture(p); + if (!image) { + console.warn(`Could not find image ${p}.`); + return; + } + + this._p = p; + + this.del_anim?.(); + if (image.texture) + this.image = image; + else if (image.frames) { + // It's an animation + this.anim = image; + this.image = image.frames[0]; + this.animset = [this.anim] + } else { + // Maybe an animset; try to grab the first one + for (var anim in image) { + if (image[anim].frames) { + this.anim = image[anim]; + this.image = image[anim].frames[0]; + this.animset = image; + break; + } + } + } + + this.tex_sync(); + }, + get path() { + return this._p; + }, + garbage: function() { + console.log("KILLING SPRITE") + this.del_anim?.(); + this.anim = undefined; + so_sprite_qt.remove(this._sprite) + }, + anchor: [0, 0], + set layer(v) { this._sprite.layer = v; }, + get layer() { return this._sprite.layer; }, + pick() { + return this; + }, + boundingbox() { + var dim = this.dimensions(); + var realpos = dim.scale(0.5).add(this.pos); + return bbox.fromcwh(realpos, dim); + } +}; + +sprite.setanchor = function (anch) { + var off = [0, 0]; + switch (anch) { + case "ll": + break; + case "lm": + off = [-0.5, 0]; + break; + case "lr": + off = [-1, 0]; + break; + case "ml": + off = [0, -0.5]; + break; + case "mm": + off = [-0.5, -0.5]; + break; + case "mr": + off = [-1, -0.5]; + break; + case "ul": + off = [0, -1]; + break; + case "um": + off = [-0.5, -1]; + break; + case "ur": + off = [-1, -1]; + break; + } + this.anchor = off; + this.pos = this.dimensions().scale(off); +}; + +sprite.inputs = {}; +sprite.inputs.kp9 = function () { + this.setanchor("ll"); +}; +sprite.inputs.kp8 = function () { + this.setanchor("lm"); +}; +sprite.inputs.kp7 = function () { + this.setanchor("lr"); +}; +sprite.inputs.kp6 = function () { + this.setanchor("ml"); +}; +sprite.inputs.kp5 = function () { + this.setanchor("mm"); +}; +sprite.inputs.kp4 = function () { + this.setanchor("mr"); +}; +sprite.inputs.kp3 = function () { + this.setanchor("ur"); +}; +sprite.inputs.kp2 = function () { + this.setanchor("um"); +}; +sprite.inputs.kp1 = function () { + this.setanchor("ul"); +}; + +sprite.t_hook = function() { + console.log("SHIFT") + var msp = this.sprite; + so_sprite_qt.remove(msp); + msp.rect = this.torect() + msp.set_affine(this) + so_sprite_qt.insert(msp) + console.log("BOTTOM") +} + +return sprite; + +--- + +if (!this.overling.transform) throw new Error("Overling must have a transform to have a sprite") + +this.transform = os.make_transform(); +this.transform.parent = this.overling.transform; +this.transform.change_hook = $.t_hook; + +var msp = os.make_sprite(); +this._sprite = msp; +msp.color = Color.white; +this.transform.sprite = msp