kiwiengine 0.0.1-alpha

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.
Files changed (145) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +8 -0
  3. package/assets/logo.png +0 -0
  4. package/examples/package.json +13 -0
  5. package/examples/test-dom/index.html +24 -0
  6. package/examples/test-dom/index.ts +21 -0
  7. package/examples/tsconfig.json +22 -0
  8. package/examples/webpack.config.js +31 -0
  9. package/lib/asset/audio.js +158 -0
  10. package/lib/asset/audio.js.map +1 -0
  11. package/lib/asset/loaders/audio.js +35 -0
  12. package/lib/asset/loaders/audio.js.map +1 -0
  13. package/lib/asset/loaders/binary.js +28 -0
  14. package/lib/asset/loaders/binary.js.map +1 -0
  15. package/lib/asset/loaders/font.js +27 -0
  16. package/lib/asset/loaders/font.js.map +1 -0
  17. package/lib/asset/loaders/loader.js +37 -0
  18. package/lib/asset/loaders/loader.js.map +1 -0
  19. package/lib/asset/loaders/spritesheet.js +56 -0
  20. package/lib/asset/loaders/spritesheet.js.map +1 -0
  21. package/lib/asset/loaders/text.js +27 -0
  22. package/lib/asset/loaders/text.js.map +1 -0
  23. package/lib/asset/loaders/texture.js +38 -0
  24. package/lib/asset/loaders/texture.js.map +1 -0
  25. package/lib/asset/preload.js +69 -0
  26. package/lib/asset/preload.js.map +1 -0
  27. package/lib/game-object/game-object-physics.js +188 -0
  28. package/lib/game-object/game-object-physics.js.map +1 -0
  29. package/lib/game-object/game-object-rendering.js +35 -0
  30. package/lib/game-object/game-object-rendering.js.map +1 -0
  31. package/lib/game-object/game-object.js +162 -0
  32. package/lib/game-object/game-object.js.map +1 -0
  33. package/lib/game-object/transform.js +118 -0
  34. package/lib/game-object/transform.js.map +1 -0
  35. package/lib/game-object-ext/animated-sprite.js +117 -0
  36. package/lib/game-object-ext/animated-sprite.js.map +1 -0
  37. package/lib/game-object-ext/dom-container.js +56 -0
  38. package/lib/game-object-ext/dom-container.js.map +1 -0
  39. package/lib/game-object-ext/rect.js +30 -0
  40. package/lib/game-object-ext/rect.js.map +1 -0
  41. package/lib/game-object-ext/spine.js +206 -0
  42. package/lib/game-object-ext/spine.js.map +1 -0
  43. package/lib/game-object-ext/sprite.js +46 -0
  44. package/lib/game-object-ext/sprite.js.map +1 -0
  45. package/lib/game-object-ext/text.js +68 -0
  46. package/lib/game-object-ext/text.js.map +1 -0
  47. package/lib/game-object-ext/tiling-sprite.js +64 -0
  48. package/lib/game-object-ext/tiling-sprite.js.map +1 -0
  49. package/lib/index.js +13 -0
  50. package/lib/index.js.map +1 -0
  51. package/lib/types/asset/audio.d.ts +21 -0
  52. package/lib/types/asset/audio.d.ts.map +1 -0
  53. package/lib/types/asset/loaders/audio.d.ts +7 -0
  54. package/lib/types/asset/loaders/audio.d.ts.map +1 -0
  55. package/lib/types/asset/loaders/binary.d.ts +7 -0
  56. package/lib/types/asset/loaders/binary.d.ts.map +1 -0
  57. package/lib/types/asset/loaders/font.d.ts +7 -0
  58. package/lib/types/asset/loaders/font.d.ts.map +1 -0
  59. package/lib/types/asset/loaders/loader.d.ts +13 -0
  60. package/lib/types/asset/loaders/loader.d.ts.map +1 -0
  61. package/lib/types/asset/loaders/spritesheet.d.ts +11 -0
  62. package/lib/types/asset/loaders/spritesheet.d.ts.map +1 -0
  63. package/lib/types/asset/loaders/text.d.ts +7 -0
  64. package/lib/types/asset/loaders/text.d.ts.map +1 -0
  65. package/lib/types/asset/loaders/texture.d.ts +9 -0
  66. package/lib/types/asset/loaders/texture.d.ts.map +1 -0
  67. package/lib/types/asset/preload.d.ts +8 -0
  68. package/lib/types/asset/preload.d.ts.map +1 -0
  69. package/lib/types/game-object/game-object-physics.d.ts +42 -0
  70. package/lib/types/game-object/game-object-physics.d.ts.map +1 -0
  71. package/lib/types/game-object/game-object-rendering.d.ts +15 -0
  72. package/lib/types/game-object/game-object-rendering.d.ts.map +1 -0
  73. package/lib/types/game-object/game-object.d.ts +81 -0
  74. package/lib/types/game-object/game-object.d.ts.map +1 -0
  75. package/lib/types/game-object/transform.d.ts +43 -0
  76. package/lib/types/game-object/transform.d.ts.map +1 -0
  77. package/lib/types/game-object-ext/animated-sprite.d.ts +29 -0
  78. package/lib/types/game-object-ext/animated-sprite.d.ts.map +1 -0
  79. package/lib/types/game-object-ext/dom-container.d.ts +16 -0
  80. package/lib/types/game-object-ext/dom-container.d.ts.map +1 -0
  81. package/lib/types/game-object-ext/rect.d.ts +17 -0
  82. package/lib/types/game-object-ext/rect.d.ts.map +1 -0
  83. package/lib/types/game-object-ext/spine.d.ts +35 -0
  84. package/lib/types/game-object-ext/spine.d.ts.map +1 -0
  85. package/lib/types/game-object-ext/sprite.d.ts +14 -0
  86. package/lib/types/game-object-ext/sprite.d.ts.map +1 -0
  87. package/lib/types/game-object-ext/text.d.ts +26 -0
  88. package/lib/types/game-object-ext/text.d.ts.map +1 -0
  89. package/lib/types/game-object-ext/tiling-sprite.d.ts +20 -0
  90. package/lib/types/game-object-ext/tiling-sprite.d.ts.map +1 -0
  91. package/lib/types/index.d.ts +14 -0
  92. package/lib/types/index.d.ts.map +1 -0
  93. package/lib/types/utils/debug.d.ts +3 -0
  94. package/lib/types/utils/debug.d.ts.map +1 -0
  95. package/lib/types/utils/go.d.ts +26 -0
  96. package/lib/types/utils/go.d.ts.map +1 -0
  97. package/lib/types/world/world-debug.d.ts +11 -0
  98. package/lib/types/world/world-debug.d.ts.map +1 -0
  99. package/lib/types/world/world-physics.d.ts +16 -0
  100. package/lib/types/world/world-physics.d.ts.map +1 -0
  101. package/lib/types/world/world-rendering.d.ts +28 -0
  102. package/lib/types/world/world-rendering.d.ts.map +1 -0
  103. package/lib/types/world/world.d.ts +38 -0
  104. package/lib/types/world/world.d.ts.map +1 -0
  105. package/lib/utils/debug.js +5 -0
  106. package/lib/utils/debug.js.map +1 -0
  107. package/lib/utils/go.js +33 -0
  108. package/lib/utils/go.js.map +1 -0
  109. package/lib/world/world-debug.js +89 -0
  110. package/lib/world/world-debug.js.map +1 -0
  111. package/lib/world/world-physics.js +45 -0
  112. package/lib/world/world-physics.js.map +1 -0
  113. package/lib/world/world-rendering.js +123 -0
  114. package/lib/world/world-rendering.js.map +1 -0
  115. package/lib/world/world.js +147 -0
  116. package/lib/world/world.js.map +1 -0
  117. package/package.json +23 -0
  118. package/src/asset/audio.ts +176 -0
  119. package/src/asset/loaders/audio.ts +39 -0
  120. package/src/asset/loaders/binary.ts +32 -0
  121. package/src/asset/loaders/font.ts +27 -0
  122. package/src/asset/loaders/loader.ts +39 -0
  123. package/src/asset/loaders/spritesheet.ts +67 -0
  124. package/src/asset/loaders/text.ts +31 -0
  125. package/src/asset/loaders/texture.ts +46 -0
  126. package/src/asset/preload.ts +76 -0
  127. package/src/game-object/game-object-physics.ts +191 -0
  128. package/src/game-object/game-object-rendering.ts +27 -0
  129. package/src/game-object/game-object.ts +190 -0
  130. package/src/game-object/transform.ts +164 -0
  131. package/src/game-object-ext/animated-sprite.ts +140 -0
  132. package/src/game-object-ext/dom-container.ts +67 -0
  133. package/src/game-object-ext/rect.ts +40 -0
  134. package/src/game-object-ext/spine.ts +235 -0
  135. package/src/game-object-ext/sprite.ts +55 -0
  136. package/src/game-object-ext/text.ts +83 -0
  137. package/src/game-object-ext/tiling-sprite.ts +73 -0
  138. package/src/index.ts +14 -0
  139. package/src/utils/debug.ts +5 -0
  140. package/src/utils/go.ts +53 -0
  141. package/src/world/world-debug.ts +114 -0
  142. package/src/world/world-physics.ts +52 -0
  143. package/src/world/world-rendering.ts +145 -0
  144. package/src/world/world.ts +171 -0
  145. package/tsconfig.json +33 -0
