@pixelation/engine
Version:
A simple pixel art game engine.
1,515 lines • 50.7 kB
JavaScript
var Y = Object.defineProperty;
var K = (h, t, e) => t in h ? Y(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e;
var u = (h, t, e) => K(h, typeof t != "symbol" ? t + "" : t, e);
import { Aseprite as T, AsepriteColorDepth as $, AsepriteTagAnimationDirection as I } from "@pixelation/aseprite";
const R = () => {
}, D = (h) => {
const t = new ArrayBuffer(h.byteLength);
return new Uint8Array(t).set(new Uint8Array(h)), t;
}, Lt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
cloneArrayBuffer: D,
noop: R
}, Symbol.toStringTag, { value: "Module" }));
class L {
constructor(t, e, s = {
track: "main",
strategy: "once"
}) {
u(this, "ready", !1);
u(this, "queued", !1);
u(this, "playing", !1);
u(this, "duration", 0);
u(this, "position", 0);
u(this, "started", 0);
u(this, "source");
this.audio = t, this.raw = e, this.options = s, s.track || (s.track = "main"), s.strategy || (s.strategy = "once"), t.assets.push(this), this.source = new AudioBufferSourceNode(t.context, {
loop: s.strategy === "loop" || s.strategy === "loop-restart"
}), this.source.connect(t[s.track]), this.source.onended = () => {
this.stop();
}, t.context.decodeAudioData(D(e), (n) => {
this.source.buffer = n, this.ready = !0, this.duration = n.duration, this.position = 0, this.queued && this.play();
});
}
destroy() {
const t = this.audio.assets.indexOf(this);
t !== -1 && (this.audio.assets = this.audio.assets.splice(t, 1)), this.source.disconnect(), this.source.buffer = null;
}
update() {
const t = this.audio.context.currentTime - this.started;
this.position = t % this.duration, this.playing && t >= this.duration && !this.source.loop && this.stop();
}
clone() {
return new L(this.audio, this.raw, this.options);
}
play() {
if (!this.ready) {
this.queued = !0;
return;
}
if (this.playing)
if (this.options.strategy === "once-restart" || this.options.strategy === "loop-restart")
this.source.stop();
else
return;
this.started = this.audio.context.currentTime + 0.01, this.source.start(this.started);
}
stop() {
if (!this.ready) {
this.queued = !1;
return;
}
this.source.stop(), this.started = 0, this.position = 0;
}
}
class _ {
constructor() {
u(this, "context", new AudioContext());
u(this, "main", this.context.createGain());
u(this, "sfx", this.context.createGain());
u(this, "speech", this.context.createGain());
u(this, "music", this.context.createGain());
u(this, "assets", []);
this.main.connect(this.context.destination), this.main.gain.value = 1, this.sfx.connect(this.main), this.main.gain.value = 1, this.speech.connect(this.main), this.main.gain.value = 1, this.music.connect(this.main), this.main.gain.value = 1;
}
asset(t, e = {
track: "main",
strategy: "once"
}) {
return e.track || (e.track = "main"), e.strategy || (e.strategy = "once"), new L(this, t, e);
}
volume(t, e) {
this[t].gain.value = e;
}
once(t) {
const e = t.clone();
e.play();
const s = e.update.bind(e);
e.update = () => {
s(), e.playing || e.destroy();
};
}
play(t) {
const e = t.clone();
return e.play(), e;
}
update() {
for (const t of this.assets)
t.update();
}
}
const Ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
Audio: _,
AudioAsset: L
}, Symbol.toStringTag, { value: "Module" })), g = (h, t, e, s) => {
let n = 0;
return n |= h << 24, n |= t << 16, n |= e << 8, n |= s, n;
}, x = (h) => [
h >> 24 & 255,
h >> 16 & 255,
h >> 8 & 255,
h & 255
], N = /^#(?:(?<full>[a-fA-F0-9]{6})|(?:(?<short>[a-fA-F0-9]{3})))$/, U = (h) => {
const t = N.exec(h);
if (!t || !t.groups)
throw new Error(`Invalid hex color: ${h}`);
if (t.groups.short)
return g(
parseInt(t.groups.short[0] + t.groups.short[0], 16),
parseInt(t.groups.short[1] + t.groups.short[1], 16),
parseInt(t.groups.short[2] + t.groups.short[2], 16),
255
);
if (t.groups.full)
return g(
parseInt(t.groups.full[0] + t.groups.full[1], 16),
parseInt(t.groups.full[2] + t.groups.full[3], 16),
parseInt(t.groups.full[4] + t.groups.full[5], 16),
255
);
throw new Error(`Invalid hex color: ${h}`);
}, J = (h, t, e) => g(h, t, e, 255), z = (h, t) => {
if (t instanceof Uint8Array)
return t.length === 4 ? g(t[0], t[1], t[2], 255) : g(t[0], t[0], t[0], 255);
{
const e = h.palette[String(t)];
return e ? g(e.red, e.green, e.blue, 255) : (console.warn(`Invalid color index: ${t}`), B);
}
}, P = (h, t, e) => (e < 0 && (e += 1), e > 1 && (e -= 1), e < 1 / 6 ? h + (t - h) * 6 * e : e < 1 / 2 ? t : e < 2 / 3 ? h + (t - h) * (2 / 3 - e) * 6 : h), W = (h, t, e) => {
let s = 0, n = 0, d = 0;
if (t === 0)
s = e, n = e, d = e;
else {
const a = e < 0.5 ? e * (1 + t) : e + t - e * t, i = 2 * e - a;
s = P(i, a, h + 1 / 3), n = P(i, a, h), d = P(i, a, h - 1 / 3);
}
return g(
Math.round(s * 255),
Math.round(n * 255),
Math.round(d * 255),
255
);
}, Z = (h, t, e, s, n = 255) => {
let d = h * (1 - s) + s, a = t * (1 - s) + s, i = e * (1 - s) + s;
return g(
Math.round((1 - d) * 255 + 0.5),
Math.round((1 - a) * 255 + 0.5),
Math.round((1 - i) * 255 + 0.5),
n
);
}, E = (h, t) => {
const [e, s, n, d] = x(t), [a, i, r, l] = x(h), o = d / 255, c = l / 255, f = o + c * (1 - o);
if (f === 0)
return g(0, 0, 0, 0);
const p = (e * o + a * c * (1 - o)) / f, m = (s * o + i * c * (1 - o)) / f, y = (n * o + r * c * (1 - o)) / f;
return g(
Math.round(p),
Math.round(m),
Math.round(y),
Math.round(f * 255)
);
}, B = U("#c84cc6"), $t = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
PLACEHOLDER: B,
blend: E,
fromAsepritePixel: z,
fromCmyk: Z,
fromHex: U,
fromHsl: W,
fromRgb: J,
pack: g,
unpack: x
}, Symbol.toStringTag, { value: "Module" }));
var F = /* @__PURE__ */ ((h) => (h.Position = "p", h.Velocity = "v", h.Step = "s", h))(F || {});
const V = (h = 0, t = 0.5, e = 0.1, s = 0.1) => {
let n = 0;
const d = (i) => {
const r = (i - h) * e;
n += r, n *= t, h += n, n < s && n > -s && r < s && r > -s && (h = i, n = 0);
};
function a(i, r) {
if (arguments.length === 0)
return h;
switch (i) {
case "p":
return r !== void 0 && (h = r), h;
case "v":
return r !== void 0 && n + r <= s && n + r >= -s && (n = r), n;
}
return arguments.length === 1 && (i === "s" ? d(h) : typeof i == "number" && d(i)), h;
}
return a;
}, tt = (h, t, e) => (1 - e) * h + e * t, et = (h, t, e, s) => {
if (h === t)
return h;
const n = t + (h - t) * Math.exp(-e * s);
return Math.abs(n - h) < 1e-3 ? t : n;
}, it = (h, t, e) => g(
...G(x(h), x(t), e)
), G = (h, t, e) => [
Math.round(h[0] + (t[0] - h[0]) * e),
Math.round(h[1] + (t[1] - h[1]) * e),
Math.round(h[2] + (t[2] - h[2]) * e),
Math.round(h[3] + (t[3] - h[3]) * e)
], st = (h) => h * h, at = (h) => h * (2 - h), nt = (h) => h < 0.5 ? 2 * h * h : -1 + (4 - 2 * h) * h, ht = (h) => h * h * h, rt = (h) => --h * h * h + 1, dt = (h) => (h /= 0.5) < 1 ? 0.5 * h * h * h : 0.5 * ((h -= 2) * h * h + 2), lt = (h) => h * h * h * h, ot = (h) => 1 - --h * h * h * h, ft = (h) => (h /= 0.5) < 1 ? 0.5 * h * h * h * h : -0.5 * ((h -= 2) * h * h * h - 2), ct = (h) => h * h * h * h * h, pt = (h) => 1 + --h * h * h * h * h, ut = (h) => (h /= 0.5) < 1 ? 0.5 * h * h * h * h * h : 0.5 * ((h -= 2) * h * h * h * h + 2), gt = (h) => 1 - Math.cos(h * Math.PI / 2), mt = (h) => Math.sin(h * Math.PI / 2), wt = (h) => 0.5 * (1 - Math.cos(Math.PI * h)), yt = (h) => h === 0 ? 0 : Math.pow(2, 10 * (h - 1)), Mt = (h) => h === 1 ? 1 : 1 - Math.pow(2, -10 * h), bt = (h) => h === 0 || h === 1 ? h : (h /= 0.5) < 1 ? 0.5 * Math.pow(2, 10 * (h - 1)) : 0.5 * (2 - Math.pow(2, -10 * --h)), xt = (h) => 1 - Math.sqrt(1 - h * h), vt = (h) => Math.sqrt(1 - --h * h), It = (h) => (h /= 0.5) < 1 ? -0.5 * (Math.sqrt(1 - h * h) - 1) : 0.5 * (Math.sqrt(1 - (h -= 2) * h) + 1), Pt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
SmoothUpdateKind: F,
easeIn: st,
easeInCirc: xt,
easeInCubic: ht,
easeInExpo: yt,
easeInOut: nt,
easeInOutCirc: It,
easeInOutCubic: dt,
easeInOutExpo: bt,
easeInOutQuart: ft,
easeInOutQuint: ut,
easeInOutSine: wt,
easeInQuart: lt,
easeInQuint: ct,
easeInSine: gt,
easeOut: at,
easeOutCirc: vt,
easeOutCubic: rt,
easeOutExpo: Mt,
easeOutQuart: ot,
easeOutQuint: pt,
easeOutSine: mt,
lerp: tt,
lerpColor: it,
lerpColorUnpacked: G,
lerpSmooth: et,
smooth: V
}, Symbol.toStringTag, { value: "Module" })), b = class b {
constructor(t) {
u(this, "data");
if (t.length === 0)
throw new Error("Matrix3 requires 9 elements, but got none.");
if (Array.isArray(t[0]) ? this.data = t.flat() : this.data = t, this.data.length !== 9)
throw new Error(
`Matrix3 requires 9 elements, but got ${this.data.length}.`
);
}
static fromTranslation(t, e) {
return new b([
[1, 0, t],
[0, 1, e],
[0, 0, 1]
]);
}
static fromScale(t, e) {
return new b([
[t, 0, 0],
[0, e, 0],
[0, 0, 1]
]);
}
static fromRotation(t) {
const e = Math.cos(t), s = Math.sin(t);
return new b([
[e, -s, 0],
[s, e, 0],
[0, 0, 1]
]);
}
static fromSkew(t, e) {
return new b([
[1, Math.tan(t), 0],
[Math.tan(e), 1, 0],
[0, 0, 1]
]);
}
toString() {
const [
t,
e,
s,
n,
d,
a,
i,
r,
l
] = this.data, o = Math.max(
t.toString().length,
n.toString().length,
i.toString().length
), c = Math.max(
e.toString().length,
d.toString().length,
r.toString().length
), f = Math.max(
s.toString().length,
a.toString().length,
l.toString().length
), p = `${t.toString().padEnd(o)} ${e.toString().padEnd(c)} ${s.toString().padEnd(f)}`, m = `${n.toString().padEnd(o)} ${d.toString().padEnd(c)} ${a.toString().padEnd(f)}`, y = `${i.toString().padEnd(o)} ${r.toString().padEnd(c)} ${l.toString().padEnd(f)}`, M = p.length;
return `┌ ${" ".repeat(
M
)} ┐
│ ${p} │
│ ${m} │
│ ${y} │
└ ${" ".repeat(
M
)} ┘`;
}
isIdentity() {
if (this === b.identity) return !0;
const [t, e, s, n, d, a, i, r, l] = this.data;
return t === 1 && e === 0 && s === 0 && n === 0 && d === 1 && a === 0 && i === 0 && r === 0 && l === 1;
}
mul(t) {
const e = this.data, s = t.data, n = [
e[0] * s[0] + e[1] * s[3] + e[2] * s[6],
e[0] * s[1] + e[1] * s[4] + e[2] * s[7],
e[0] * s[2] + e[1] * s[5] + e[2] * s[8],
e[3] * s[0] + e[4] * s[3] + e[5] * s[6],
e[3] * s[1] + e[4] * s[4] + e[5] * s[7],
e[3] * s[2] + e[4] * s[5] + e[5] * s[8],
e[6] * s[0] + e[7] * s[3] + e[8] * s[6],
e[6] * s[1] + e[7] * s[4] + e[8] * s[7],
e[6] * s[2] + e[7] * s[5] + e[8] * s[8]
];
return new b(n);
}
translate(t, e) {
return new b([
[1, 0, t],
[0, 1, e],
[0, 0, 1]
]).mul(this);
}
scale(t, e) {
return new b([
[t, 0, 0],
[0, e, 0],
[0, 0, 1]
]).mul(this);
}
rotate(t) {
const e = Math.cos(t), s = Math.sin(t);
return new b([
[e, -s, 0],
[s, e, 0],
[0, 0, 1]
]).mul(this);
}
skew(t, e) {
return new b([
[1, Math.tan(t), 0],
[Math.tan(e), 1, 0],
[0, 0, 1]
]).mul(this);
}
inv() {
const [
t,
e,
s,
n,
d,
a,
i,
r,
l
] = this.data, o = t * (d * l - a * r) - e * (n * l - a * i) + s * (n * r - d * i);
if (o === 0)
throw new Error("Matrix3 is not invertible.");
const c = 1 / o;
return new b([
(d * l - a * r) * c,
(s * r - e * l) * c,
(e * a - s * d) * c,
(a * i - n * l) * c,
(t * l - s * i) * c,
(s * n - t * a) * c,
(n * r - d * i) * c,
(e * i - t * r) * c,
(t * d - e * n) * c
]);
}
apply(t, e) {
const [
s,
n,
d,
a,
i,
r,
l,
o,
c
] = this.data;
return {
x: s * t + n * e + d,
y: a * t + i * e + r
};
}
applyToRect(t, e, s, n) {
const d = this.apply(t, e), a = this.apply(t + s, e), i = this.apply(t + s, e + n), r = this.apply(t, e + n), l = Math.min(d.x, a.x, i.x, r.x), o = Math.max(d.x, a.x, i.x, r.x), c = Math.min(d.y, a.y, i.y, r.y), f = Math.max(d.y, a.y, i.y, r.y);
return {
x: l,
y: c,
width: o - l,
height: f - c
};
}
};
u(b, "identity", new b([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]
]));
let w = b;
class S {
constructor(t, e) {
this.x = t, this.y = e;
}
add(t) {
return new S(this.x + t.x, this.y + t.y);
}
sub(t) {
return new S(this.x - t.x, this.y - t.y);
}
mul(t) {
return new S(this.x * t, this.y * t);
}
div(t) {
return new S(this.x / t, this.y / t);
}
mag() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
norm() {
const t = this.mag();
return new S(this.x / t, this.y / t);
}
}
const O = (h, t, e, s, n, d, a, i) => {
const r = (h * (i - s) - t * (a - e) + a * s - i * e) / ((n - e) * (i - s) - (d - s) * (a - e)), l = (t - s - r * (d - s)) / (i - s);
return !(r < 0 || l < 0 || r + l > 1);
}, jt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
Matrix3: w,
Vector2: S,
isPointInTri: O
}, Symbol.toStringTag, { value: "Module" }));
class St {
constructor(t, e, s = new ImageData(t, e)) {
u(this, "virtual", !1);
u(this, "canvas");
u(this, "context");
this.width = t, this.height = e, this.image = s, this.canvas = document.createElement("canvas"), this.canvas.setAttribute("tabindex", "0"), this.canvas.style.imageRendering = "pixelated", this.canvas.width = t, this.canvas.height = e, this.context = this.canvas.getContext("2d"), this.context.imageSmoothingEnabled = !1;
}
commit() {
this.context.putImageData(this.image, 0, 0);
}
clear() {
for (let t = 0; t < this.image.data.length; t += 4)
this.image.data[t + 0] = 0, this.image.data[t + 1] = 0, this.image.data[t + 2] = 0, this.image.data[t + 3] = 255;
}
pixel(t, e, s) {
if (t < 0 || t >= this.width || e < 0 || e >= this.height) return;
const [n, d, a, i] = x(s);
t |= 0, e |= 0;
const r = (e * this.width + t) * 4;
if (i === 255)
this.image.data[r + 0] = n, this.image.data[r + 1] = d, this.image.data[r + 2] = a, this.image.data[r + 3] = i;
else if (i > 0) {
const l = x(
E(
g(
this.image.data[r + 0],
this.image.data[r + 1],
this.image.data[r + 2],
this.image.data[r + 3]
),
s
)
);
this.image.data[r + 0] = l[0], this.image.data[r + 1] = l[1], this.image.data[r + 2] = l[2], this.image.data[r + 3] = l[3];
}
}
pixelUnpacked(t, e, s, n, d, a) {
if (t < 0 || t >= this.width || e < 0 || e >= this.height) return;
t |= 0, e |= 0;
const i = (e * this.width + t) * 4;
if (a === 255)
this.image.data[i + 0] = s, this.image.data[i + 1] = n, this.image.data[i + 2] = d, this.image.data[i + 3] = a;
else if (a > 0) {
const r = x(
E(
g(
this.image.data[i + 0],
this.image.data[i + 1],
this.image.data[i + 2],
this.image.data[i + 3]
),
g(s, n, d, a)
)
);
this.image.data[i + 0] = r[0], this.image.data[i + 1] = r[1], this.image.data[i + 2] = r[2], this.image.data[i + 3] = r[3];
}
}
blit(t, e = 0, s = 0, n = w.identity) {
if (n.isIdentity()) {
for (let d = 0; d < t.height; d++)
if (!(d + s < 0 || d + s >= this.height))
for (let a = 0; a < t.width; a++) {
if (a + e < 0 || a + e >= this.width)
continue;
const i = (d * t.width + a) * 4;
this.pixelUnpacked(
a + e,
d + s,
t.data[i + 0],
t.data[i + 1],
t.data[i + 2],
t.data[i + 3]
);
}
} else {
const d = n.applyToRect(
e,
s,
t.width,
t.height
), a = n.inv();
for (let i = Math.floor(d.y); i < Math.ceil(d.y + d.height); i++)
for (let r = Math.floor(d.x); r < Math.ceil(d.x + d.width); r++) {
const l = a.apply(r, i);
if (l.x -= e, l.y -= s, l.x < 0 || l.x >= t.width || l.y < 0 || l.y >= t.height)
continue;
const o = (Math.floor(l.y) * t.width + Math.floor(l.x)) * 4;
this.pixel(
r,
i,
g(
t.data[o + 0],
t.data[o + 1],
t.data[o + 2],
t.data[o + 3]
)
);
}
}
}
blitMask(t, e, s = 0, n = 0, d = w.identity) {
if (d.isIdentity()) {
for (let a = 0; a < t.height; a++)
if (!(a + n < 0 || a + n >= this.height))
for (let i = 0; i < t.width; i++) {
if (i + s < 0 || i + s >= this.width)
continue;
const r = (a * e.width + i) * 4;
if (r + 3 >= e.data.length)
continue;
const l = (a * t.width + i) * 4;
e.data[r] === 255 && e.data[r + 1] === 255 && e.data[r + 2] === 255 && e.data[r + 3] === 255 && this.pixelUnpacked(
i + s,
a + n,
t.data[l + 0],
t.data[l + 1],
t.data[l + 2],
t.data[l + 3]
);
}
} else {
const a = d.applyToRect(
s,
n,
t.width,
t.height
), i = d.inv();
for (let r = Math.floor(a.y); r < Math.ceil(a.y + a.height); r++)
for (let l = Math.floor(a.x); l < Math.ceil(a.x + a.width); l++) {
const o = i.apply(l, r);
if (o.x -= s, o.y -= n, o.x < 0 || o.x >= t.width || o.y < 0 || o.y >= t.height)
continue;
const c = (Math.floor(o.y) * e.width + Math.floor(o.x)) * 4;
if (c + 3 >= e.data.length)
continue;
const f = (Math.floor(o.y) * t.width + Math.floor(o.x)) * 4;
e.data[c] === 255 && e.data[c + 1] === 255 && e.data[c + 2] === 255 && e.data[c + 3] === 255 && this.pixel(
l,
r,
g(
t.data[f + 0],
t.data[f + 1],
t.data[f + 2],
t.data[f + 3]
)
);
}
}
}
line(t, e, s, n, d) {
if (t |= 0, e |= 0, s |= 0, n |= 0, t - s === 0) {
for (let f = e; f <= n; f++)
this.pixel(t, f, d);
return;
}
if (e - n === 0) {
for (let f = t; f <= s; f++)
this.pixel(f, e, d);
return;
}
t > s && ([t, s] = [s, t], [e, n] = [n, e]);
const a = (n - e) / (s - t);
if (a === 1)
if (e > n) {
for (let f = t, p = e; f <= s; f++, p--)
this.pixel(f, p, d);
return;
} else {
for (let f = t, p = e; f <= s; f++, p++)
this.pixel(f, p, d);
return;
}
if (a === -1)
if (e > n) {
for (let f = t, p = e; f <= s; f++, p--)
this.pixel(f, p, d);
return;
} else {
for (let f = t, p = e; f <= s; f++, p++)
this.pixel(f, p, d);
return;
}
const i = Math.abs(s - t), r = Math.abs(n - e), l = Math.sign(s - t), o = Math.sign(n - e);
let c = i - r;
for (; ; ) {
if (this.pixel(t, e, d), t === s && e === n)
return;
const f = 2 * c;
f > -r && (c -= r, t += l), f < i && (c += i, e += o);
}
}
fillRect(t, e, s, n, d, a = w.identity) {
if (a.isIdentity())
for (let i = t; i < t + s; i++)
for (let r = e; r < e + n; r++)
this.pixel(i, r, d);
else {
const i = a.applyToRect(t, e, s, n), r = a.inv();
for (let l = i.x; l < i.x + i.width; l++)
for (let o = i.y; o < i.y + i.height; o++) {
const c = r.apply(l, o);
c.x >= t && c.x < t + s && c.y >= e && c.y < e + n && this.pixel(l, o, d);
}
}
}
traceRect(t, e, s, n, d, a = w.identity) {
if (a.isIdentity())
this.line(t, e, t + s, e, d), this.line(t + s, e, t + s, e + n, d), this.line(t, e + n, t + s, e + n, d), this.line(t, e, t, e + n, d);
else {
const i = a.apply(t, e), r = a.apply(t + s, e), l = a.apply(t, e + n), o = a.apply(t + s, e + n);
this.line(i.x, i.y, r.x, r.y, d), this.line(r.x, r.y, o.x, o.y, d), this.line(o.x, o.y, l.x, l.y, d), this.line(l.x, l.y, i.x, i.y, d);
}
}
fillCirc(t, e, s, n, d = w.identity) {
if (d.isIdentity()) {
let a = s, i = 0, r = 1 - s;
for (; a >= i; )
this.line(-a + t, -i + e, -a + t, i + e, n), this.line(-i + t, -a + e, -i + t, a + e, n), this.line(i + t, -a + e, i + t, a + e, n), this.line(a + t, -i + e, a + t, i + e, n), i++, r < 0 ? r += 2 * i + 1 : (a--, r += 2 * (i - a + 1));
} else {
const a = s * 2 + 1, i = d.applyToRect(t - a / 2, e - a / 2, a, a), r = d.inv();
for (let l = Math.floor(i.x); l < Math.ceil(i.x + i.width); l++)
for (let o = Math.floor(i.y); o < Math.ceil(i.y + i.height); o++) {
const c = r.apply(l, o);
Math.sqrt(
(c.x - t) ** 2 + (c.y - e) ** 2
) <= a / 2 && this.pixel(l, o, n);
}
}
}
traceCirc(t, e, s, n, d = w.identity) {
if (d.isIdentity()) {
let a = s, i = 0, r = 1 - s;
for (; a >= i; )
this.pixel(a + t, i + e, n), this.pixel(i + t, a + e, n), this.pixel(-a + t, i + e, n), this.pixel(-i + t, a + e, n), this.pixel(-a + t, -i + e, n), this.pixel(-i + t, -a + e, n), this.pixel(a + t, -i + e, n), this.pixel(i + t, -a + e, n), i++, r < 0 ? r += 2 * i + 1 : (a--, r += 2 * (i - a + 1));
} else {
const a = s * 2 + 1, i = d.applyToRect(t - a / 2, e - a / 2, a, a), r = d.inv();
for (let l = Math.floor(i.x); l < Math.ceil(i.x + i.width); l++)
for (let o = Math.floor(i.y); o < Math.ceil(i.y + i.height); o++) {
const c = r.apply(l, o), f = Math.sqrt(
(c.x - t) ** 2 + (c.y - e) ** 2
);
Math.abs(f - s) < 0.58 && this.pixel(l, o, n);
}
}
}
fillTri(t, e, s, n, d, a, i, r = w.identity) {
const l = Math.min(t, s, d), o = Math.max(t, s, d), c = Math.min(e, n, a), f = Math.max(e, n, a);
if (r.isIdentity())
for (let p = Math.floor(l); p < Math.ceil(o); p++)
for (let m = Math.floor(c); m < Math.ceil(f); m++)
O(p, m, t, e, s, n, d, a) && this.pixel(p, m, i);
else {
const p = r.applyToRect(
l,
c,
o - l,
f - c
), m = r.inv();
for (let y = Math.floor(p.x); y < Math.ceil(p.x + p.width); y++)
for (let M = Math.floor(p.y); M < Math.ceil(p.y + p.height); M++) {
const v = m.apply(y, M);
O(
v.x,
v.y,
t,
e,
s,
n,
d,
a
) && this.pixel(y, M, i);
}
}
}
traceTri(t, e, s, n, d, a, i, r = w.identity) {
if (r.isIdentity())
this.line(t, e, s, n, i), this.line(s, n, d, a, i), this.line(d, a, t, e, i);
else {
const l = r.apply(t, e), o = r.apply(s, n), c = r.apply(d, a);
this.line(l.x, l.y, o.x, o.y, i), this.line(o.x, o.y, c.x, c.y, i), this.line(c.x, c.y, l.x, l.y, i);
}
}
}
class kt {
constructor(t, e, s = new ImageData(t, e)) {
u(this, "virtual", !0);
u(this, "canvas");
u(this, "context");
this.width = t, this.height = e, this.image = s, this.canvas = new OffscreenCanvas(t, e), this.context = this.canvas.getContext("2d");
}
commit() {
this.context.putImageData(this.image, 0, 0);
}
clear() {
for (let t = 0; t < this.image.data.length; t += 4)
this.image.data[t + 0] = 0, this.image.data[t + 1] = 0, this.image.data[t + 2] = 0, this.image.data[t + 3] = 255;
}
pixel(t, e, s) {
if (t < 0 || t >= this.width || e < 0 || e >= this.height) return;
const [n, d, a, i] = x(s);
t |= 0, e |= 0;
const r = (e * this.width + t) * 4;
if (i === 255)
this.image.data[r + 0] = n, this.image.data[r + 1] = d, this.image.data[r + 2] = a, this.image.data[r + 3] = i;
else if (i > 0) {
const l = x(
E(
g(
this.image.data[r + 0],
this.image.data[r + 1],
this.image.data[r + 2],
this.image.data[r + 3]
),
s
)
);
this.image.data[r + 0] = l[0], this.image.data[r + 1] = l[1], this.image.data[r + 2] = l[2], this.image.data[r + 3] = l[3];
}
}
pixelUnpacked(t, e, s, n, d, a) {
if (t < 0 || t >= this.width || e < 0 || e >= this.height) return;
t |= 0, e |= 0;
const i = (e * this.width + t) * 4;
if (a === 255)
this.image.data[i + 0] = s, this.image.data[i + 1] = n, this.image.data[i + 2] = d, this.image.data[i + 3] = a;
else if (a > 0) {
const r = x(
E(
g(
this.image.data[i + 0],
this.image.data[i + 1],
this.image.data[i + 2],
this.image.data[i + 3]
),
g(s, n, d, a)
)
);
this.image.data[i + 0] = r[0], this.image.data[i + 1] = r[1], this.image.data[i + 2] = r[2], this.image.data[i + 3] = r[3];
}
}
blit(t, e = 0, s = 0, n = w.identity) {
if (n.isIdentity()) {
for (let d = 0; d < t.height; d++)
if (!(d + s < 0 || d + s >= this.height))
for (let a = 0; a < t.width; a++) {
if (a + e < 0 || a + e >= this.width)
continue;
const i = (d * t.width + a) * 4;
this.pixelUnpacked(
a + e,
d + s,
t.data[i + 0],
t.data[i + 1],
t.data[i + 2],
t.data[i + 3]
);
}
} else {
const d = n.applyToRect(
e,
s,
t.width,
t.height
), a = n.inv();
for (let i = Math.floor(d.y); i < Math.ceil(d.y + d.height); i++)
for (let r = Math.floor(d.x); r < Math.ceil(d.x + d.width); r++) {
const l = a.apply(r, i);
if (l.x -= e, l.y -= s, l.x < 0 || l.x >= t.width || l.y < 0 || l.y >= t.height)
continue;
const o = (Math.floor(l.y) * t.width + Math.floor(l.x)) * 4;
this.pixel(
r,
i,
g(
t.data[o + 0],
t.data[o + 1],
t.data[o + 2],
t.data[o + 3]
)
);
}
}
}
blitMask(t, e, s = 0, n = 0, d = w.identity) {
if (d.isIdentity()) {
for (let a = 0; a < t.height; a++)
if (!(a + n < 0 || a + n >= this.height))
for (let i = 0; i < t.width; i++) {
if (i + s < 0 || i + s >= this.width)
continue;
const r = (a * e.width + i) * 4;
if (r + 3 >= e.data.length)
continue;
const l = (a * t.width + i) * 4;
e.data[r] === 255 && e.data[r + 1] === 255 && e.data[r + 2] === 255 && e.data[r + 3] === 255 && this.pixelUnpacked(
i + s,
a + n,
t.data[l + 0],
t.data[l + 1],
t.data[l + 2],
t.data[l + 3]
);
}
} else {
const a = d.applyToRect(
s,
n,
t.width,
t.height
), i = d.inv();
for (let r = Math.floor(a.y); r < Math.ceil(a.y + a.height); r++)
for (let l = Math.floor(a.x); l < Math.ceil(a.x + a.width); l++) {
const o = i.apply(l, r);
if (o.x -= s, o.y -= n, o.x < 0 || o.x >= t.width || o.y < 0 || o.y >= t.height)
continue;
const c = (Math.floor(o.y) * e.width + Math.floor(o.x)) * 4;
if (c + 3 >= e.data.length)
continue;
const f = (Math.floor(o.y) * t.width + Math.floor(o.x)) * 4;
e.data[c] === 255 && e.data[c + 1] === 255 && e.data[c + 2] === 255 && e.data[c + 3] === 255 && this.pixel(
l,
r,
g(
t.data[f + 0],
t.data[f + 1],
t.data[f + 2],
t.data[f + 3]
)
);
}
}
}
line(t, e, s, n, d) {
if (t - s === 0) {
for (let f = e; f <= n; f++)
this.pixel(t, f, d);
return;
}
if (e - n === 0) {
for (let f = t; f <= s; f++)
this.pixel(f, e, d);
return;
}
t > s && ([t, s] = [s, t], [e, n] = [n, e]);
const a = (n - e) / (s - t);
if (a === 1)
if (e > n) {
for (let f = t, p = e; f <= s; f++, p--)
this.pixel(f, p, d);
return;
} else {
for (let f = t, p = e; f <= s; f++, p++)
this.pixel(f, p, d);
return;
}
if (a === -1)
if (e > n) {
for (let f = t, p = e; f <= s; f++, p--)
this.pixel(f, p, d);
return;
} else {
for (let f = t, p = e; f <= s; f++, p++)
this.pixel(f, p, d);
return;
}
const i = Math.abs(s - t), r = Math.abs(n - e), l = Math.sign(s - t), o = Math.sign(n - e);
let c = i - r;
for (; ; ) {
if (this.pixel(t, e, d), t === s && e === n)
return;
const f = 2 * c;
f > -r && (c -= r, t += l), f < i && (c += i, e += o);
}
}
fillRect(t, e, s, n, d, a = w.identity) {
if (a.isIdentity())
for (let i = t; i < t + s; i++)
for (let r = e; r < e + n; r++)
this.pixel(i, r, d);
else {
const i = a.applyToRect(t, e, s, n), r = a.inv();
for (let l = i.x; l < i.x + i.width; l++)
for (let o = i.y; o < i.y + i.height; o++) {
const c = r.apply(l, o);
c.x >= t && c.x < t + s && c.y >= e && c.y < e + n && this.pixel(l, o, d);
}
}
}
traceRect(t, e, s, n, d, a = w.identity) {
if (a.isIdentity())
this.line(t, e, t + s, e, d), this.line(t + s, e, t + s, e + n, d), this.line(t, e + n, t + s, e + n, d), this.line(t, e, t, e + n, d);
else {
const i = a.apply(t, e), r = a.apply(t + s, e), l = a.apply(t, e + n), o = a.apply(t + s, e + n);
this.line(i.x, i.y, r.x, r.y, d), this.line(r.x, r.y, o.x, o.y, d), this.line(o.x, o.y, l.x, l.y, d), this.line(l.x, l.y, i.x, i.y, d);
}
}
fillCirc(t, e, s, n, d = w.identity) {
if (d.isIdentity()) {
let a = s, i = 0, r = 1 - s;
for (; a >= i; )
this.line(-a + t, -i + e, -a + t, i + e, n), this.line(-i + t, -a + e, -i + t, a + e, n), this.line(i + t, -a + e, i + t, a + e, n), this.line(a + t, -i + e, a + t, i + e, n), i++, r < 0 ? r += 2 * i + 1 : (a--, r += 2 * (i - a + 1));
} else {
const a = s * 2 + 1, i = d.applyToRect(t - a / 2, e - a / 2, a, a), r = d.inv();
for (let l = Math.floor(i.x); l < Math.ceil(i.x + i.width); l++)
for (let o = Math.floor(i.y); o < Math.ceil(i.y + i.height); o++) {
const c = r.apply(l, o);
Math.sqrt(
(c.x - t) ** 2 + (c.y - e) ** 2
) <= a / 2 && this.pixel(l, o, n);
}
}
}
traceCirc(t, e, s, n, d = w.identity) {
if (d.isIdentity()) {
let a = s, i = 0, r = 1 - s;
for (; a >= i; )
this.pixel(a + t, i + e, n), this.pixel(i + t, a + e, n), this.pixel(-a + t, i + e, n), this.pixel(-i + t, a + e, n), this.pixel(-a + t, -i + e, n), this.pixel(-i + t, -a + e, n), this.pixel(a + t, -i + e, n), this.pixel(i + t, -a + e, n), i++, r < 0 ? r += 2 * i + 1 : (a--, r += 2 * (i - a + 1));
} else {
const a = s * 2 + 1, i = d.applyToRect(t - a / 2, e - a / 2, a, a), r = d.inv();
for (let l = Math.floor(i.x); l < Math.ceil(i.x + i.width); l++)
for (let o = Math.floor(i.y); o < Math.ceil(i.y + i.height); o++) {
const c = r.apply(l, o), f = Math.sqrt(
(c.x - t) ** 2 + (c.y - e) ** 2
);
Math.abs(f - s) < 0.58 && this.pixel(l, o, n);
}
}
}
fillTri(t, e, s, n, d, a, i, r = w.identity) {
const l = Math.min(t, s, d), o = Math.max(t, s, d), c = Math.min(e, n, a), f = Math.max(e, n, a);
if (r.isIdentity())
for (let p = Math.floor(l); p < Math.ceil(o); p++)
for (let m = Math.floor(c); m < Math.ceil(f); m++)
O(p, m, t, e, s, n, d, a) && this.pixel(p, m, i);
else {
const p = r.applyToRect(
l,
c,
o - l,
f - c
), m = r.inv();
for (let y = Math.floor(p.x); y < Math.ceil(p.x + p.width); y++)
for (let M = Math.floor(p.y); M < Math.ceil(p.y + p.height); M++) {
const v = m.apply(y, M);
O(
v.x,
v.y,
t,
e,
s,
n,
d,
a
) && this.pixel(y, M, i);
}
}
}
traceTri(t, e, s, n, d, a, i, r = w.identity) {
if (r.isIdentity())
this.line(t, e, s, n, i), this.line(s, n, d, a, i), this.line(d, a, t, e, i);
else {
const l = r.apply(t, e), o = r.apply(s, n), c = r.apply(d, a);
this.line(l.x, l.y, o.x, o.y, i), this.line(o.x, o.y, c.x, c.y, i), this.line(c.x, c.y, l.x, l.y, i);
}
}
}
class A {
constructor(t, e = 0, s = {
x: 0,
y: 0,
width: t.width,
height: t.height
}) {
// @ts-expect-error
u(this, "image");
this.asset = t, this.frame = e, this.subregion = s, this.update();
}
static fromArrayBuffer(t) {
const e = new T(t);
return new A(e);
}
get width() {
return this.subregion.width;
}
get height() {
return this.subregion.height;
}
update() {
this.image = new ImageData(this.subregion.width, this.subregion.height);
const t = this.asset.frames[this.frame];
if (!t) {
console.error(`Frame ${this.frame} does not exist.`);
return;
}
const e = this.asset.palette[0];
for (let s = 0; s < this.subregion.width; s++)
for (let n = 0; n < this.subregion.height; n++)
for (let d = t.layers.length - 1; d >= 0; d--) {
const a = t.layers[d];
let i = !1;
for (let r = a.cels.length - 1; r >= 0; r--) {
const l = a.cels[r], o = s + this.subregion.x - l.x, c = n + this.subregion.y - l.y;
if (c < 0 || c >= l.height || o < 0 || o >= l.width)
continue;
const f = l.pixels[c * l.width + o], p = n * this.subregion.width + s, [m, y, M, v] = x(
z(this.asset, f)
);
v === 0 || this.asset.header.depth !== $.Index && e && e.red === m && e.green === y && e.blue === M || this.asset.header.depth !== $.Index && !e && m === 0 && y === 0 && M === 0 || this.asset.header.depth === $.Index && f === 0 || (this.image.data[p * 4 + 0] = m, this.image.data[p * 4 + 1] = y, this.image.data[p * 4 + 2] = M, this.image.data[p * 4 + 3] = v, i = !0);
}
if (i)
break;
}
}
render(t, e, s, n = w.identity) {
if (n.isIdentity())
for (let d = 0; d < this.subregion.width; d++)
for (let a = 0; a < this.subregion.height; a++) {
const i = (a * this.subregion.width + d) * 4;
this.image.data[i + 3] !== 0 && t.pixelUnpacked(
d + e,
a + s,
this.image.data[i + 0],
this.image.data[i + 1],
this.image.data[i + 2],
this.image.data[i + 3]
);
}
else {
const d = n.applyToRect(
e,
s,
this.subregion.width,
this.subregion.height
), a = n.inv();
for (let i = d.x; i < d.x + d.width; i++)
for (let r = d.y; r < d.y + d.height; r++) {
const l = a.apply(i, r);
if (l.x >= e && l.x < e + this.subregion.width && l.y >= s && l.y < s + this.subregion.height) {
const o = (Math.floor(l.y - s) * this.subregion.width + Math.floor(l.x - e)) * 4;
if (this.image.data[o + 3] === 0)
continue;
t.pixelUnpacked(
i,
r,
this.image.data[o + 0],
this.image.data[o + 1],
this.image.data[o + 2],
this.image.data[o + 3]
);
}
}
}
}
}
class C extends A {
constructor(e, s = 0, n = {
x: 0,
y: 0,
width: e.width,
height: e.height
}) {
super(e, s, n);
// @ts-expect-error
u(this, "image");
u(this, "duration", 0);
u(this, "start");
u(this, "end");
u(this, "animation");
u(this, "direction", I.Forward);
u(this, "repeat", 0);
u(this, "iterations", 0);
u(this, "playing", !1);
this.asset = e, this.frame = s, this.subregion = n, this.start = 0, this.end = e.frames.length - 1, this.update();
}
static fromArrayBuffer(e) {
const s = new T(e);
return new C(s);
}
get width() {
return this.subregion.width;
}
get height() {
return this.subregion.height;
}
pause() {
this.playing = !1;
}
play() {
this.playing = !0;
}
setAnimation(e) {
if (this.iterations = 0, this.duration = 0, this.animation = e, e) {
const s = this.asset.tags.find((n) => n.name === e);
s ? (s.direction === I.Reverse || s.direction === I.PingPongReverse ? this.frame = s.to : this.frame = s.from, this.start = s.from, this.end = s.to, this.direction = s.direction, this.repeat = s.repeat) : console.error(`Animation ${e} does not exist.`);
} else
this.start = 0, this.end = this.asset.frames.length - 1;
}
update(e = 0) {
for (this.duration += e; this.duration >= this.asset.frames[this.frame].duration; )
if (this.duration -= this.asset.frames[this.frame].duration, !!this.playing) {
if (this.repeat !== 0 && this.iterations >= this.repeat) {
this.playing = !1;
continue;
}
switch (this.direction) {
case I.Forward:
this.frame++, this.frame > this.end && (this.iterations++, this.frame = this.start);
break;
case I.Reverse:
this.frame--, this.frame < this.start && (this.iterations++, this.frame = this.end);
break;
case I.PingPong:
this.iterations % 2 === 0 ? (this.frame++, this.frame > this.end && (this.iterations++, this.frame = this.end)) : (this.frame--, this.frame < this.start && (this.iterations++, this.frame = this.start));
break;
case I.PingPongReverse:
this.iterations % 2 !== 0 ? (this.frame++, this.frame > this.end && (this.iterations++, this.frame = this.end)) : (this.frame--, this.frame < this.start && (this.iterations++, this.frame = this.start));
break;
}
}
super.update();
}
}
class j {
constructor(t) {
u(this, "rows");
u(this, "cols");
u(this, "sprites", []);
this.asset = t;
const e = this.asset.width - this.asset.header.grid.x, s = this.asset.height - this.asset.header.grid.y;
this.rows = Math.floor(s / this.asset.header.grid.height), this.cols = Math.floor(e / this.asset.header.grid.width), this.init();
}
static fromArrayBuffer(t) {
const e = new T(t);
return new j(e);
}
init() {
for (let t = 0; t < this.rows; t++)
for (let e = 0; e < this.cols; e++) {
const s = {
x: e * this.asset.header.grid.width,
y: t * this.asset.header.grid.height,
width: this.asset.header.grid.width,
height: this.asset.header.grid.height
};
this.sprites.push(new A(this.asset, 0, s));
}
}
update() {
for (const t of this.sprites)
t.update();
}
}
class q {
constructor(t) {
u(this, "rows");
u(this, "cols");
u(this, "sprites", []);
this.asset = t;
const e = this.asset.width - this.asset.header.grid.x, s = this.asset.height - this.asset.header.grid.y;
this.rows = Math.floor(s / this.asset.header.grid.height), this.cols = Math.floor(e / this.asset.header.grid.width), this.init();
}
static fromArrayBuffer(t) {
const e = new T(t);
return new q(e);
}
init() {
for (let t = 0; t < this.rows; t++)
for (let e = 0; e < this.cols; e++) {
const s = {
x: e * this.asset.header.grid.width,
y: t * this.asset.header.grid.height,
width: this.asset.header.grid.width,
height: this.asset.header.grid.height
};
this.sprites.push(new C(this.asset, 0, s));
}
}
update(t = 0) {
for (const e of this.sprites)
e.update(t);
}
}
const Et = (h, t, e = 0, s = 0) => {
for (let n = 0; n < h.height; n++)
if (!(n + s < 0 || n + s >= t.height))
for (let d = 0; d < h.width; d++) {
if (d + e < 0 || d + e >= t.width)
continue;
const a = (n * h.width + d) * 4, i = ((n + s) * t.width + (d + e)) * 4;
t.data[i + 0] = h.data[a + 0], t.data[i + 1] = h.data[a + 1], t.data[i + 2] = h.data[a + 2], t.data[i + 3] = h.data[a + 3];
}
}, Ot = (h, t, e, s = 0, n = 0) => {
for (let d = 0; d < h.height; d++)
if (!(d + n < 0 || d + n >= t.height))
for (let a = 0; a < h.width; a++) {
if (a + s < 0 || a + s >= t.width)
continue;
const i = ((d + n) * e.width + (a + s)) * 4;
if (i + 3 >= e.data.length)
continue;
const r = (d * h.width + a) * 4, l = ((d + n) * t.width + (a + s)) * 4;
e.data[i] === 255 && e.data[i + 1] === 255 && e.data[i + 2] === 255 && e.data[i + 3] === 255 && (t.data[l + 0] = h.data[r + 0], t.data[l + 1] = h.data[r + 1], t.data[l + 2] = h.data[r + 2], t.data[l + 3] = h.data[r + 3]);
}
}, qt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
AnimatedSprite: C,
AnimatedSpriteSheet: q,
Screen: St,
Sprite: A,
SpriteSheet: j,
VirtualScreen: kt,
blit: Et,
blitMask: Ot
}, Symbol.toStringTag, { value: "Module" }));
class H {
constructor(t, e) {
u(this, "x", 0);
u(this, "y", 0);
u(this, "visible", !1);
u(this, "primary", !1);
u(this, "secondary", !1);
u(this, "middle", !1);
this.root = t, this.surface = e, t.addEventListener("mouseenter", () => {
this.visible = !0;
}), t.addEventListener("mouseleave", () => {
this.visible = !1;
}), t.addEventListener("mousemove", (s) => {
const n = t.getBoundingClientRect(), d = s.clientX - n.left, a = s.clientY - n.top;
this.x = Math.floor(d / n.width * this.surface.width), this.y = Math.floor(a / n.height * this.surface.height);
}), t.addEventListener("mousedown", (s) => {
switch (s.button) {
case 0:
this.primary = !0;
break;
case 1:
this.middle = !0;
break;
case 2:
this.secondary = !0;
break;
}
}), t.addEventListener("mouseup", (s) => {
switch (s.button) {
case 0:
this.primary = !1;
break;
case 1:
this.middle = !1;
break;
case 2:
this.secondary = !1;
break;
}
}), t.addEventListener("contextmenu", (s) => {
s.preventDefault();
});
}
update() {
}
}
class Q {
constructor(t) {
u(this, "keys", {
"`": { held: !1, pressed: !1 },
1: { held: !1, pressed: !1 },
2: { held: !1, pressed: !1 },
3: { held: !1, pressed: !1 },
4: { held: !1, pressed: !1 },
5: { held: !1, pressed: !1 },
6: { held: !1, pressed: !1 },
7: { held: !1, pressed: !1 },
8: { held: !1, pressed: !1 },
9: { held: !1, pressed: !1 },
0: { held: !1, pressed: !1 },
"-": { held: !1, pressed: !1 },
"=": { held: !1, pressed: !1 },
Backspace: { held: !1, pressed: !1 },
Tab: { held: !1, pressed: !1 },
q: { held: !1, pressed: !1 },
w: { held: !1, pressed: !1 },
e: { held: !1, pressed: !1 },
r: { held: !1, pressed: !1 },
t: { held: !1, pressed: !1 },
y: { held: !1, pressed: !1 },
u: { held: !1, pressed: !1 },
i: { held: !1, pressed: !1 },
o: { held: !1, pressed: !1 },
p: { held: !1, pressed: !1 },
"[": { held: !1, pressed: !1 },
"]": { held: !1, pressed: !1 },
"\\": { held: !1, pressed: !1 },
CapsLock: { held: !1, pressed: !1 },
a: { held: !1, pressed: !1 },
s: { held: !1, pressed: !1 },
d: { held: !1, pressed: !1 },
f: { held: !1, pressed: !1 },
g: { held: !1, pressed: !1 },
h: { held: !1, pressed: !1 },
j: { held: !1, pressed: !1 },
k: { held: !1, pressed: !1 },
l: { held: !1, pressed: !1 },
";": { held: !1, pressed: !1 },
"'": { held: !1, pressed: !1 },
Enter: { held: !1, pressed: !1 },
ShiftLeft: { held: !1, pressed: !1 },
z: { held: !1, pressed: !1 },
x: { held: !1, pressed: !1 },
c: { held: !1, pressed: !1 },
v: { held: !1, pressed: !1 },
b: { held: !1, pressed: !1 },
n: { held: !1, pressed: !1 },
m: { held: !1, pressed: !1 },
",": { held: !1, pressed: !1 },
".": { held: !1, pressed: !1 },
"/": { held: !1, pressed: !1 },
ShiftRight: { held: !1, pressed: !1 },
ControlLeft: { held: !1, pressed: !1 },
MetaLeft: { held: !1, pressed: !1 },
AltLeft: { held: !1, pressed: !1 },
Space: { held: !1, pressed: !1 },
AltRight: { held: !1, pressed: !1 },
MetaRight: { held: !1, pressed: !1 },
ContextMenu: { held: !1, pressed: !1 },
ControlRight: { held: !1, pressed: !1 },
ArrowLeft: { held: !1, pressed: !1 },
ArrowUp: { held: !1, pressed: !1 },
ArrowRight: { held: !1, pressed: !1 },
ArrowDown: { held: !1, pressed: !1 }
});
this.root = t, t.addEventListener("keydown", (e) => {
switch (e.preventDefault(), e.key) {
case "Shift":
case "Control":
case "Meta":
case "Alt":
e.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT ? this.keys[`${e.key}Right`].held = !0 : this.keys[`${e.key}Left`].held = !0;
break;
case " ":
this.keys.Space.held = !0;
break;
default:
this.keys.hasOwnProperty(e.key) && (this.keys[e.key].held = !0);
break;
}
}), t.addEventListener("keyup", (e) => {
switch (e.preventDefault(), e.key) {
case "Shift":
case "Control":
case "Meta":
case "Alt":
e.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT ? (this.keys[`${e.key}Right`].held = !1, this.keys[`${e.key}Right`].pressed = !0) : (this.keys[`${e.key}Left`].held = !1, this.keys[`${e.key}Left`].pressed = !0);
break;
case " ":
this.keys.Space.held = !1, this.keys.Space.pressed = !0;
break;
default:
this.keys.hasOwnProperty(e.key) && (this.keys[e.key].held = !1, this.keys[e.key].pressed = !0);
break;
}
});
}
update() {
for (const t in this.keys)
this.keys[t].pressed = !1;
}
held(t) {
return this.keys[t].held;
}
pressed(t) {
return this.keys[t].pressed;
}
}
class k {
constructor(t) {
u(this, "connected", !1);
u(this, "device", null);
u(this, "buttons", []);
this.root = t;
}
update() {
var t;
for (let e = 0; e < this.buttons.length; e++) {
const s = (t = this.device) == null ? void 0 : t.buttons[e], n = this.buttons[e];
s && (n.pressed && (n.pressed = !1), n.held && !s.pressed && (n.pressed = !0), n.held = s.pressed);
}
}
connect(t) {
this.connected = !0, this.device = t.gamepad, this.buttons = this.device.buttons.map(() => ({
held: !1,
pressed: !1
}));
}
disconnect() {
this.connected = !1;
}
held(t) {
var e;
return ((e = this.device) == null ? void 0 : e.buttons[t].pressed) ?? !1;
}
pressed(t) {
var e;
return ((e = this.buttons[t]) == null ? void 0 : e.pressed) ?? !1;
}
analog(t) {
var e;
return ((e = this.device) == null ? void 0 : e.buttons[t].value) ?? 0;
}
axis(t) {
var e;
return ((e = this.device) == null ? void 0 : e.axes[t]) ?? 0;
}
}
class X {
constructor(t) {
u(this, "root");
u(this, "mouse");
u(this, "keyboard");
u(this, "gamepads");
this.surface = t, t.virtual ? this.root = document.createElement("div") : this.root = t.canvas, this.mouse = new H(this.root, this.surface), this.keyboard = new Q(this.root), this.gamepads = [
new k(this.root),
new k(this.root),
new k(this.root),
new k(this.root)
], window.addEventListener("gamepadconnected", (e) => {
if (e.gamepad.index >= 4)
return;
this.gamepads[e.gamepad.index].connect(e);
}), window.addEventListener(
"gamepaddisconnected",
(e) => {
if (e.gamepad.index >= 4)
return;
this.gamepads[e.gamepad.index].disconnect();
}
);
}
update() {
this.mouse.update(), this.keyboard.update();
for (const t of this.gamepads)
t.update();
}
}
const Dt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null,
GamepadInput: k,
Inputs: X,
KeyboardInput: Q,
MouseInput: H
}, Symbol.toStringTag, { value: "Module" })), At = ({
surface: h,
setup: t = R,
update: e = R,
render: s = R
}) => {
let n = 0, d = 0, a = 0, i = 0;
const r = new X(h), l = new _();
let o = document.visibilityState === "visible";
window.addEventListener("vis