311 lines
7.1 KiB
JavaScript
311 lines
7.1 KiB
JavaScript
var graphics = use('graphics')
|
|
|
|
var base_pipeline = {
|
|
vertex: "sprite.vert",
|
|
fragment: "sprite.frag",
|
|
primitive: "triangle", // point, line, linestrip, triangle, trianglestrip
|
|
fill: true, // false for lines
|
|
depth: {
|
|
compare: "greater_equal", // never/less/equal/less_equal/greater/not_equal/greater_equal/always
|
|
test: false,
|
|
write: false,
|
|
bias: 0,
|
|
bias_slope_scale: 0,
|
|
bias_clamp: 0
|
|
},
|
|
stencil: {
|
|
enabled: true,
|
|
front: {
|
|
compare: "equal", // never/less/equal/less_equal/greater/neq/greq/always
|
|
fail: "keep", // keep/zero/replace/incr_clamp/decr_clamp/invert/incr_wrap/decr_wrap
|
|
depth_fail: "keep",
|
|
pass: "keep"
|
|
},
|
|
back: {
|
|
compare: "equal", // never/less/equal/less_equal/greater/neq/greq/always
|
|
fail: "keep", // keep/zero/replace/incr_clamp/decr_clamp/invert/incr_wrap/decr_wrap
|
|
depth_fail: "keep",
|
|
pass: "keep"
|
|
},
|
|
test: true,
|
|
compare_mask: 0,
|
|
write_mask: 0
|
|
},
|
|
blend: {
|
|
enabled: false,
|
|
src_rgb: "zero", // zero/one/src_color/one_minus_src_color/dst_color/one_minus_dst_color/src_alpha/one_minus_src_alpha/dst_alpha/one_minus_dst_alpha/constant_color/one_minus_constant_color/src_alpha_saturate
|
|
dst_rgb: "zero",
|
|
op_rgb: "add", // add/sub/rev_sub/min/max
|
|
src_alpha: "one",
|
|
dst_alpha: "zero",
|
|
op_alpha: "add"
|
|
},
|
|
cull: "none", // none/front/back
|
|
face: "cw", // cw/ccw
|
|
alpha_to_coverage: false,
|
|
multisample: {
|
|
count: 1, // number of multisamples
|
|
mask: 0xFFFFFFFF,
|
|
domask: false
|
|
},
|
|
label: "scripted pipeline",
|
|
target: {}
|
|
}
|
|
|
|
var sprite_pipeline = Object.create(base_pipeline);
|
|
sprite_pipeline.blend = {
|
|
enabled:true,
|
|
src_rgb: "src_alpha", // zero/one/src_color/one_minus_src_color/dst_color/one_minus_dst_color/src_alpha/one_minus_src_alpha/dst_alpha/one_minus_dst_alpha/constant_color/one_minus_constant_color/src_alpha_saturate
|
|
dst_rgb: "one_minus_src_alpha",
|
|
op_rgb: "add", // add/sub/rev_sub/min/max
|
|
src_alpha: "one",
|
|
dst_alpha: "zero",
|
|
op_alpha: "add"
|
|
};
|
|
|
|
sprite_pipeline.target = {
|
|
color_targets: [{
|
|
format:"rgba8",
|
|
blend:sprite_pipeline.blend
|
|
}],
|
|
depth: "d32 float s8"
|
|
};
|
|
|
|
|
|
var sprite = {
|
|
image: undefined,
|
|
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) {
|
|
fn?.();
|
|
return;
|
|
}
|
|
|
|
if (typeof str === 'string') {
|
|
if (!this.animset[str]) {
|
|
fn?.();
|
|
return;
|
|
}
|
|
this.anim = this.animset[str];
|
|
}
|
|
|
|
var playing = this.anim;
|
|
|
|
var stop;
|
|
|
|
this.del_anim?.();
|
|
this.del_anim = () => {
|
|
this.del_anim = undefined;
|
|
advance = undefined;
|
|
stop?.();
|
|
};
|
|
|
|
var f = 0;
|
|
if (reverse) f = playing.frames.length - 1;
|
|
|
|
var advance = (time) => {
|
|
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;
|
|
}
|
|
|
|
this.image = playing.frames[f];
|
|
|
|
if (done) {
|
|
// notify requestor
|
|
fn?.();
|
|
if (!loop) {
|
|
this?.stop();
|
|
return;
|
|
}
|
|
}
|
|
|
|
return playing.frames[f].time/this.anim_speed;
|
|
}
|
|
stop = this.delay(advance, playing.frames[f].time/this.anim_speed);
|
|
advance();
|
|
},
|
|
stop() {
|
|
this.del_anim?.();
|
|
},
|
|
set path(p) {
|
|
var image = graphics.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]
|
|
this.play()
|
|
} 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;
|
|
this.play()
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
this.transform.scale = this.image.texture.dim //[this.image.texture.width, this.image.texture.height]
|
|
this._sprite.set_image(this.image)
|
|
},
|
|
get path() {
|
|
return this._p;
|
|
},
|
|
garbage: function() {
|
|
this.del_anim?.();
|
|
this.anim = undefined;
|
|
tree.delete(this._sprite)
|
|
this.transform.parent = undefined
|
|
for (var t of this.transform.children())
|
|
t.parent = undefined
|
|
delete this.transform.sprite
|
|
delete this._sprite
|
|
// console.log("CLEARED SPRITE")
|
|
},
|
|
anchor: [0, 0],
|
|
set layer(v) { this._sprite.layer = v; },
|
|
get layer() { return this._sprite.layer; },
|
|
pick() {
|
|
return this;
|
|
},
|
|
boundingbox() {
|
|
return Object.freeze(this._sprite.rect) // freeze so it can't be modified on the outside
|
|
}
|
|
};
|
|
|
|
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");
|
|
};
|
|
|
|
var tree = graphics.make_rtree()
|
|
sprite.tree = tree;
|
|
|
|
var IN = Symbol()
|
|
|
|
sprite.t_hook = function() {
|
|
var msp = this.sprite._sprite;
|
|
if (this[IN])
|
|
tree.delete(msp);
|
|
msp.rect = this.torect()
|
|
msp.set_affine(this)
|
|
tree.add(msp)
|
|
this[IN] = true
|
|
}
|
|
|
|
Object.mixin(sprite,use("transform"))
|
|
|
|
sprite.to_queue = function(ysort = false)
|
|
{
|
|
var pos = prosperon.camera.transform.pos;
|
|
var size = prosperon.camera.size;
|
|
var camrect = {
|
|
x:pos.x-size.x/2,
|
|
y:pos.y-size.y/2,
|
|
width:size.x,
|
|
height:size.y
|
|
};
|
|
var culled = sprite.tree.query(camrect)
|
|
if (culled.length == 0) return [];
|
|
var cmd = graphics.make_sprite_queue(culled, prosperon.camera, sprite_pipeline, 1);
|
|
return cmd;
|
|
}
|
|
|
|
return sprite;
|
|
|
|
---
|
|
|
|
var Color = use('color')
|
|
var os = use('os')
|
|
var graphics = use('graphics')
|
|
|
|
this.transform = os.make_transform();
|
|
if (this.overling.transform)
|
|
this.transform.parent = this.overling.transform;
|
|
|
|
this.transform.change_hook = $.t_hook;
|
|
var msp = graphics.make_sprite();
|
|
this._sprite = msp;
|
|
msp.color = Color.white;
|
|
this.transform.sprite = this
|
|
|
|
|