@@ -0,0 +1,140 @@
1
+ import { EventMap } from '@webtaku/event-emitter';
2
+ import { AnimatedSprite, Spritesheet, SpritesheetData } from 'pixi.js';
3
+ import { getCachedId, spritesheetLoader } from '../asset/loaders/spritesheet';
4
+ import { GameObject, GameObjectOptions } from '../game-object/game-object';
5
+
6
+ type AnimatedSpriteOptions = {
7
+ src?: string;
8
+ atlas?: SpritesheetData;
9
+ animation?: string;
10
+ fps?: number;
11
+ loop?: boolean;
12
+ } & GameObjectOptions;
13
+
14
+ class AnimatedSpriteObject<E extends EventMap = EventMap> extends GameObject<E & {
15
+ animationend: (animation: string) => void;
16
+ }> {
17
+ #id?: string;
18
+ #sheet?: Spritesheet;
19
+ #sprite?: AnimatedSprite;
20
+
21
+ #src?: string;
22
+ #atlas?: SpritesheetData;
23
+ #animation?: string;
24
+ #fps?: number;
25
+ #loop?: boolean;
26
+
27
+ constructor(opts?: AnimatedSpriteOptions) {
28
+ super(opts);
29
+ if (opts) {
30
+ if (opts.src) this.src = opts.src;
31
+ if (opts.atlas) this.atlas = opts.atlas;
32
+ if (opts.animation) this.animation = opts.animation;
33
+ if (opts.fps) this.fps = opts.fps;
34
+ if (opts.loop) this.loop = opts.loop;
35
+ }
36
+ }
37
+
38
+ #updateAnimation() {
39
+ this.#sprite?.destroy();
40
+ this.#sprite = undefined;
41
+
42
+ if (this.#sheet && this.#animation) {
43
+ if (!this.#sheet.animations[this.#animation]) {
44
+ console.error(`Animation not found: ${this.#animation}`);
45
+ return;
46
+ }
47
+ const sprite = new AnimatedSprite(this.#sheet.animations[this.#animation]);
48
+ sprite.anchor.set(0.5, 0.5);
49
+ sprite.loop = this.#loop ?? true;
50
+ sprite.animationSpeed = (this.#fps ?? 0) / 60;
51
+ sprite.play();
52
+ this._addPixiChild(sprite);
53
+ this.#sprite = sprite;
54
+
55
+ sprite.onLoop = () => (this as any).emit('animationend', this.#animation);
56
+ sprite.onComplete = () => (this as any).emit('animationend', this.#animation);
57
+ }
58
+ }
59
+
60
+ async #load() {
61
+ if (this.#id) spritesheetLoader.release(this.#id);
62
+
63
+ this.#id = undefined;
64
+ this.#sheet = undefined;
65
+ this.#sprite?.destroy();
66
+ this.#sprite = undefined;
67
+
68
+ if (this.#src && this.#atlas) {
69
+ this.#id = getCachedId(this.#src, this.#atlas);
70
+ if (!spritesheetLoader.checkLoaded(this.#id)) {
71
+ console.info(`Spritesheet not preloaded. Loading now: ${this.#id}`);
72
+ }
73
+ this.#sheet = await spritesheetLoader.load(this.#id, this.#src, this.#atlas);
74
+ }
75
+
76
+ this.#updateAnimation();
77
+ }
78
+
79
+ get src() {
80
+ return this.#src;
81
+ }
82
+
83
+ set src(src: string | undefined) {
84
+ if (this.#src !== src) {
85
+ this.#src = src;
86
+ this.#load();
87
+ }
88
+ }
89
+
90
+ get atlas() {
91
+ return this.#atlas;
92
+ }
93
+
94
+ set atlas(atlas: SpritesheetData | undefined) {
95
+ if (this.#atlas !== atlas) {
96
+ this.#atlas = atlas;
97
+ this.#load();
98
+ }
99
+ }
100
+
101
+ get animation() {
102
+ return this.#animation;
103
+ }
104
+
105
+ set animation(animation: string | undefined) {
106
+ if (this.#animation !== animation) {
107
+ this.#animation = animation;
108
+ this.#updateAnimation();
109
+ }
110
+ }
111
+
112
+ get fps() {
113
+ return this.#fps;
114
+ }
115
+
116
+ set fps(fps: number | undefined) {
117
+ if (this.#fps !== fps) {
118
+ this.#fps = fps;
119
+ if (this.#sprite) this.#sprite.animationSpeed = (fps ?? 0) / 60;
120
+ }
121
+ }
122
+
123
+ get loop() {
124
+ return this.#loop;
125
+ }
126
+
127
+ set loop(loop: boolean | undefined) {
128
+ if (this.#loop !== loop) {
129
+ this.#loop = loop;
130
+ if (this.#sprite) this.#sprite.loop = loop === true;
131
+ }
132
+ }
133
+
134
+ remove() {
135
+ if (this.#id) spritesheetLoader.release(this.#id);
136
+ super.remove();
137
+ }
138
+ }
139
+
140
+ export { AnimatedSpriteObject };
@@ -0,0 +1,67 @@
1
+ import { EventMap } from '@webtaku/event-emitter';
2
+ import { GameObject, GameObjectOptions } from "../game-object/game-object";
3
+ import { World } from '../world/world';
4
+
5
+ type DomContainerObjectOptions = {
6
+ el?: HTMLElement;
7
+ } & GameObjectOptions;
8
+
9
+ export class DomContainerObject<E extends EventMap = EventMap> extends GameObject<E> {
10
+ #el?: HTMLElement;
11
+
12
+ constructor(opts?: DomContainerObjectOptions) {
13
+ super(opts);
14
+ if (opts) {
15
+ if (opts.el) this.el = opts.el;
16
+ }
17
+ }
18
+
19
+ protected _setWorld(world: World): void {
20
+ super._setWorld(world);
21
+ if (this.#el) world.container.appendChild(this.#el);
22
+ }
23
+
24
+ get el() {
25
+ return this.#el;
26
+ }
27
+
28
+ set el(el: HTMLElement | undefined) {
29
+ this.#el = el;
30
+ if (el) {
31
+ el.style.position = 'absolute';
32
+ el.style.left = '0';
33
+ el.style.top = '0';
34
+ el.style.zIndex = '1';
35
+
36
+ const world = this._getWorld();
37
+ if (world) world.container.appendChild(el);
38
+ }
39
+ }
40
+
41
+ _afterRender() {
42
+ const world = this._getWorld();
43
+ if (world && this.#el) {
44
+ if (
45
+ world._containerSizeDirty ||
46
+ this._wt.x.dirty ||
47
+ this._wt.y.dirty ||
48
+ this._wt.scaleX.dirty ||
49
+ this._wt.scaleY.dirty ||
50
+ this._wt.rotation.dirty
51
+ ) {
52
+ const R = world._worldRendering;
53
+ const S = R.renderScale;
54
+
55
+ this.#el.style.transform = `
56
+ translate(
57
+ calc(-50% + ${this._wt.x.v * S + R.canvasLeft + R.centerX * S}px),
58
+ calc(-50% + ${this._wt.y.v * S + R.canvasTop + R.centerY * S}px)
59
+ )
60
+ scale(${this._wt.scaleX.v * S}, ${this._wt.scaleY.v * S})
61
+ rotate(${this._wt.rotation.v}rad)
62
+ `;
63
+ }
64
+ if (this._wt.alpha.dirty) this.#el.style.opacity = this._wt.alpha.v.toString();
65
+ }
66
+ }
67
+ }
@@ -0,0 +1,40 @@
1
+ import { EventMap } from '@webtaku/event-emitter';
2
+ import { FillInput, Graphics, StrokeInput } from 'pixi.js';
3
+ import { GameObject } from '../game-object/game-object';
4
+
5
+ class RectangleObject<E extends EventMap = EventMap> extends GameObject<E> {
6
+ #graphics = new Graphics({ zIndex: -999999 });
7
+ #width: number = 0;
8
+ #height: number = 0;
9
+ #fill?: FillInput;
10
+ #stroke?: StrokeInput;
11
+
12
+ constructor() {
13
+ super();
14
+ this._addPixiChild(this.#graphics);
15
+ }
16
+
17
+ #draw() {
18
+ this.#graphics.clear().rect(
19
+ -this.#width / 2,
20
+ -this.#height / 2,
21
+ this.#width,
22
+ this.#height,
23
+ );
24
+ if (this.#fill) this.#graphics.fill(this.#fill);
25
+ if (this.#stroke) this.#graphics.stroke(this.#stroke);
26
+ }
27
+
28
+ get width(): number { return this.#width; }
29
+ set width(value: number) { this.#width = value; this.#draw(); }
30
+ get height(): number { return this.#height; }
31
+ set height(value: number) { this.#height = value; this.#draw(); }
32
+
33
+ get fill(): FillInput | undefined { return this.#fill; }
34
+ set fill(value: FillInput | undefined) { this.#fill = value; this.#draw(); }
35
+
36
+ get stroke(): StrokeInput | undefined { return this.#stroke; }
37
+ set stroke(value: StrokeInput | undefined) { this.#stroke = value; this.#draw(); }
38
+ }
39
+
40
+ export { RectangleObject };
@@ -0,0 +1,235 @@
1
+ import { AtlasAttachmentLoader, SkeletonBinary, SkeletonData, SkeletonJson, Skin, Spine, SpineTexture, TextureAtlas } from '@esotericsoftware/spine-pixi-v8';
2
+ import { EventMap } from '@webtaku/event-emitter';
3
+ import { Texture } from 'pixi.js';
4
+ import { binaryLoader } from '../asset/loaders/binary';
5
+ import { textLoader } from '../asset/loaders/text';
6
+ import { textureLoader } from '../asset/loaders/texture';
7
+ import { GameObject, GameObjectOptions } from '../game-object/game-object';
8
+
9
+ type SpineOptions = {
10
+ atlas?: string;
11
+ skeletonData?: any;
12
+ skel?: string;
13
+ json?: string;
14
+ texture?: string | Record<string, string>;
15
+ skins?: string[];
16
+ animation?: string;
17
+ loop?: boolean;
18
+ } & GameObjectOptions;
19
+
20
+ class SpineObject<E extends EventMap = EventMap> extends GameObject<E> {
21
+ #spine?: Spine;
22
+
23
+ #atlas?: string;
24
+ #skeletonData?: any;
25
+ #skel?: string;
26
+ #json?: string;
27
+ #texture?: string | Record<string, string>;
28
+ #skins?: string[];
29
+ #animation?: string;
30
+ #loop?: boolean;
31
+
32
+ constructor(opts?: SpineOptions) {
33
+ super(opts);
34
+ if (opts) {
35
+ if (opts.atlas) this.atlas = opts.atlas;
36
+ if (opts.skeletonData) this.skeletonData = opts.skeletonData;
37
+ if (opts.skel) this.skel = opts.skel;
38
+ if (opts.json) this.json = opts.json;
39
+ if (opts.texture) this.texture = opts.texture;
40
+ if (opts.skins) this.skins = opts.skins;
41
+ if (opts.animation) this.animation = opts.animation;
42
+ if (opts.loop) this.loop = opts.loop;
43
+ }
44
+ }
45
+
46
+ async #load() {
47
+ if (this.#atlas && (
48
+ this.#skeletonData ||
49
+ this.#skel ||
50
+ this.#json
51
+ )) {
52
+ const promises: Promise<any>[] = [];
53
+
54
+ let textAtlasData: string | undefined;
55
+ let skeletonBynary: Uint8Array | undefined;
56
+ let textSkeletonData: string | undefined;
57
+
58
+ let texture: Texture | undefined;
59
+ let textures: Record<string, Texture> | undefined;
60
+
61
+ if (!textLoader.checkLoaded(this.#atlas)) console.info(`Atlas not preloaded. Loading now: ${this.#atlas}`);
62
+ promises.push((async () => textAtlasData = await textLoader.load(this.#atlas!))());
63
+
64
+ if (this.#skeletonData) {
65
+ // Skeleton data is already loaded, no need to load again
66
+ } else if (this.#skel) {
67
+ if (!binaryLoader.checkLoaded(this.#skel)) console.info(`Skeleton not preloaded. Loading now: ${this.#skel}`);
68
+ promises.push((async () => skeletonBynary = await binaryLoader.load(this.#skel!))());
69
+ } else if (this.#json) {
70
+ if (!textLoader.checkLoaded(this.#json)) console.info(`Skeleton not preloaded. Loading now: ${this.#json}`);
71
+ promises.push((async () => textSkeletonData = await textLoader.load(this.#json!))());
72
+ } else {
73
+ console.error('Either skel or json must be provided');
74
+ return;
75
+ }
76
+
77
+ if (typeof this.#texture === 'string') {
78
+ if (!textureLoader.checkLoaded(this.#texture)) console.info(`Texture not preloaded. Loading now: ${this.#texture}`);
79
+ promises.push((async () => texture = await textureLoader.load(this.#texture as string))());
80
+ } else if (this.#texture) {
81
+ textures = {};
82
+ for (const [key, path] of Object.entries(this.#texture)) {
83
+ if (!textureLoader.checkLoaded(path)) console.info(`Texture not preloaded. Loading now: ${path}`);
84
+ promises.push((async () => {
85
+ const texture = await textureLoader.load(path);
86
+ if (texture) textures[key] = texture;
87
+ })());
88
+ }
89
+ }
90
+
91
+ await Promise.all(promises);
92
+
93
+ if (texture || textures) {
94
+ const atlas = new TextureAtlas(textAtlasData!);
95
+ atlas.pages.forEach((page) => {
96
+ if (texture) page.setTexture(SpineTexture.from(texture.source));
97
+ else if (textures) {
98
+ page.setTexture(SpineTexture.from(textures[page.name].source));
99
+ }
100
+ });
101
+
102
+ const atlasLoader = new AtlasAttachmentLoader(atlas);
103
+
104
+ let skeletonData: SkeletonData;
105
+ if (this.#skeletonData) {
106
+ const jsonLoader = new SkeletonJson(atlasLoader);
107
+ skeletonData = jsonLoader.readSkeletonData(this.#skeletonData);
108
+ } else if (skeletonBynary) {
109
+ const binaryLoader = new SkeletonBinary(atlasLoader);
110
+ skeletonData = binaryLoader.readSkeletonData(skeletonBynary);
111
+ } else if (textSkeletonData) {
112
+ const jsonLoader = new SkeletonJson(atlasLoader);
113
+ skeletonData = jsonLoader.readSkeletonData(textSkeletonData);
114
+ } else {
115
+ console.error('Either skel or json must be provided');
116
+ return;
117
+ }
118
+
119
+ this.#spine = new Spine(skeletonData);
120
+ this.#applyAnimation();
121
+ this.#applySkins();
122
+
123
+ this._addPixiChild(this.#spine);
124
+ }
125
+ }
126
+ }
127
+
128
+ #applyAnimation() {
129
+ if (this.#spine && this.#animation) {
130
+ this.#spine.state.setAnimation(
131
+ 0,
132
+ this.#animation,
133
+ this.#loop ?? true,
134
+ );
135
+ this.#spine.state.apply(this.#spine.skeleton);
136
+ }
137
+ }
138
+
139
+ #applySkins() {
140
+ if (this.#spine && this.#skins) {
141
+ const newSkin = new Skin('combined-skin');
142
+ for (const skinName of this.#skins) {
143
+ const skin = this.#spine.skeleton.data.findSkin(skinName);
144
+ if (skin) newSkin.addSkin(skin);
145
+ }
146
+ this.#spine.skeleton.setSkin(newSkin);
147
+ this.#spine.skeleton.setSlotsToSetupPose();
148
+ }
149
+ }
150
+
151
+ get atlas() {
152
+ return this.#atlas;
153
+ }
154
+
155
+ set atlas(atlas: string | undefined) {
156
+ this.#atlas = atlas;
157
+ this.#load();
158
+ }
159
+
160
+ get skeletonData() {
161
+ return this.#skeletonData;
162
+ }
163
+
164
+ set skeletonData(skeletonData: any | undefined) {
165
+ this.#skeletonData = skeletonData;
166
+ this.#load();
167
+ }
168
+
169
+ get skel() {
170
+ return this.#skel;
171
+ }
172
+
173
+ set skel(skel: string | undefined) {
174
+ this.#skel = skel;
175
+ this.#load();
176
+ }
177
+
178
+ get json() {
179
+ return this.#json;
180
+ }
181
+
182
+ set json(json: string | undefined) {
183
+ this.#json = json;
184
+ this.#load();
185
+ }
186
+
187
+ get texture() {
188
+ return this.#texture;
189
+ }
190
+
191
+ set texture(texture: string | Record<string, string> | undefined) {
192
+ this.#texture = texture;
193
+ this.#load();
194
+ }
195
+
196
+ get skins() {
197
+ return this.#skins;
198
+ }
199
+
200
+ set skins(skins: string[] | undefined) {
201
+ this.#skins = skins;
202
+ this.#applySkins();
203
+ }
204
+
205
+ get animation() {
206
+ return this.#animation;
207
+ }
208
+
209
+ set animation(animation: string | undefined) {
210
+ this.#animation = animation;
211
+ this.#applyAnimation();
212
+ }
213
+
214
+ get loop() {
215
+ return this.#loop;
216
+ }
217
+
218
+ set loop(loop: boolean | undefined) {
219
+ this.#loop = loop;
220
+ this.#applyAnimation();
221
+ }
222
+
223
+ remove() {
224
+ if (typeof this.#texture === 'string') {
225
+ textureLoader.release(this.#texture);
226
+ } else if (this.#texture) {
227
+ for (const path of Object.values(this.#texture)) {
228
+ textureLoader.release(path);
229
+ }
230
+ }
231
+ super.remove();
232
+ }
233
+ }
234
+
235
+ export { SpineObject };
@@ -0,0 +1,55 @@
1
+ import { EventMap } from '@webtaku/event-emitter';
2
+ import { Sprite } from 'pixi.js';
3
+ import { textureLoader } from '../asset/loaders/texture';
4
+ import { GameObject, GameObjectOptions } from '../game-object/game-object';
5
+
6
+ type SpriteOptions = {
7
+ src?: string;
8
+ } & GameObjectOptions;
9
+
10
+ class SpriteObject<E extends EventMap = EventMap> extends GameObject<E> {
11
+ #sprite?: Sprite;
12
+ #src?: string;
13
+
14
+ constructor(opts?: SpriteOptions) {
15
+ super(opts);
16
+ if (opts) {
17
+ if (opts.src) this.src = opts.src;
18
+ }
19
+ }
20
+
21
+ async #load() {
22
+ this.#sprite?.destroy({ children: true });
23
+ this.#sprite = undefined;
24
+
25
+ if (this.#src) {
26
+ if (!textureLoader.checkLoaded(this.#src)) {
27
+ console.info(`Texture not preloaded. Loading now: ${this.#src}`);
28
+ }
29
+ const texture = await textureLoader.load(this.#src);
30
+ if (texture) {
31
+ this.#sprite = new Sprite({ texture, anchor: 0.5, zIndex: -999999 });
32
+ this._addPixiChild(this.#sprite);
33
+ }
34
+ }
35
+ }
36
+
37
+ get src() {
38
+ return this.#src;
39
+ }
40
+
41
+ set src(src: string | undefined) {
42
+ if (this.#src !== src) {
43
+ if (this.#src) textureLoader.release(this.#src);
44
+ this.#src = src;
45
+ this.#load();
46
+ }
47
+ }
48
+
49
+ remove() {
50
+ if (this.#src) textureLoader.release(this.#src);
51
+ super.remove();
52
+ }
53
+ }
54
+
55
+ export { SpriteObject };
@@ -0,0 +1,83 @@
1
+ import { EventMap } from '@webtaku/event-emitter';
2
+ import { Text as PixiText } from 'pixi.js';
3
+ import { GameObject, GameObjectOptions } from '../game-object/game-object';
4
+
5
+ type TextObjectOptions = {
6
+ text: string;
7
+ textAlign?: 'left' | 'center' | 'right';
8
+ fontSize?: number;
9
+ color?: string;
10
+ } & GameObjectOptions;
11
+
12
+ class TextObject<E extends EventMap = EventMap> extends GameObject<E> {
13
+ #pixiText = new PixiText({ anchor: 0.5 });
14
+ #text?: string;
15
+ #textAlign?: 'left' | 'center' | 'right';
16
+ #fontSize?: number;
17
+ #color?: string;
18
+
19
+ constructor(opts?: TextObjectOptions) {
20
+ super(opts);
21
+ this._addPixiChild(this.#pixiText);
22
+ if (opts) {
23
+ if (opts.text) this.text = opts.text;
24
+ if (opts.textAlign) this.textAlign = opts.textAlign;
25
+ if (opts.fontSize) this.fontSize = opts.fontSize;
26
+ if (opts.color) this.color = opts.color;
27
+ }
28
+ }
29
+
30
+ get text() {
31
+ return this.#text;
32
+ }
33
+
34
+ set text(text: string | undefined) {
35
+ this.#text = text;
36
+ this.#pixiText.text = text || '';
37
+ }
38
+
39
+ get textAlign() {
40
+ return this.#textAlign;
41
+ }
42
+
43
+ set textAlign(textAlign: 'left' | 'center' | 'right' | undefined) {
44
+ this.#textAlign = textAlign;
45
+ if (textAlign !== undefined) this.#pixiText.style.align = textAlign;
46
+ }
47
+
48
+ get fontSize() {
49
+ return this.#fontSize;
50
+ }
51
+
52
+ set fontSize(fontSize: number | undefined) {
53
+ this.#fontSize = fontSize;
54
+ if (fontSize !== undefined) this.#pixiText.style.fontSize = fontSize;
55
+ }
56
+
57
+ get color() {
58
+ return this.#color;
59
+ }
60
+
61
+ set color(color: string | undefined) {
62
+ this.#color = color;
63
+ if (color !== undefined) this.#pixiText.style.fill = color;
64
+ }
65
+
66
+ get anchorX() {
67
+ return this.#pixiText.anchor.x - 0.5;
68
+ }
69
+
70
+ set anchorX(value: number) {
71
+ this.#pixiText.anchor.x = value + 0.5;
72
+ }
73
+
74
+ get anchorY() {
75
+ return this.#pixiText.anchor.y - 0.5;
76
+ }
77
+
78
+ set anchorY(value: number) {
79
+ this.#pixiText.anchor.y = value + 0.5;
80
+ }
81
+ }
82
+
83
+ export { TextObject };
@@ -0,0 +1,73 @@
1
+ import { EventMap } from '@webtaku/event-emitter';
2
+ import { TilingSprite } from 'pixi.js';
3
+ import { textureLoader } from '../asset/loaders/texture';
4
+ import { GameObject, GameObjectOptions } from '../game-object/game-object';
5
+ import { WorldTransform } from '../game-object/transform';
6
+
7
+ type TilingSpriteOptions = {
8
+ src?: string;
9
+ scrollSpeedX?: number;
10
+ scrollSpeedY?: number;
11
+ } & GameObjectOptions;
12
+
13
+ class TilingSpriteObject<E extends EventMap = EventMap> extends GameObject<E> {
14
+ #sprite?: TilingSprite;
15
+ #src?: string;
16
+
17
+ scrollSpeedX?: number;
18
+ scrollSpeedY?: number;
19
+
20
+ constructor(opts?: TilingSpriteOptions) {
21
+ super();
22
+ if (opts) {
23
+ if (opts.src) this.src = opts.src;
24
+ if (opts.scrollSpeedX) this.scrollSpeedX = opts.scrollSpeedX;
25
+ if (opts.scrollSpeedY) this.scrollSpeedY = opts.scrollSpeedY;
26
+ }
27
+ }
28
+
29
+ async #load() {
30
+ if (this.#src) {
31
+ if (!textureLoader.checkLoaded(this.#src)) {
32
+ console.info(`Tiling sprite not preloaded. Loading now: ${this.#src}`);
33
+ }
34
+ const texture = await textureLoader.load(this.#src);
35
+ if (texture) {
36
+ const sprite = new TilingSprite({
37
+ texture,
38
+ anchor: 0.5,
39
+ zIndex: -999999,
40
+ });
41
+ this._addPixiChild(sprite);
42
+ this.#sprite = sprite;
43
+ }
44
+ }
45
+ }
46
+
47
+ get src() {
48
+ return this.#src;
49
+ }
50
+
51
+ set src(src: string | undefined) {
52
+ this.#sprite?.destroy({ children: true });
53
+ this.#sprite = undefined;
54
+ if (this.#src) textureLoader.release(this.#src);
55
+ this.#src = src;
56
+ this.#load();
57
+ }
58
+
59
+ _engineUpdate(dt: number, pt: WorldTransform) {
60
+ if (this.#sprite) {
61
+ if (this.scrollSpeedX !== undefined) this.#sprite.tilePosition.x += this.scrollSpeedX * dt;
62
+ if (this.scrollSpeedY !== undefined) this.#sprite.tilePosition.y += this.scrollSpeedY * dt;
63
+ }
64
+ super._engineUpdate(dt, pt);
65
+ }
66
+
67
+ remove() {
68
+ if (this.#src) textureLoader.release(this.#src);
69
+ super.remove();
70
+ }
71
+ }
72
+
73
+ export { TilingSpriteObject };
package/src/index.ts ADDED
@@ -0,0 +1,14 @@
1
+ export { musicPlayer, sfxPlayer } from './asset/audio';
2
+ export { AssetSource, preload } from './asset/preload';
3
+ export { AnimatedSpriteObject } from './game-object-ext/animated-sprite';
4
+ export { DomContainerObject } from './game-object-ext/dom-container';
5
+ export { RectangleObject } from './game-object-ext/rect';
6
+ export { SpineObject } from './game-object-ext/spine';
7
+ export { SpriteObject } from './game-object-ext/sprite';
8
+ export { TextObject } from './game-object-ext/text';
9
+ export { GameObject, GameObjectOptions } from './game-object/game-object';
10
+ export { Collider } from './game-object/game-object-physics';
11
+ export { enableDebug } from './utils/debug';
12
+ export { go } from './utils/go';
13
+ export { World } from './world/world';
14
+