minimojs 1.0.0-alpha.2 → 1.0.0-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -285
- package/dist/internal/AnimationSystem.js +345 -0
- package/dist/internal/AssetSystem.d.ts +1 -0
- package/dist/internal/AssetSystem.js +101 -0
- package/dist/internal/BackgroundSystem.d.ts +1 -0
- package/dist/internal/BackgroundSystem.js +26 -0
- package/dist/internal/CanvasSystem.d.ts +1 -0
- package/dist/internal/CanvasSystem.js +51 -0
- package/dist/internal/ExplosionSystem.d.ts +1 -0
- package/dist/internal/ExplosionSystem.js +540 -0
- package/dist/internal/InputSystem.d.ts +1 -0
- package/dist/internal/InputSystem.js +265 -0
- package/dist/internal/LoopSystem.d.ts +1 -0
- package/dist/internal/LoopSystem.js +61 -0
- package/dist/internal/PhysicsSystem.d.ts +1 -0
- package/dist/internal/PhysicsSystem.js +174 -0
- package/dist/internal/RenderSystem.d.ts +1 -0
- package/dist/internal/RenderSystem.js +910 -0
- package/dist/internal/SoundSystem.d.ts +1 -0
- package/dist/internal/SoundSystem.js +55 -0
- package/dist/internal/SpriteSystem.d.ts +1 -0
- package/dist/internal/SpriteSystem.js +32 -0
- package/dist/internal/TextSystem.d.ts +1 -0
- package/dist/internal/TextSystem.js +16 -0
- package/dist/internal/TimerSystem.d.ts +1 -0
- package/dist/internal/TimerSystem.js +43 -0
- package/dist/internal/TrailSystem.d.ts +1 -0
- package/dist/internal/TrailSystem.js +116 -0
- package/dist/internal/TransitionSystem.d.ts +1 -0
- package/dist/internal/TransitionSystem.js +74 -0
- package/dist/internal/arcade-racer/ArcadeRacerCollisionSystem.d.ts +1 -0
- package/dist/internal/arcade-racer/ArcadeRacerCollisionSystem.js +198 -0
- package/dist/internal/arcade-racer/ArcadeRacerLaneSystem.d.ts +1 -0
- package/dist/internal/arcade-racer/ArcadeRacerLaneSystem.js +120 -0
- package/dist/internal/arcade-racer/ArcadeRacerRenderSystem.d.ts +1 -0
- package/dist/internal/arcade-racer/ArcadeRacerRenderSystem.js +599 -0
- package/dist/internal/arcade-racer/ArcadeRacerRoadSprite.d.ts +1 -0
- package/dist/internal/arcade-racer/ArcadeRacerRoadSprite.js +13 -0
- package/dist/internal/arcade-racer/ArcadeRacerTrackSystem.d.ts +1 -0
- package/dist/internal/arcade-racer/ArcadeRacerTrackSystem.js +447 -0
- package/dist/minimo-arcaderacer.d.ts +1431 -0
- package/dist/minimo-arcaderacer.js +2060 -0
- package/dist/minimo.d.ts +1412 -162
- package/dist/minimo.js +2083 -816
- package/package.json +3 -2
- package/dist/animations.js +0 -30
- package/dist/audio.js +0 -17
- package/dist/game.js +0 -1105
- package/dist/input.js +0 -185
- package/dist/internal-types.js +0 -4
- package/dist/physics.js +0 -10
- package/dist/render.js +0 -75
- package/dist/sprite.js +0 -149
- package/dist/timers.js +0 -23
- /package/dist/{pointer-info.js → internal/AnimationSystem.d.ts} +0 -0
package/dist/input.js
DELETED
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
export function createInputState() {
|
|
2
|
-
return {
|
|
3
|
-
keysDown: new Set(),
|
|
4
|
-
keysPressed: new Set(),
|
|
5
|
-
pointerDown: false,
|
|
6
|
-
pointerPressed: false,
|
|
7
|
-
pointerX: 0,
|
|
8
|
-
pointerY: 0,
|
|
9
|
-
mouseDown: false,
|
|
10
|
-
mousePressed: false,
|
|
11
|
-
mouseX: 0,
|
|
12
|
-
mouseY: 0,
|
|
13
|
-
touchPointers: new Map(),
|
|
14
|
-
primaryTouchId: null,
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
export function bindInputEvents(canvas, input) {
|
|
18
|
-
window.addEventListener("keydown", (e) => {
|
|
19
|
-
if (!input.keysDown.has(e.key)) {
|
|
20
|
-
input.keysPressed.add(e.key);
|
|
21
|
-
}
|
|
22
|
-
input.keysDown.add(e.key);
|
|
23
|
-
});
|
|
24
|
-
window.addEventListener("keyup", (e) => {
|
|
25
|
-
input.keysDown.delete(e.key);
|
|
26
|
-
});
|
|
27
|
-
const getCanvasPoint = (clientX, clientY) => {
|
|
28
|
-
const rect = canvas.getBoundingClientRect();
|
|
29
|
-
const scaleX = canvas.width / rect.width;
|
|
30
|
-
const scaleY = canvas.height / rect.height;
|
|
31
|
-
return {
|
|
32
|
-
x: (clientX - rect.left) * scaleX,
|
|
33
|
-
y: (clientY - rect.top) * scaleY,
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
canvas.addEventListener("mousedown", (e) => {
|
|
37
|
-
const p = getCanvasPoint(e.clientX, e.clientY);
|
|
38
|
-
input.mouseX = p.x;
|
|
39
|
-
input.mouseY = p.y;
|
|
40
|
-
input.mouseDown = true;
|
|
41
|
-
input.mousePressed = true;
|
|
42
|
-
syncPrimaryPointer(input);
|
|
43
|
-
});
|
|
44
|
-
canvas.addEventListener("mouseup", () => {
|
|
45
|
-
input.mouseDown = false;
|
|
46
|
-
syncPrimaryPointer(input);
|
|
47
|
-
});
|
|
48
|
-
canvas.addEventListener("mousemove", (e) => {
|
|
49
|
-
const p = getCanvasPoint(e.clientX, e.clientY);
|
|
50
|
-
input.mouseX = p.x;
|
|
51
|
-
input.mouseY = p.y;
|
|
52
|
-
syncPrimaryPointer(input);
|
|
53
|
-
});
|
|
54
|
-
canvas.addEventListener("touchstart", (e) => {
|
|
55
|
-
for (const touch of Array.from(e.changedTouches)) {
|
|
56
|
-
const p = getCanvasPoint(touch.clientX, touch.clientY);
|
|
57
|
-
input.touchPointers.set(touch.identifier, {
|
|
58
|
-
x: p.x,
|
|
59
|
-
y: p.y,
|
|
60
|
-
pressed: true,
|
|
61
|
-
});
|
|
62
|
-
if (input.primaryTouchId === null) {
|
|
63
|
-
input.primaryTouchId = touch.identifier;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
syncPrimaryPointer(input);
|
|
67
|
-
e.preventDefault();
|
|
68
|
-
}, { passive: false });
|
|
69
|
-
const clearTouches = (e) => {
|
|
70
|
-
for (const touch of Array.from(e.changedTouches)) {
|
|
71
|
-
input.touchPointers.delete(touch.identifier);
|
|
72
|
-
if (input.primaryTouchId === touch.identifier) {
|
|
73
|
-
input.primaryTouchId = null;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
syncPrimaryPointer(input);
|
|
77
|
-
e.preventDefault();
|
|
78
|
-
};
|
|
79
|
-
canvas.addEventListener("touchend", clearTouches, { passive: false });
|
|
80
|
-
canvas.addEventListener("touchcancel", clearTouches, { passive: false });
|
|
81
|
-
canvas.addEventListener("touchmove", (e) => {
|
|
82
|
-
for (const touch of Array.from(e.changedTouches)) {
|
|
83
|
-
const p = getCanvasPoint(touch.clientX, touch.clientY);
|
|
84
|
-
const existing = input.touchPointers.get(touch.identifier);
|
|
85
|
-
if (existing) {
|
|
86
|
-
existing.x = p.x;
|
|
87
|
-
existing.y = p.y;
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
input.touchPointers.set(touch.identifier, {
|
|
91
|
-
x: p.x,
|
|
92
|
-
y: p.y,
|
|
93
|
-
pressed: false,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
syncPrimaryPointer(input);
|
|
98
|
-
e.preventDefault();
|
|
99
|
-
}, { passive: false });
|
|
100
|
-
}
|
|
101
|
-
export function syncPrimaryPointer(input) {
|
|
102
|
-
if (input.primaryTouchId !== null) {
|
|
103
|
-
const primaryTouch = input.touchPointers.get(input.primaryTouchId);
|
|
104
|
-
if (primaryTouch) {
|
|
105
|
-
input.pointerX = primaryTouch.x;
|
|
106
|
-
input.pointerY = primaryTouch.y;
|
|
107
|
-
input.pointerDown = true;
|
|
108
|
-
input.pointerPressed = primaryTouch.pressed;
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
input.primaryTouchId = null;
|
|
112
|
-
}
|
|
113
|
-
if (input.touchPointers.size > 0) {
|
|
114
|
-
const firstTouchEntry = input.touchPointers.entries().next().value;
|
|
115
|
-
if (firstTouchEntry) {
|
|
116
|
-
const [touchId, touch] = firstTouchEntry;
|
|
117
|
-
input.primaryTouchId = touchId;
|
|
118
|
-
input.pointerX = touch.x;
|
|
119
|
-
input.pointerY = touch.y;
|
|
120
|
-
input.pointerDown = true;
|
|
121
|
-
input.pointerPressed = touch.pressed;
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
input.primaryTouchId = null;
|
|
126
|
-
input.pointerX = input.mouseX;
|
|
127
|
-
input.pointerY = input.mouseY;
|
|
128
|
-
input.pointerDown = input.mouseDown;
|
|
129
|
-
input.pointerPressed = input.mousePressed;
|
|
130
|
-
}
|
|
131
|
-
export function collectPointers(input) {
|
|
132
|
-
const pointers = [];
|
|
133
|
-
if (input.mouseDown) {
|
|
134
|
-
pointers.push({
|
|
135
|
-
id: "mouse",
|
|
136
|
-
kind: "mouse",
|
|
137
|
-
x: input.mouseX,
|
|
138
|
-
y: input.mouseY,
|
|
139
|
-
pressed: input.mousePressed,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
for (const [id, pointer] of input.touchPointers.entries()) {
|
|
143
|
-
pointers.push({
|
|
144
|
-
id,
|
|
145
|
-
kind: "touch",
|
|
146
|
-
x: pointer.x,
|
|
147
|
-
y: pointer.y,
|
|
148
|
-
pressed: pointer.pressed,
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
return pointers;
|
|
152
|
-
}
|
|
153
|
-
export function isScreenPointOverSprite(x, y, sprite, radiusScale, scrollX, scrollY) {
|
|
154
|
-
const safeScale = Math.max(0, radiusScale);
|
|
155
|
-
const radius = sprite.size * safeScale;
|
|
156
|
-
const drawX = sprite.ignoreScroll ? sprite.x : sprite.x - scrollX;
|
|
157
|
-
const drawY = sprite.ignoreScroll ? sprite.y : sprite.y - scrollY;
|
|
158
|
-
const dx = x - drawX;
|
|
159
|
-
const dy = y - drawY;
|
|
160
|
-
return dx * dx + dy * dy <= radius * radius;
|
|
161
|
-
}
|
|
162
|
-
export function isPointerDownOverSprite(input, sprite, radiusScale, scrollX, scrollY) {
|
|
163
|
-
if (!sprite)
|
|
164
|
-
return false;
|
|
165
|
-
return collectPointers(input).some((pointer) => isScreenPointOverSprite(pointer.x, pointer.y, sprite, radiusScale, scrollX, scrollY));
|
|
166
|
-
}
|
|
167
|
-
export function isPointerPressedOverSprite(input, sprite, radiusScale, scrollX, scrollY) {
|
|
168
|
-
if (!sprite)
|
|
169
|
-
return false;
|
|
170
|
-
return collectPointers(input).some((pointer) => pointer.pressed &&
|
|
171
|
-
isScreenPointOverSprite(pointer.x, pointer.y, sprite, radiusScale, scrollX, scrollY));
|
|
172
|
-
}
|
|
173
|
-
export function getPointersOverSprite(input, sprite, radiusScale, scrollX, scrollY) {
|
|
174
|
-
if (!sprite)
|
|
175
|
-
return [];
|
|
176
|
-
return collectPointers(input).filter((pointer) => isScreenPointOverSprite(pointer.x, pointer.y, sprite, radiusScale, scrollX, scrollY));
|
|
177
|
-
}
|
|
178
|
-
export function resetTransientInput(input) {
|
|
179
|
-
input.keysPressed.clear();
|
|
180
|
-
input.mousePressed = false;
|
|
181
|
-
for (const pointer of input.touchPointers.values()) {
|
|
182
|
-
pointer.pressed = false;
|
|
183
|
-
}
|
|
184
|
-
syncPrimaryPointer(input);
|
|
185
|
-
}
|
package/dist/internal-types.js
DELETED
package/dist/physics.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export function updatePhysics(sprites, gravityX, gravityY, dt) {
|
|
2
|
-
for (const sprite of sprites) {
|
|
3
|
-
if (sprite.gravityScale !== 0) {
|
|
4
|
-
sprite.vx += gravityX * sprite.gravityScale * dt;
|
|
5
|
-
sprite.vy += gravityY * sprite.gravityScale * dt;
|
|
6
|
-
}
|
|
7
|
-
sprite.x += sprite.vx * dt;
|
|
8
|
-
sprite.y += sprite.vy * dt;
|
|
9
|
-
}
|
|
10
|
-
}
|
package/dist/render.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
export function renderFrame(options) {
|
|
2
|
-
const { ctx, canvas, sprites, textOverlays, background, backgroundGradient, scrollX, scrollY, } = options;
|
|
3
|
-
const width = canvas.width;
|
|
4
|
-
const height = canvas.height;
|
|
5
|
-
ctx.clearRect(0, 0, width, height);
|
|
6
|
-
if (backgroundGradient !== null) {
|
|
7
|
-
const gradient = ctx.createLinearGradient(0, 0, 0, height);
|
|
8
|
-
gradient.addColorStop(0, backgroundGradient.from);
|
|
9
|
-
gradient.addColorStop(1, backgroundGradient.to);
|
|
10
|
-
ctx.fillStyle = gradient;
|
|
11
|
-
ctx.fillRect(0, 0, width, height);
|
|
12
|
-
}
|
|
13
|
-
else if (background !== null) {
|
|
14
|
-
ctx.fillStyle = background;
|
|
15
|
-
ctx.fillRect(0, 0, width, height);
|
|
16
|
-
}
|
|
17
|
-
const sortedSprites = [...sprites].sort((a, b) => a.layer - b.layer);
|
|
18
|
-
for (const sprite of sortedSprites) {
|
|
19
|
-
if (!sprite.visible)
|
|
20
|
-
continue;
|
|
21
|
-
ctx.save();
|
|
22
|
-
ctx.globalAlpha = Math.max(0, Math.min(1, sprite.alpha));
|
|
23
|
-
const drawX = sprite.ignoreScroll ? sprite.x : sprite.x - scrollX;
|
|
24
|
-
const drawY = sprite.ignoreScroll ? sprite.y : sprite.y - scrollY;
|
|
25
|
-
ctx.translate(drawX, drawY);
|
|
26
|
-
if (sprite.rotation !== 0) {
|
|
27
|
-
ctx.rotate((sprite.rotation * Math.PI) / 180);
|
|
28
|
-
}
|
|
29
|
-
if (sprite.flipX || sprite.flipY) {
|
|
30
|
-
ctx.scale(sprite.flipX ? -1 : 1, sprite.flipY ? -1 : 1);
|
|
31
|
-
}
|
|
32
|
-
ctx.font = `${sprite.size}px serif`;
|
|
33
|
-
ctx.textAlign = "center";
|
|
34
|
-
ctx.textBaseline = "middle";
|
|
35
|
-
ctx.fillText(sprite.sprite, 0, 0);
|
|
36
|
-
ctx.restore();
|
|
37
|
-
}
|
|
38
|
-
for (const entry of textOverlays) {
|
|
39
|
-
ctx.save();
|
|
40
|
-
ctx.font = `${entry.fontSize}px monospace`;
|
|
41
|
-
ctx.fillStyle = entry.color;
|
|
42
|
-
ctx.textAlign = entry.centered ? "center" : "left";
|
|
43
|
-
ctx.textBaseline = entry.centered ? "middle" : "top";
|
|
44
|
-
ctx.fillText(entry.text, entry.x, entry.y);
|
|
45
|
-
ctx.restore();
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
export function applyPageBackground(pageBackground, lastAppliedPageBackground) {
|
|
49
|
-
if (!document.body)
|
|
50
|
-
return lastAppliedPageBackground;
|
|
51
|
-
if (lastAppliedPageBackground === pageBackground)
|
|
52
|
-
return lastAppliedPageBackground;
|
|
53
|
-
if (pageBackground === null) {
|
|
54
|
-
document.body.style.removeProperty("background");
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
document.body.style.background = pageBackground;
|
|
58
|
-
}
|
|
59
|
-
return pageBackground;
|
|
60
|
-
}
|
|
61
|
-
export function applyResponsiveCanvasLayout(canvas) {
|
|
62
|
-
if (!document.body)
|
|
63
|
-
return;
|
|
64
|
-
document.body.style.margin = "0";
|
|
65
|
-
document.body.style.minHeight = "100vh";
|
|
66
|
-
document.body.style.display = "grid";
|
|
67
|
-
document.body.style.placeItems = "center";
|
|
68
|
-
document.body.style.touchAction = "manipulation";
|
|
69
|
-
const viewportWidth = Math.max(1, window.innerWidth);
|
|
70
|
-
const viewportHeight = Math.max(1, window.innerHeight);
|
|
71
|
-
const scale = Math.min(viewportWidth / canvas.width, viewportHeight / canvas.height);
|
|
72
|
-
const safeScale = Number.isFinite(scale) && scale > 0 ? scale : 1;
|
|
73
|
-
canvas.style.width = `${Math.floor(canvas.width * safeScale)}px`;
|
|
74
|
-
canvas.style.height = `${Math.floor(canvas.height * safeScale)}px`;
|
|
75
|
-
}
|
package/dist/sprite.js
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
// ---------------------------------------------------------------------------
|
|
2
|
-
// Sprite
|
|
3
|
-
// ---------------------------------------------------------------------------
|
|
4
|
-
/**
|
|
5
|
-
* A 2D game object rendered as an emoji on the canvas.
|
|
6
|
-
*
|
|
7
|
-
* Instantiate directly or extend to create custom sprite types.
|
|
8
|
-
* Register with the engine by passing the instance to {@link Game.add}.
|
|
9
|
-
*
|
|
10
|
-
* **Coordinate system:** center-based world space. `(x, y)` is the center of
|
|
11
|
-
* the sprite. Positive X = right, positive Y = down.
|
|
12
|
-
*
|
|
13
|
-
* **Lifecycle:** A sprite exists until {@link Game.destroySprite} is called or
|
|
14
|
-
* {@link Game.reset} is invoked. After destruction, do not read or write its fields.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* ```ts
|
|
18
|
-
* // Direct instantiation
|
|
19
|
-
* const coin = new Sprite("🪙");
|
|
20
|
-
* coin.x = 300;
|
|
21
|
-
* coin.y = 200;
|
|
22
|
-
* coin.size = 32;
|
|
23
|
-
* game.add(coin);
|
|
24
|
-
* ```
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```ts
|
|
28
|
-
* // Subclassing for custom game objects
|
|
29
|
-
* class Player extends Sprite {
|
|
30
|
-
* health = 3;
|
|
31
|
-
*
|
|
32
|
-
* constructor(x: number, y: number) {
|
|
33
|
-
* super("🐢");
|
|
34
|
-
* this.x = x;
|
|
35
|
-
* this.y = y;
|
|
36
|
-
* this.size = 48;
|
|
37
|
-
* this.gravityScale = 1;
|
|
38
|
-
* }
|
|
39
|
-
* }
|
|
40
|
-
*
|
|
41
|
-
* const player = new Player(400, 300);
|
|
42
|
-
* game.add(player);
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
export class Sprite {
|
|
46
|
-
/**
|
|
47
|
-
* Creates a new Sprite with the given emoji and optional position.
|
|
48
|
-
* All other properties use their defaults and can be set after construction.
|
|
49
|
-
*
|
|
50
|
-
* @param sprite - The emoji character to render. Must be a single emoji.
|
|
51
|
-
* Image sprites are NOT supported — emoji only.
|
|
52
|
-
* @example "🔥", "⭐", "🐢", "💣", "👾"
|
|
53
|
-
* @param x - Initial X position in world space (center), in pixels. Default: `0`.
|
|
54
|
-
* @param y - Initial Y position in world space (center), in pixels. Default: `0`.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```ts
|
|
58
|
-
* const enemy = new Sprite("👾", 200, 100);
|
|
59
|
-
* enemy.size = 40;
|
|
60
|
-
* game.add(enemy);
|
|
61
|
-
* ```
|
|
62
|
-
*/
|
|
63
|
-
constructor(sprite, x = 0, y = 0) {
|
|
64
|
-
/**
|
|
65
|
-
* X position in world space (horizontal center of the sprite), in pixels.
|
|
66
|
-
* Positive X points right. Updated each frame by: `x += vx * dt`.
|
|
67
|
-
* May be set directly to teleport the sprite.
|
|
68
|
-
*/
|
|
69
|
-
this.x = 0;
|
|
70
|
-
/**
|
|
71
|
-
* Y position in world space (vertical center of the sprite), in pixels.
|
|
72
|
-
* Positive Y points down. Updated each frame by: `y += vy * dt`.
|
|
73
|
-
* May be set directly to teleport the sprite.
|
|
74
|
-
*/
|
|
75
|
-
this.y = 0;
|
|
76
|
-
/**
|
|
77
|
-
* Width and height of the sprite's bounding square, in pixels.
|
|
78
|
-
* Used for both canvas rendering (font size) and AABB collision detection.
|
|
79
|
-
*/
|
|
80
|
-
this.size = 32;
|
|
81
|
-
/**
|
|
82
|
-
* Visual rotation of the sprite in degrees.
|
|
83
|
-
* `0` = upright. Positive values rotate clockwise.
|
|
84
|
-
* **Note:** rotation does NOT affect the AABB collision box — it remains axis-aligned.
|
|
85
|
-
*/
|
|
86
|
-
this.rotation = 0;
|
|
87
|
-
/**
|
|
88
|
-
* Horizontal visual flip.
|
|
89
|
-
* When `true`, the sprite is mirrored left-right during rendering.
|
|
90
|
-
* This is visual-only and does NOT affect collision detection.
|
|
91
|
-
*/
|
|
92
|
-
this.flipX = false;
|
|
93
|
-
/**
|
|
94
|
-
* Vertical visual flip.
|
|
95
|
-
* When `true`, the sprite is mirrored top-bottom during rendering.
|
|
96
|
-
* This is visual-only and does NOT affect collision detection.
|
|
97
|
-
*/
|
|
98
|
-
this.flipY = false;
|
|
99
|
-
/**
|
|
100
|
-
* Camera scroll toggle for this sprite.
|
|
101
|
-
* When `false` (default), the sprite is rendered in world space and is affected
|
|
102
|
-
* by {@link Game.scrollX} and {@link Game.scrollY}.
|
|
103
|
-
* When `true`, the sprite is rendered in canvas/screen space and ignores camera
|
|
104
|
-
* scrolling. Useful for HUD-like sprites that should stay fixed on screen.
|
|
105
|
-
*/
|
|
106
|
-
this.ignoreScroll = false;
|
|
107
|
-
/**
|
|
108
|
-
* Opacity of the sprite. Must be in range `[0, 1]`.
|
|
109
|
-
* `0` = fully transparent, `1` = fully opaque.
|
|
110
|
-
* Clamped to `[0, 1]` at render time.
|
|
111
|
-
*/
|
|
112
|
-
this.alpha = 1;
|
|
113
|
-
/**
|
|
114
|
-
* Controls whether this sprite is drawn each frame.
|
|
115
|
-
* When `false`, the sprite still receives physics updates (gravity, velocity)
|
|
116
|
-
* but is not rendered. Use {@link Game.destroySprite} to fully remove a sprite.
|
|
117
|
-
*/
|
|
118
|
-
this.visible = true;
|
|
119
|
-
/**
|
|
120
|
-
* Render layer order. Sprites with higher `layer` values are drawn on top.
|
|
121
|
-
* Sprites on the same layer render in creation order (first created = bottom).
|
|
122
|
-
* Changing this at runtime takes effect on the next frame.
|
|
123
|
-
*/
|
|
124
|
-
this.layer = 0;
|
|
125
|
-
/**
|
|
126
|
-
* Horizontal velocity in pixels per second.
|
|
127
|
-
* Applied each frame: `x += vx * dt`.
|
|
128
|
-
* Gravity also modifies this: `vx += gravityX * gravityScale * dt`.
|
|
129
|
-
*/
|
|
130
|
-
this.vx = 0;
|
|
131
|
-
/**
|
|
132
|
-
* Vertical velocity in pixels per second.
|
|
133
|
-
* Applied each frame: `y += vy * dt`.
|
|
134
|
-
* Gravity also modifies this: `vy += gravityY * gravityScale * dt`.
|
|
135
|
-
*/
|
|
136
|
-
this.vy = 0;
|
|
137
|
-
/**
|
|
138
|
-
* Gravity multiplier for this sprite.
|
|
139
|
-
* Each frame: `vx += game.gravityX * gravityScale * dt`
|
|
140
|
-
* `vy += game.gravityY * gravityScale * dt`.
|
|
141
|
-
* `0` = immune to gravity (default). `1` = full gravity.
|
|
142
|
-
* Values > 1 amplify gravity; negative values invert it.
|
|
143
|
-
*/
|
|
144
|
-
this.gravityScale = 0;
|
|
145
|
-
this.sprite = sprite;
|
|
146
|
-
this.x = x;
|
|
147
|
-
this.y = y;
|
|
148
|
-
}
|
|
149
|
-
}
|
package/dist/timers.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
export function updateTimers(timers, dtMs) {
|
|
2
|
-
const toRemove = new Set();
|
|
3
|
-
const toFire = [];
|
|
4
|
-
for (const timer of timers) {
|
|
5
|
-
timer.elapsed += dtMs;
|
|
6
|
-
if (timer.elapsed >= timer.delayMs) {
|
|
7
|
-
toFire.push(timer);
|
|
8
|
-
if (timer.repeat) {
|
|
9
|
-
timer.elapsed -= timer.delayMs;
|
|
10
|
-
}
|
|
11
|
-
else {
|
|
12
|
-
toRemove.add(timer.id);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
const nextTimers = toRemove.size > 0
|
|
17
|
-
? timers.filter((timer) => !toRemove.has(timer.id))
|
|
18
|
-
: timers;
|
|
19
|
-
for (const timer of toFire) {
|
|
20
|
-
timer.callback();
|
|
21
|
-
}
|
|
22
|
-
return nextTimers;
|
|
23
|
-
}
|
|
File without changes
|