kiwiengine 0.0.1-alpha → 0.5.3

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 (599) hide show
  1. package/README.ko.md +550 -0
  2. package/README.md +575 -4
  3. package/examples/auto-battle/assets/bgm/battle.mp3 +0 -0
  4. package/examples/auto-battle/assets/bitmap-fonts/white-peaberry.fnt +107 -0
  5. package/examples/auto-battle/assets/bitmap-fonts/white-peaberry.png +0 -0
  6. package/examples/auto-battle/assets/joystick/joystick.png +0 -0
  7. package/examples/auto-battle/assets/joystick/knob.png +0 -0
  8. package/examples/auto-battle/assets/sfx/hero/die/die.wav +0 -0
  9. package/examples/auto-battle/assets/sfx/hero/heal/heal.wav +0 -0
  10. package/examples/auto-battle/assets/sfx/hero/hit/hit1.wav +0 -0
  11. package/examples/auto-battle/assets/sfx/hero/hit/hit2.wav +0 -0
  12. package/examples/auto-battle/assets/sfx/hero/hit/hit3.wav +0 -0
  13. package/examples/auto-battle/assets/sfx/hero/miss/miss1.wav +0 -0
  14. package/examples/auto-battle/assets/sfx/hero/miss/miss2.wav +0 -0
  15. package/examples/auto-battle/assets/sfx/hero/miss/miss3.wav +0 -0
  16. package/examples/auto-battle/assets/sfx/orc/die/die.wav +0 -0
  17. package/examples/auto-battle/assets/sfx/orc/hit/hit1.wav +0 -0
  18. package/examples/auto-battle/assets/sfx/orc/hit/hit2.wav +0 -0
  19. package/examples/auto-battle/assets/sfx/orc/hit/hit3.wav +0 -0
  20. package/examples/auto-battle/assets/sfx/orc/miss/miss1.wav +0 -0
  21. package/examples/auto-battle/assets/sfx/orc/miss/miss2.wav +0 -0
  22. package/examples/auto-battle/assets/sfx/orc/miss/miss3.wav +0 -0
  23. package/examples/auto-battle/assets/spritesheets/hero-atlas.json +246 -0
  24. package/examples/auto-battle/assets/spritesheets/hero.png +0 -0
  25. package/examples/auto-battle/assets/spritesheets/orc-atlas.json +246 -0
  26. package/examples/auto-battle/assets/spritesheets/orc.png +0 -0
  27. package/examples/auto-battle/assets/spritesheets/potion-atlas.json +68 -0
  28. package/examples/auto-battle/assets/spritesheets/potion.png +0 -0
  29. package/examples/auto-battle/dist/game.js +2 -0
  30. package/examples/auto-battle/dist/game.js.LICENSE.txt +35 -0
  31. package/examples/auto-battle/hud/damage-text.ts +46 -0
  32. package/examples/auto-battle/hud/heal-text.ts +46 -0
  33. package/examples/auto-battle/hud/hp-bar.ts +38 -0
  34. package/examples/auto-battle/index.ts +41 -0
  35. package/examples/auto-battle/objects/character.ts +95 -0
  36. package/examples/auto-battle/objects/hero.ts +119 -0
  37. package/examples/auto-battle/objects/orc.ts +107 -0
  38. package/examples/auto-battle/objects/potion.ts +27 -0
  39. package/examples/auto-battle/stage.ts +366 -0
  40. package/examples/battle-benchmark-matterjs/assets/bgm/battle.mp3 +0 -0
  41. package/examples/battle-benchmark-matterjs/assets/bitmap-fonts/white-peaberry.fnt +107 -0
  42. package/examples/battle-benchmark-matterjs/assets/bitmap-fonts/white-peaberry.png +0 -0
  43. package/examples/battle-benchmark-matterjs/assets/joystick/joystick.png +0 -0
  44. package/examples/battle-benchmark-matterjs/assets/joystick/knob.png +0 -0
  45. package/examples/battle-benchmark-matterjs/assets/sfx/hero/die/die.wav +0 -0
  46. package/examples/battle-benchmark-matterjs/assets/sfx/hero/heal/heal.wav +0 -0
  47. package/examples/battle-benchmark-matterjs/assets/sfx/hero/hit/hit1.wav +0 -0
  48. package/examples/battle-benchmark-matterjs/assets/sfx/hero/hit/hit2.wav +0 -0
  49. package/examples/battle-benchmark-matterjs/assets/sfx/hero/hit/hit3.wav +0 -0
  50. package/examples/battle-benchmark-matterjs/assets/sfx/hero/miss/miss1.wav +0 -0
  51. package/examples/battle-benchmark-matterjs/assets/sfx/hero/miss/miss2.wav +0 -0
  52. package/examples/battle-benchmark-matterjs/assets/sfx/hero/miss/miss3.wav +0 -0
  53. package/examples/battle-benchmark-matterjs/assets/sfx/orc/die/die.wav +0 -0
  54. package/examples/battle-benchmark-matterjs/assets/sfx/orc/hit/hit1.wav +0 -0
  55. package/examples/battle-benchmark-matterjs/assets/sfx/orc/hit/hit2.wav +0 -0
  56. package/examples/battle-benchmark-matterjs/assets/sfx/orc/hit/hit3.wav +0 -0
  57. package/examples/battle-benchmark-matterjs/assets/sfx/orc/miss/miss1.wav +0 -0
  58. package/examples/battle-benchmark-matterjs/assets/sfx/orc/miss/miss2.wav +0 -0
  59. package/examples/battle-benchmark-matterjs/assets/sfx/orc/miss/miss3.wav +0 -0
  60. package/examples/battle-benchmark-matterjs/assets/spritesheets/hero-atlas.json +246 -0
  61. package/examples/battle-benchmark-matterjs/assets/spritesheets/hero.png +0 -0
  62. package/examples/battle-benchmark-matterjs/assets/spritesheets/orc-atlas.json +246 -0
  63. package/examples/battle-benchmark-matterjs/assets/spritesheets/orc.png +0 -0
  64. package/examples/battle-benchmark-matterjs/assets/spritesheets/potion-atlas.json +68 -0
  65. package/examples/battle-benchmark-matterjs/assets/spritesheets/potion.png +0 -0
  66. package/examples/battle-benchmark-matterjs/dist/game.js +2 -0
  67. package/examples/battle-benchmark-matterjs/dist/game.js.LICENSE.txt +35 -0
  68. package/examples/battle-benchmark-matterjs/hud/damage-text.ts +46 -0
  69. package/examples/battle-benchmark-matterjs/hud/heal-text.ts +46 -0
  70. package/examples/battle-benchmark-matterjs/hud/hp-bar.ts +38 -0
  71. package/examples/battle-benchmark-matterjs/index.html +24 -0
  72. package/examples/battle-benchmark-matterjs/index.ts +41 -0
  73. package/examples/battle-benchmark-matterjs/objects/character.ts +95 -0
  74. package/examples/battle-benchmark-matterjs/objects/hero.ts +111 -0
  75. package/examples/battle-benchmark-matterjs/objects/orc.ts +107 -0
  76. package/examples/battle-benchmark-matterjs/objects/potion.ts +27 -0
  77. package/examples/battle-benchmark-matterjs/stage.ts +177 -0
  78. package/examples/battle-benchmark-separation/assets/bgm/battle.mp3 +0 -0
  79. package/examples/battle-benchmark-separation/assets/bitmap-fonts/white-peaberry.fnt +107 -0
  80. package/examples/battle-benchmark-separation/assets/bitmap-fonts/white-peaberry.png +0 -0
  81. package/examples/battle-benchmark-separation/assets/joystick/joystick.png +0 -0
  82. package/examples/battle-benchmark-separation/assets/joystick/knob.png +0 -0
  83. package/examples/battle-benchmark-separation/assets/sfx/hero/die/die.wav +0 -0
  84. package/examples/battle-benchmark-separation/assets/sfx/hero/heal/heal.wav +0 -0
  85. package/examples/battle-benchmark-separation/assets/sfx/hero/hit/hit1.wav +0 -0
  86. package/examples/battle-benchmark-separation/assets/sfx/hero/hit/hit2.wav +0 -0
  87. package/examples/battle-benchmark-separation/assets/sfx/hero/hit/hit3.wav +0 -0
  88. package/examples/battle-benchmark-separation/assets/sfx/hero/miss/miss1.wav +0 -0
  89. package/examples/battle-benchmark-separation/assets/sfx/hero/miss/miss2.wav +0 -0
  90. package/examples/battle-benchmark-separation/assets/sfx/hero/miss/miss3.wav +0 -0
  91. package/examples/battle-benchmark-separation/assets/sfx/orc/die/die.wav +0 -0
  92. package/examples/battle-benchmark-separation/assets/sfx/orc/hit/hit1.wav +0 -0
  93. package/examples/battle-benchmark-separation/assets/sfx/orc/hit/hit2.wav +0 -0
  94. package/examples/battle-benchmark-separation/assets/sfx/orc/hit/hit3.wav +0 -0
  95. package/examples/battle-benchmark-separation/assets/sfx/orc/miss/miss1.wav +0 -0
  96. package/examples/battle-benchmark-separation/assets/sfx/orc/miss/miss2.wav +0 -0
  97. package/examples/battle-benchmark-separation/assets/sfx/orc/miss/miss3.wav +0 -0
  98. package/examples/battle-benchmark-separation/assets/spritesheets/hero-atlas.json +246 -0
  99. package/examples/battle-benchmark-separation/assets/spritesheets/hero.png +0 -0
  100. package/examples/battle-benchmark-separation/assets/spritesheets/orc-atlas.json +246 -0
  101. package/examples/battle-benchmark-separation/assets/spritesheets/orc.png +0 -0
  102. package/examples/battle-benchmark-separation/assets/spritesheets/potion-atlas.json +68 -0
  103. package/examples/battle-benchmark-separation/assets/spritesheets/potion.png +0 -0
  104. package/examples/battle-benchmark-separation/dist/game.js +2 -0
  105. package/examples/battle-benchmark-separation/dist/game.js.LICENSE.txt +35 -0
  106. package/examples/battle-benchmark-separation/hud/damage-text.ts +46 -0
  107. package/examples/battle-benchmark-separation/hud/heal-text.ts +46 -0
  108. package/examples/battle-benchmark-separation/hud/hp-bar.ts +38 -0
  109. package/examples/battle-benchmark-separation/index.html +24 -0
  110. package/examples/battle-benchmark-separation/index.ts +41 -0
  111. package/examples/battle-benchmark-separation/objects/character.ts +225 -0
  112. package/examples/battle-benchmark-separation/objects/hero.ts +110 -0
  113. package/examples/battle-benchmark-separation/objects/orc.ts +213 -0
  114. package/examples/battle-benchmark-separation/objects/potion.ts +27 -0
  115. package/examples/battle-benchmark-separation/stage.ts +178 -0
  116. package/examples/battle-benchmark-separation2/assets/bgm/battle.mp3 +0 -0
  117. package/examples/battle-benchmark-separation2/assets/bitmap-fonts/white-peaberry.fnt +107 -0
  118. package/examples/battle-benchmark-separation2/assets/bitmap-fonts/white-peaberry.png +0 -0
  119. package/examples/battle-benchmark-separation2/assets/joystick/joystick.png +0 -0
  120. package/examples/battle-benchmark-separation2/assets/joystick/knob.png +0 -0
  121. package/examples/battle-benchmark-separation2/assets/sfx/hero/die/die.wav +0 -0
  122. package/examples/battle-benchmark-separation2/assets/sfx/hero/heal/heal.wav +0 -0
  123. package/examples/battle-benchmark-separation2/assets/sfx/hero/hit/hit1.wav +0 -0
  124. package/examples/battle-benchmark-separation2/assets/sfx/hero/hit/hit2.wav +0 -0
  125. package/examples/battle-benchmark-separation2/assets/sfx/hero/hit/hit3.wav +0 -0
  126. package/examples/battle-benchmark-separation2/assets/sfx/hero/miss/miss1.wav +0 -0
  127. package/examples/battle-benchmark-separation2/assets/sfx/hero/miss/miss2.wav +0 -0
  128. package/examples/battle-benchmark-separation2/assets/sfx/hero/miss/miss3.wav +0 -0
  129. package/examples/battle-benchmark-separation2/assets/sfx/orc/die/die.wav +0 -0
  130. package/examples/battle-benchmark-separation2/assets/sfx/orc/hit/hit1.wav +0 -0
  131. package/examples/battle-benchmark-separation2/assets/sfx/orc/hit/hit2.wav +0 -0
  132. package/examples/battle-benchmark-separation2/assets/sfx/orc/hit/hit3.wav +0 -0
  133. package/examples/battle-benchmark-separation2/assets/sfx/orc/miss/miss1.wav +0 -0
  134. package/examples/battle-benchmark-separation2/assets/sfx/orc/miss/miss2.wav +0 -0
  135. package/examples/battle-benchmark-separation2/assets/sfx/orc/miss/miss3.wav +0 -0
  136. package/examples/battle-benchmark-separation2/assets/spritesheets/hero-atlas.json +246 -0
  137. package/examples/battle-benchmark-separation2/assets/spritesheets/hero.png +0 -0
  138. package/examples/battle-benchmark-separation2/assets/spritesheets/orc-atlas.json +246 -0
  139. package/examples/battle-benchmark-separation2/assets/spritesheets/orc.png +0 -0
  140. package/examples/battle-benchmark-separation2/assets/spritesheets/potion-atlas.json +68 -0
  141. package/examples/battle-benchmark-separation2/assets/spritesheets/potion.png +0 -0
  142. package/examples/battle-benchmark-separation2/dist/game.js +2 -0
  143. package/examples/battle-benchmark-separation2/dist/game.js.LICENSE.txt +35 -0
  144. package/examples/battle-benchmark-separation2/hud/damage-text.ts +46 -0
  145. package/examples/battle-benchmark-separation2/hud/heal-text.ts +46 -0
  146. package/examples/battle-benchmark-separation2/hud/hp-bar.ts +38 -0
  147. package/examples/battle-benchmark-separation2/index.html +24 -0
  148. package/examples/battle-benchmark-separation2/index.ts +41 -0
  149. package/examples/battle-benchmark-separation2/objects/character.ts +195 -0
  150. package/examples/battle-benchmark-separation2/objects/hero.ts +110 -0
  151. package/examples/battle-benchmark-separation2/objects/orc.ts +213 -0
  152. package/examples/battle-benchmark-separation2/objects/potion.ts +27 -0
  153. package/examples/battle-benchmark-separation2/stage.ts +178 -0
  154. package/examples/collision-test/assets/cat.png +0 -0
  155. package/examples/collision-test/dist/game.js +2 -0
  156. package/examples/collision-test/dist/game.js.LICENSE.txt +35 -0
  157. package/examples/collision-test/index.html +24 -0
  158. package/examples/collision-test/index.ts +30 -0
  159. package/examples/dom-particle-test/assets/bird.png +0 -0
  160. package/examples/dom-particle-test/dist/game.js +2 -0
  161. package/examples/dom-particle-test/dist/game.js.LICENSE.txt +35 -0
  162. package/examples/dom-particle-test/index.html +24 -0
  163. package/examples/dom-particle-test/index.ts +27 -0
  164. package/examples/dom-sprite-test/assets/bird.png +0 -0
  165. package/examples/dom-sprite-test/assets/fire.png +0 -0
  166. package/examples/dom-sprite-test/assets/run.png +0 -0
  167. package/examples/dom-sprite-test/dist/game.js +2 -0
  168. package/examples/dom-sprite-test/dist/game.js.LICENSE.txt +35 -0
  169. package/examples/dom-sprite-test/index.html +24 -0
  170. package/examples/dom-sprite-test/index.ts +35 -0
  171. package/examples/dom-test/dist/game.js +2 -0
  172. package/examples/dom-test/dist/game.js.LICENSE.txt +35 -0
  173. package/examples/dom-test/index.html +24 -0
  174. package/examples/dom-test/index.ts +22 -0
  175. package/examples/particle-test/assets/bird.png +0 -0
  176. package/examples/particle-test/dist/game.js +2 -0
  177. package/examples/particle-test/dist/game.js.LICENSE.txt +35 -0
  178. package/examples/particle-test/index.html +24 -0
  179. package/examples/particle-test/index.ts +30 -0
  180. package/examples/renderer-test/dist/game.js +2 -0
  181. package/examples/renderer-test/dist/game.js.LICENSE.txt +35 -0
  182. package/examples/renderer-test/index.html +24 -0
  183. package/examples/renderer-test/index.ts +9 -0
  184. package/examples/simple-battle/assets/bgm/battle.mp3 +0 -0
  185. package/examples/simple-battle/assets/bitmap-fonts/white-peaberry.fnt +107 -0
  186. package/examples/simple-battle/assets/bitmap-fonts/white-peaberry.png +0 -0
  187. package/examples/simple-battle/assets/joystick/joystick.png +0 -0
  188. package/examples/simple-battle/assets/joystick/knob.png +0 -0
  189. package/examples/simple-battle/assets/sfx/hero/die/die.wav +0 -0
  190. package/examples/simple-battle/assets/sfx/hero/heal/heal.wav +0 -0
  191. package/examples/simple-battle/assets/sfx/hero/hit/hit1.wav +0 -0
  192. package/examples/simple-battle/assets/sfx/hero/hit/hit2.wav +0 -0
  193. package/examples/simple-battle/assets/sfx/hero/hit/hit3.wav +0 -0
  194. package/examples/simple-battle/assets/sfx/hero/miss/miss1.wav +0 -0
  195. package/examples/simple-battle/assets/sfx/hero/miss/miss2.wav +0 -0
  196. package/examples/simple-battle/assets/sfx/hero/miss/miss3.wav +0 -0
  197. package/examples/simple-battle/assets/sfx/orc/die/die.wav +0 -0
  198. package/examples/simple-battle/assets/sfx/orc/hit/hit1.wav +0 -0
  199. package/examples/simple-battle/assets/sfx/orc/hit/hit2.wav +0 -0
  200. package/examples/simple-battle/assets/sfx/orc/hit/hit3.wav +0 -0
  201. package/examples/simple-battle/assets/sfx/orc/miss/miss1.wav +0 -0
  202. package/examples/simple-battle/assets/sfx/orc/miss/miss2.wav +0 -0
  203. package/examples/simple-battle/assets/sfx/orc/miss/miss3.wav +0 -0
  204. package/examples/simple-battle/assets/spritesheets/hero-atlas.json +246 -0
  205. package/examples/simple-battle/assets/spritesheets/hero.png +0 -0
  206. package/examples/simple-battle/assets/spritesheets/orc-atlas.json +246 -0
  207. package/examples/simple-battle/assets/spritesheets/orc.png +0 -0
  208. package/examples/simple-battle/assets/spritesheets/potion-atlas.json +68 -0
  209. package/examples/simple-battle/assets/spritesheets/potion.png +0 -0
  210. package/examples/simple-battle/dist/game.js +2 -0
  211. package/examples/simple-battle/dist/game.js.LICENSE.txt +35 -0
  212. package/examples/simple-battle/hud/damage-text.ts +46 -0
  213. package/examples/simple-battle/hud/heal-text.ts +46 -0
  214. package/examples/simple-battle/hud/hp-bar.ts +38 -0
  215. package/examples/simple-battle/index.html +24 -0
  216. package/examples/simple-battle/index.ts +41 -0
  217. package/examples/simple-battle/objects/character.ts +95 -0
  218. package/examples/simple-battle/objects/hero.ts +111 -0
  219. package/examples/simple-battle/objects/orc.ts +107 -0
  220. package/examples/simple-battle/objects/potion.ts +27 -0
  221. package/examples/simple-battle/stage.ts +174 -0
  222. package/examples/spine-test/assets/spine/spineboy.atlas +95 -0
  223. package/examples/spine-test/assets/spine/spineboy.png +0 -0
  224. package/examples/spine-test/assets/spine/spineboy.skel +0 -0
  225. package/examples/spine-test/dist/game.js +2 -0
  226. package/examples/spine-test/dist/game.js.LICENSE.txt +35 -0
  227. package/examples/spine-test/index.html +24 -0
  228. package/examples/spine-test/index.ts +29 -0
  229. package/examples/sprite-test/assets/bird.png +0 -0
  230. package/examples/sprite-test/assets/fire.png +0 -0
  231. package/examples/sprite-test/dist/game.js +2 -0
  232. package/examples/sprite-test/dist/game.js.LICENSE.txt +35 -0
  233. package/examples/sprite-test/index.html +24 -0
  234. package/examples/sprite-test/index.ts +38 -0
  235. package/examples/tsconfig.json +2 -1
  236. package/examples/webpack.config.js +17 -3
  237. package/jest.config.ts +10 -0
  238. package/lib/asset/audio.js +47 -11
  239. package/lib/asset/audio.js.map +1 -1
  240. package/lib/asset/loaders/audio.js +7 -4
  241. package/lib/asset/loaders/audio.js.map +1 -1
  242. package/lib/asset/loaders/binary.js +7 -4
  243. package/lib/asset/loaders/binary.js.map +1 -1
  244. package/lib/asset/loaders/bitmap-font.js +74 -0
  245. package/lib/asset/loaders/bitmap-font.js.map +1 -0
  246. package/lib/asset/loaders/font.js +4 -1
  247. package/lib/asset/loaders/font.js.map +1 -1
  248. package/lib/asset/loaders/loader.js +17 -12
  249. package/lib/asset/loaders/loader.js.map +1 -1
  250. package/lib/asset/loaders/spritesheet.js +18 -8
  251. package/lib/asset/loaders/spritesheet.js.map +1 -1
  252. package/lib/asset/loaders/text.js +6 -3
  253. package/lib/asset/loaders/text.js.map +1 -1
  254. package/lib/asset/loaders/texture.js +22 -26
  255. package/lib/asset/loaders/texture.js.map +1 -1
  256. package/lib/asset/preload.js +60 -56
  257. package/lib/asset/preload.js.map +1 -1
  258. package/lib/collision/check-collision.js +804 -0
  259. package/lib/collision/check-collision.js.map +1 -0
  260. package/lib/collision/check-collision.test.js +300 -0
  261. package/lib/collision/check-collision.test.js.map +1 -0
  262. package/lib/collision/colliders.js +8 -0
  263. package/lib/collision/colliders.js.map +1 -0
  264. package/lib/debug.js.map +1 -0
  265. package/lib/dom/dom-animated-sprite.js +106 -0
  266. package/lib/dom/dom-animated-sprite.js.map +1 -0
  267. package/lib/dom/dom-game-object.js +108 -0
  268. package/lib/dom/dom-game-object.js.map +1 -0
  269. package/lib/dom/dom-particle.js +105 -0
  270. package/lib/dom/dom-particle.js.map +1 -0
  271. package/lib/dom/dom-preload.js +43 -0
  272. package/lib/dom/dom-preload.js.map +1 -0
  273. package/lib/dom/dom-sprite.js +40 -0
  274. package/lib/dom/dom-sprite.js.map +1 -0
  275. package/lib/dom/dom-texture-loader.js +36 -0
  276. package/lib/dom/dom-texture-loader.js.map +1 -0
  277. package/lib/dom/dom-utils.js +20 -0
  278. package/lib/dom/dom-utils.js.map +1 -0
  279. package/lib/index copy.js +16 -0
  280. package/lib/index copy.js.map +1 -0
  281. package/lib/index.js +36 -10
  282. package/lib/index.js.map +1 -1
  283. package/lib/input/joystick.js +262 -0
  284. package/lib/input/joystick.js.map +1 -0
  285. package/lib/node/core/dirty-number.js +19 -0
  286. package/lib/node/core/dirty-number.js.map +1 -0
  287. package/lib/node/core/game-node.js +63 -0
  288. package/lib/node/core/game-node.js.map +1 -0
  289. package/lib/node/core/game-object.js +8 -0
  290. package/lib/node/core/game-object.js.map +1 -0
  291. package/lib/node/core/renderable.js +59 -0
  292. package/lib/node/core/renderable.js.map +1 -0
  293. package/lib/node/core/transform.js +70 -0
  294. package/lib/node/core/transform.js.map +1 -0
  295. package/lib/node/core/transformable.js +85 -0
  296. package/lib/node/core/transformable.js.map +1 -0
  297. package/lib/node/ext/animated-sprite.js +77 -0
  298. package/lib/node/ext/animated-sprite.js.map +1 -0
  299. package/lib/node/ext/bitmap-text.js +93 -0
  300. package/lib/node/ext/bitmap-text.js.map +1 -0
  301. package/lib/node/ext/circle.js +43 -0
  302. package/lib/node/ext/circle.js.map +1 -0
  303. package/lib/node/ext/deplay.js +22 -0
  304. package/lib/node/ext/deplay.js.map +1 -0
  305. package/lib/node/ext/dom-container.js +51 -0
  306. package/lib/node/ext/dom-container.js.map +1 -0
  307. package/lib/node/ext/interval.js +22 -0
  308. package/lib/node/ext/interval.js.map +1 -0
  309. package/lib/node/ext/particle.js +98 -0
  310. package/lib/node/ext/particle.js.map +1 -0
  311. package/lib/node/ext/rectangle.js +52 -0
  312. package/lib/node/ext/rectangle.js.map +1 -0
  313. package/lib/node/ext/spine.js +272 -0
  314. package/lib/node/ext/spine.js.map +1 -0
  315. package/lib/node/ext/sprite.js +42 -0
  316. package/lib/node/ext/sprite.js.map +1 -0
  317. package/lib/node/physics/physics-object.js +92 -0
  318. package/lib/node/physics/physics-object.js.map +1 -0
  319. package/lib/node/physics/physics-world.js +29 -0
  320. package/lib/node/physics/physics-world.js.map +1 -0
  321. package/lib/node/physics/rigidbodies.js +7 -0
  322. package/lib/node/physics/rigidbodies.js.map +1 -0
  323. package/lib/renderer/camera.js +19 -0
  324. package/lib/renderer/camera.js.map +1 -0
  325. package/lib/renderer/container-manager.js +29 -0
  326. package/lib/renderer/container-manager.js.map +1 -0
  327. package/lib/renderer/fps-display.js +18 -0
  328. package/lib/renderer/fps-display.js.map +1 -0
  329. package/lib/renderer/layer.js +12 -0
  330. package/lib/renderer/layer.js.map +1 -0
  331. package/lib/renderer/renderer.js +146 -0
  332. package/lib/renderer/renderer.js.map +1 -0
  333. package/lib/renderer/ticker.js +56 -0
  334. package/lib/renderer/ticker.js.map +1 -0
  335. package/lib/renderer/ticker.test.js +241 -0
  336. package/lib/renderer/ticker.test.js.map +1 -0
  337. package/lib/types/animation-atlas.js +2 -0
  338. package/lib/types/animation-atlas.js.map +1 -0
  339. package/lib/types/asset/audio.d.ts +5 -4
  340. package/lib/types/asset/audio.d.ts.map +1 -1
  341. package/lib/types/asset/loaders/audio.d.ts +2 -1
  342. package/lib/types/asset/loaders/audio.d.ts.map +1 -1
  343. package/lib/types/asset/loaders/binary.d.ts +2 -1
  344. package/lib/types/asset/loaders/binary.d.ts.map +1 -1
  345. package/lib/types/asset/loaders/bitmap-font.d.ts +17 -0
  346. package/lib/types/asset/loaders/bitmap-font.d.ts.map +1 -0
  347. package/lib/types/asset/loaders/font.d.ts +2 -1
  348. package/lib/types/asset/loaders/font.d.ts.map +1 -1
  349. package/lib/types/asset/loaders/loader.d.ts +6 -6
  350. package/lib/types/asset/loaders/loader.d.ts.map +1 -1
  351. package/lib/types/asset/loaders/spritesheet.d.ts +14 -6
  352. package/lib/types/asset/loaders/spritesheet.d.ts.map +1 -1
  353. package/lib/types/asset/loaders/text.d.ts +2 -1
  354. package/lib/types/asset/loaders/text.d.ts.map +1 -1
  355. package/lib/types/asset/loaders/texture.d.ts +2 -2
  356. package/lib/types/asset/loaders/texture.d.ts.map +1 -1
  357. package/lib/types/asset/preload.d.ts +7 -5
  358. package/lib/types/asset/preload.d.ts.map +1 -1
  359. package/lib/types/atlas copy.js +2 -0
  360. package/lib/types/atlas copy.js.map +1 -0
  361. package/lib/types/atlas.js +2 -0
  362. package/lib/types/atlas.js.map +1 -0
  363. package/lib/types/bitmap-font.js +2 -0
  364. package/lib/types/bitmap-font.js.map +1 -0
  365. package/lib/types/collision/check-collision.d.ts +4 -0
  366. package/lib/types/collision/check-collision.d.ts.map +1 -0
  367. package/lib/types/collision/check-collision.test.d.ts +2 -0
  368. package/lib/types/collision/check-collision.test.d.ts.map +1 -0
  369. package/lib/types/collision/colliders.d.ts +34 -0
  370. package/lib/types/collision/colliders.d.ts.map +1 -0
  371. package/lib/types/debug.d.ts.map +1 -0
  372. package/lib/types/dom/dom-animated-sprite.d.ts +23 -0
  373. package/lib/types/dom/dom-animated-sprite.d.ts.map +1 -0
  374. package/lib/types/dom/dom-game-object.d.ts +44 -0
  375. package/lib/types/dom/dom-game-object.d.ts.map +1 -0
  376. package/lib/types/dom/dom-particle.d.ts +30 -0
  377. package/lib/types/dom/dom-particle.d.ts.map +1 -0
  378. package/lib/types/dom/dom-preload.d.ts +2 -0
  379. package/lib/types/dom/dom-preload.d.ts.map +1 -0
  380. package/lib/types/dom/dom-sprite.d.ts +13 -0
  381. package/lib/types/dom/dom-sprite.d.ts.map +1 -0
  382. package/lib/types/dom/dom-texture-loader.d.ts +8 -0
  383. package/lib/types/dom/dom-texture-loader.d.ts.map +1 -0
  384. package/lib/types/dom/dom-utils.d.ts +3 -0
  385. package/lib/types/dom/dom-utils.d.ts.map +1 -0
  386. package/lib/types/index copy.d.ts +16 -0
  387. package/lib/types/index copy.d.ts.map +1 -0
  388. package/lib/types/index.d.ts +26 -11
  389. package/lib/types/index.d.ts.map +1 -1
  390. package/lib/types/input/joystick.d.ts +28 -0
  391. package/lib/types/input/joystick.d.ts.map +1 -0
  392. package/lib/types/node/core/dirty-number.d.ts +9 -0
  393. package/lib/types/node/core/dirty-number.d.ts.map +1 -0
  394. package/lib/types/node/core/game-node.d.ts +16 -0
  395. package/lib/types/node/core/game-node.d.ts.map +1 -0
  396. package/lib/types/node/core/game-object.d.ts +8 -0
  397. package/lib/types/node/core/game-object.d.ts.map +1 -0
  398. package/lib/types/node/core/renderable.d.ts +23 -0
  399. package/lib/types/node/core/renderable.d.ts.map +1 -0
  400. package/lib/types/node/core/transform.d.ts +27 -0
  401. package/lib/types/node/core/transform.d.ts.map +1 -0
  402. package/lib/types/node/core/transformable.d.ts +44 -0
  403. package/lib/types/node/core/transformable.d.ts.map +1 -0
  404. package/lib/types/node/ext/animated-sprite.d.ts +22 -0
  405. package/lib/types/node/ext/animated-sprite.d.ts.map +1 -0
  406. package/lib/types/node/ext/bitmap-text.d.ts +14 -0
  407. package/lib/types/node/ext/bitmap-text.d.ts.map +1 -0
  408. package/lib/types/node/ext/circle.d.ts +19 -0
  409. package/lib/types/node/ext/circle.d.ts.map +1 -0
  410. package/lib/types/node/ext/deplay.d.ts +8 -0
  411. package/lib/types/node/ext/deplay.d.ts.map +1 -0
  412. package/lib/types/node/ext/dom-container.d.ts +12 -0
  413. package/lib/types/node/ext/dom-container.d.ts.map +1 -0
  414. package/lib/types/node/ext/interval.d.ts +9 -0
  415. package/lib/types/node/ext/interval.d.ts.map +1 -0
  416. package/lib/types/node/ext/particle.d.ts +30 -0
  417. package/lib/types/node/ext/particle.d.ts.map +1 -0
  418. package/lib/types/node/ext/rectangle.d.ts +22 -0
  419. package/lib/types/node/ext/rectangle.d.ts.map +1 -0
  420. package/lib/types/node/ext/spine.d.ts +36 -0
  421. package/lib/types/node/ext/spine.d.ts.map +1 -0
  422. package/lib/types/node/ext/sprite.d.ts +13 -0
  423. package/lib/types/node/ext/sprite.d.ts.map +1 -0
  424. package/lib/types/node/physics/physics-object.d.ts +38 -0
  425. package/lib/types/node/physics/physics-object.d.ts.map +1 -0
  426. package/lib/types/node/physics/physics-world.d.ts +18 -0
  427. package/lib/types/node/physics/physics-world.d.ts.map +1 -0
  428. package/lib/types/node/physics/rigidbodies.d.ts +23 -0
  429. package/lib/types/node/physics/rigidbodies.d.ts.map +1 -0
  430. package/lib/types/renderer/camera.d.ts +13 -0
  431. package/lib/types/renderer/camera.d.ts.map +1 -0
  432. package/lib/types/renderer/container-manager.d.ts +9 -0
  433. package/lib/types/renderer/container-manager.d.ts.map +1 -0
  434. package/lib/types/renderer/fps-display.d.ts +7 -0
  435. package/lib/types/renderer/fps-display.d.ts.map +1 -0
  436. package/lib/types/renderer/layer.d.ts +7 -0
  437. package/lib/types/renderer/layer.d.ts.map +1 -0
  438. package/lib/types/renderer/renderer.d.ts +40 -0
  439. package/lib/types/renderer/renderer.d.ts.map +1 -0
  440. package/lib/types/renderer/ticker.d.ts +6 -0
  441. package/lib/types/renderer/ticker.d.ts.map +1 -0
  442. package/lib/types/renderer/ticker.test.d.ts +40 -0
  443. package/lib/types/renderer/ticker.test.d.ts.map +1 -0
  444. package/lib/types/sprite-atlas.js +2 -0
  445. package/lib/types/sprite-atlas.js.map +1 -0
  446. package/lib/types/types/animation-atlas.d.ts +14 -0
  447. package/lib/types/types/animation-atlas.d.ts.map +1 -0
  448. package/lib/types/types/atlas copy.d.ts +12 -0
  449. package/lib/types/types/atlas copy.d.ts.map +1 -0
  450. package/lib/types/types/atlas.d.ts +16 -0
  451. package/lib/types/types/atlas.d.ts.map +1 -0
  452. package/lib/types/types/bitmap-font.d.ts +18 -0
  453. package/lib/types/types/bitmap-font.d.ts.map +1 -0
  454. package/lib/types/types/sprite-atlas.d.ts +13 -0
  455. package/lib/types/types/sprite-atlas.d.ts.map +1 -0
  456. package/lib/types/utils/device.d.ts +2 -0
  457. package/lib/types/utils/device.d.ts.map +1 -0
  458. package/lib/utils/device.js +2 -0
  459. package/lib/utils/device.js.map +1 -0
  460. package/package.json +8 -7
  461. package/src/asset/audio.ts +134 -90
  462. package/src/asset/loaders/audio.ts +23 -20
  463. package/src/asset/loaders/binary.ts +20 -16
  464. package/src/asset/loaders/bitmap-font.ts +91 -0
  465. package/src/asset/loaders/font.ts +18 -14
  466. package/src/asset/loaders/loader.ts +27 -23
  467. package/src/asset/loaders/spritesheet.ts +47 -36
  468. package/src/asset/loaders/text.ts +19 -15
  469. package/src/asset/loaders/texture.ts +30 -37
  470. package/src/asset/preload.ts +71 -64
  471. package/src/collision/check-collision.test.ts +349 -0
  472. package/src/collision/check-collision.ts +821 -0
  473. package/src/collision/colliders.ts +19 -0
  474. package/src/debug.ts +5 -0
  475. package/src/dom/dom-animated-sprite.ts +132 -0
  476. package/src/dom/dom-game-object.ts +134 -0
  477. package/src/dom/dom-particle.ts +151 -0
  478. package/src/dom/dom-preload.ts +54 -0
  479. package/src/dom/dom-sprite.ts +50 -0
  480. package/src/dom/dom-texture-loader.ts +44 -0
  481. package/src/dom/dom-utils.ts +19 -0
  482. package/src/index.ts +47 -13
  483. package/src/input/joystick.ts +316 -0
  484. package/src/node/core/dirty-number.ts +21 -0
  485. package/src/node/core/game-node.ts +74 -0
  486. package/src/node/core/game-object.ts +11 -0
  487. package/src/node/core/renderable.ts +72 -0
  488. package/src/node/core/transform.ts +82 -0
  489. package/src/node/core/transformable.ts +111 -0
  490. package/src/node/ext/animated-sprite.ts +103 -0
  491. package/src/node/ext/bitmap-text.ts +113 -0
  492. package/src/node/ext/circle.ts +55 -0
  493. package/src/node/ext/deplay.ts +25 -0
  494. package/src/node/ext/dom-container.ts +62 -0
  495. package/src/node/ext/interval.ts +25 -0
  496. package/src/node/ext/particle.ts +142 -0
  497. package/src/node/ext/rectangle.ts +71 -0
  498. package/src/node/ext/spine.ts +323 -0
  499. package/src/node/ext/sprite.ts +53 -0
  500. package/src/node/physics/physics-object.ts +127 -0
  501. package/src/node/physics/physics-world.ts +41 -0
  502. package/src/node/physics/rigidbodies.ts +14 -0
  503. package/src/renderer/camera.ts +25 -0
  504. package/src/renderer/container-manager.ts +36 -0
  505. package/src/renderer/fps-display.ts +21 -0
  506. package/src/renderer/layer.ts +15 -0
  507. package/src/renderer/renderer.ts +181 -0
  508. package/src/renderer/ticker.test.ts +325 -0
  509. package/src/renderer/ticker.ts +54 -0
  510. package/src/types/atlas.ts +17 -0
  511. package/src/types/bitmap-font.ts +19 -0
  512. package/src/utils/device.ts +1 -0
  513. package/examples/test-dom/index.ts +0 -21
  514. package/lib/game-object/game-object-physics.js +0 -188
  515. package/lib/game-object/game-object-physics.js.map +0 -1
  516. package/lib/game-object/game-object-rendering.js +0 -35
  517. package/lib/game-object/game-object-rendering.js.map +0 -1
  518. package/lib/game-object/game-object.js +0 -162
  519. package/lib/game-object/game-object.js.map +0 -1
  520. package/lib/game-object/transform.js +0 -118
  521. package/lib/game-object/transform.js.map +0 -1
  522. package/lib/game-object-ext/animated-sprite.js +0 -117
  523. package/lib/game-object-ext/animated-sprite.js.map +0 -1
  524. package/lib/game-object-ext/dom-container.js +0 -56
  525. package/lib/game-object-ext/dom-container.js.map +0 -1
  526. package/lib/game-object-ext/rect.js +0 -30
  527. package/lib/game-object-ext/rect.js.map +0 -1
  528. package/lib/game-object-ext/spine.js +0 -206
  529. package/lib/game-object-ext/spine.js.map +0 -1
  530. package/lib/game-object-ext/sprite.js +0 -46
  531. package/lib/game-object-ext/sprite.js.map +0 -1
  532. package/lib/game-object-ext/text.js +0 -68
  533. package/lib/game-object-ext/text.js.map +0 -1
  534. package/lib/game-object-ext/tiling-sprite.js +0 -64
  535. package/lib/game-object-ext/tiling-sprite.js.map +0 -1
  536. package/lib/types/game-object/game-object-physics.d.ts +0 -42
  537. package/lib/types/game-object/game-object-physics.d.ts.map +0 -1
  538. package/lib/types/game-object/game-object-rendering.d.ts +0 -15
  539. package/lib/types/game-object/game-object-rendering.d.ts.map +0 -1
  540. package/lib/types/game-object/game-object.d.ts +0 -81
  541. package/lib/types/game-object/game-object.d.ts.map +0 -1
  542. package/lib/types/game-object/transform.d.ts +0 -43
  543. package/lib/types/game-object/transform.d.ts.map +0 -1
  544. package/lib/types/game-object-ext/animated-sprite.d.ts +0 -29
  545. package/lib/types/game-object-ext/animated-sprite.d.ts.map +0 -1
  546. package/lib/types/game-object-ext/dom-container.d.ts +0 -16
  547. package/lib/types/game-object-ext/dom-container.d.ts.map +0 -1
  548. package/lib/types/game-object-ext/rect.d.ts +0 -17
  549. package/lib/types/game-object-ext/rect.d.ts.map +0 -1
  550. package/lib/types/game-object-ext/spine.d.ts +0 -35
  551. package/lib/types/game-object-ext/spine.d.ts.map +0 -1
  552. package/lib/types/game-object-ext/sprite.d.ts +0 -14
  553. package/lib/types/game-object-ext/sprite.d.ts.map +0 -1
  554. package/lib/types/game-object-ext/text.d.ts +0 -26
  555. package/lib/types/game-object-ext/text.d.ts.map +0 -1
  556. package/lib/types/game-object-ext/tiling-sprite.d.ts +0 -20
  557. package/lib/types/game-object-ext/tiling-sprite.d.ts.map +0 -1
  558. package/lib/types/utils/debug.d.ts.map +0 -1
  559. package/lib/types/utils/go.d.ts +0 -26
  560. package/lib/types/utils/go.d.ts.map +0 -1
  561. package/lib/types/world/world-debug.d.ts +0 -11
  562. package/lib/types/world/world-debug.d.ts.map +0 -1
  563. package/lib/types/world/world-physics.d.ts +0 -16
  564. package/lib/types/world/world-physics.d.ts.map +0 -1
  565. package/lib/types/world/world-rendering.d.ts +0 -28
  566. package/lib/types/world/world-rendering.d.ts.map +0 -1
  567. package/lib/types/world/world.d.ts +0 -38
  568. package/lib/types/world/world.d.ts.map +0 -1
  569. package/lib/utils/debug.js.map +0 -1
  570. package/lib/utils/go.js +0 -33
  571. package/lib/utils/go.js.map +0 -1
  572. package/lib/world/world-debug.js +0 -89
  573. package/lib/world/world-debug.js.map +0 -1
  574. package/lib/world/world-physics.js +0 -45
  575. package/lib/world/world-physics.js.map +0 -1
  576. package/lib/world/world-rendering.js +0 -123
  577. package/lib/world/world-rendering.js.map +0 -1
  578. package/lib/world/world.js +0 -147
  579. package/lib/world/world.js.map +0 -1
  580. package/src/game-object/game-object-physics.ts +0 -191
  581. package/src/game-object/game-object-rendering.ts +0 -27
  582. package/src/game-object/game-object.ts +0 -190
  583. package/src/game-object/transform.ts +0 -164
  584. package/src/game-object-ext/animated-sprite.ts +0 -140
  585. package/src/game-object-ext/dom-container.ts +0 -67
  586. package/src/game-object-ext/rect.ts +0 -40
  587. package/src/game-object-ext/spine.ts +0 -235
  588. package/src/game-object-ext/sprite.ts +0 -55
  589. package/src/game-object-ext/text.ts +0 -83
  590. package/src/game-object-ext/tiling-sprite.ts +0 -73
  591. package/src/utils/debug.ts +0 -5
  592. package/src/utils/go.ts +0 -53
  593. package/src/world/world-debug.ts +0 -114
  594. package/src/world/world-physics.ts +0 -52
  595. package/src/world/world-rendering.ts +0 -145
  596. package/src/world/world.ts +0 -171
  597. /package/examples/{test-dom → auto-battle}/index.html +0 -0
  598. /package/lib/{utils/debug.js → debug.js} +0 -0
  599. /package/lib/types/{utils/debug.d.ts → debug.d.ts} +0 -0
@@ -0,0 +1,35 @@
1
+ /*!
2
+ * matter-js 0.20.0 by @liabru
3
+ * http://brm.io/matter-js/
4
+ * License MIT
5
+ *
6
+ * The MIT License (MIT)
7
+ *
8
+ * Copyright (c) Liam Brummitt and contributors.
9
+ *
10
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ * of this software and associated documentation files (the "Software"), to deal
12
+ * in the Software without restriction, including without limitation the rights
13
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ * copies of the Software, and to permit persons to whom the Software is
15
+ * furnished to do so, subject to the following conditions:
16
+ *
17
+ * The above copyright notice and this permission notice shall be included in
18
+ * all copies or substantial portions of the Software.
19
+ *
20
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
+ * THE SOFTWARE.
27
+ */
28
+
29
+ /**
30
+ * tiny-lru
31
+ *
32
+ * @copyright 2025 Jason Mulligan <jason.mulligan@avoidwork.com>
33
+ * @license BSD-3-Clause
34
+ * @version 11.4.5
35
+ */
@@ -0,0 +1,24 @@
1
+ <!doctype html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width,initial-scale=1">
7
+ <style>
8
+ html,
9
+ body {
10
+ width: 100%;
11
+ height: 100%;
12
+ margin: 0;
13
+ padding: 0;
14
+ overflow: hidden;
15
+ background-color: #000;
16
+ }
17
+ </style>
18
+ </head>
19
+
20
+ <body>
21
+ <script src="dist/game.js"></script>
22
+ </body>
23
+
24
+ </html>
@@ -0,0 +1,38 @@
1
+ import { AnimatedSpriteNode, enableDebug, preload, Renderer, SpriteNode } from '../../src'
2
+
3
+ enableDebug()
4
+
5
+ const renderer = new Renderer(document.body, {
6
+ logicalWidth: 800,
7
+ logicalHeight: 600,
8
+ backgroundColor: '#304C79'
9
+ })
10
+
11
+ await preload(['assets/bird.png'])
12
+
13
+ for (let i = 0; i < 100; i++) {
14
+ const sprite = new SpriteNode({
15
+ src: 'assets/bird.png',
16
+ x: Math.random() * renderer.canvasWidth - renderer.canvasWidth / 2,
17
+ y: Math.random() * renderer.canvasHeight - renderer.canvasHeight / 2
18
+ })
19
+ renderer.add(sprite)
20
+ }
21
+
22
+ const animatedSprite = new AnimatedSpriteNode({
23
+ src: 'assets/fire.png',
24
+ atlas: {
25
+ frames: {
26
+ fire1: { x: 0, y: 0, w: 64, h: 64 },
27
+ fire2: { x: 64, y: 0, w: 64, h: 64 },
28
+ fire3: { x: 128, y: 0, w: 64, h: 64 },
29
+ fire4: { x: 192, y: 0, w: 64, h: 64 },
30
+ fire5: { x: 256, y: 0, w: 64, h: 64 },
31
+ },
32
+ animations: {
33
+ fire: { frames: ['fire1', 'fire2', 'fire3', 'fire4', 'fire5'], fps: 12, loop: true },
34
+ },
35
+ },
36
+ animation: 'fire',
37
+ })
38
+ renderer.add(animatedSprite)
@@ -17,6 +17,7 @@
17
17
  "composite": false,
18
18
  "moduleResolution": "node",
19
19
  "skipLibCheck": true,
20
- "strict": true
20
+ "strict": true,
21
+ "resolveJsonModule": true
21
22
  }
22
23
  }
@@ -1,8 +1,22 @@
1
- const path = require('path');
1
+ const path = require('path')
2
2
 
3
3
  module.exports = {
4
4
  entry: {
5
- 'test-dom': './test-dom/index.ts',
5
+
6
+ 'renderer-test': './renderer-test/index.ts',
7
+ 'dom-test': './dom-test/index.ts',
8
+ 'sprite-test': './sprite-test/index.ts',
9
+ 'collision-test': './collision-test/index.ts',
10
+ 'spine-test': './spine-test/index.ts',
11
+ 'particle-test': './particle-test/index.ts',
12
+ 'dom-sprite-test': './dom-sprite-test/index.ts',
13
+ 'dom-particle-test': './dom-particle-test/index.ts',
14
+
15
+ 'simple-battle': './simple-battle/index.ts',
16
+ 'auto-battle': './auto-battle/index.ts',
17
+ 'battle-benchmark-matterjs': './battle-benchmark-matterjs/index.ts',
18
+ 'battle-benchmark-separation': './battle-benchmark-separation/index.ts',
19
+ 'battle-benchmark-separation2': './battle-benchmark-separation2/index.ts',
6
20
  },
7
21
  output: {
8
22
  filename: '[name]/dist/game.js',
@@ -28,4 +42,4 @@ module.exports = {
28
42
  },
29
43
  open: true
30
44
  }
31
- };
45
+ }
package/jest.config.ts ADDED
@@ -0,0 +1,10 @@
1
+ /** @type {import('jest').Config} */
2
+ module.exports = {
3
+ testEnvironment: 'jsdom',
4
+ transform: {
5
+ '^.+\\.(ts|tsx)$': 'ts-jest',
6
+ },
7
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
8
+ testPathIgnorePatterns: ['/node_modules/', '/lib/'],
9
+ testMatch: ['**/src/**/*.test.ts', '**/__tests__/**/*.spec.ts'],
10
+ };
@@ -1,5 +1,6 @@
1
+ import { isMobile } from '../utils/device';
1
2
  import { audioLoader } from './loaders/audio';
2
- const audioContext = new (window.AudioContext || window.webkitAudioContext)();
3
+ export const audioContext = new (window.AudioContext || window.webkitAudioContext)();
3
4
  window.addEventListener('mousedown', () => audioContext.resume());
4
5
  window.addEventListener('touchend', () => audioContext.resume());
5
6
  async function getAvailableContext() {
@@ -7,9 +8,39 @@ async function getAvailableContext() {
7
8
  await audioContext.resume();
8
9
  return audioContext;
9
10
  }
10
- const isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);
11
11
  let isPageVisible = !document.hidden;
12
12
  window.addEventListener('visibilitychange', () => isPageVisible = !document.hidden);
13
+ function createSafeStorage() {
14
+ const memory = (() => {
15
+ const m = new Map();
16
+ const api = {
17
+ persistent: false,
18
+ getItem: (k) => (m.has(k) ? m.get(k) : null),
19
+ setItem: (k, v) => { m.set(k, String(v)); },
20
+ removeItem: (k) => { m.delete(k); },
21
+ };
22
+ return api;
23
+ })();
24
+ if (typeof window === 'undefined')
25
+ return memory;
26
+ try {
27
+ const ls = window.localStorage;
28
+ const probeKey = '__safe_ls_probe__' + Math.random().toString(36).slice(2);
29
+ ls.setItem(probeKey, '1');
30
+ ls.removeItem(probeKey);
31
+ const safe = {
32
+ persistent: true,
33
+ getItem: (k) => ls.getItem(k),
34
+ setItem: (k, v) => ls.setItem(k, v),
35
+ removeItem: (k) => ls.removeItem(k),
36
+ };
37
+ return safe;
38
+ }
39
+ catch {
40
+ return memory;
41
+ }
42
+ }
43
+ const safeStorage = createSafeStorage();
13
44
  class Audio {
14
45
  src;
15
46
  #volume;
@@ -39,10 +70,13 @@ class Audio {
39
70
  if (isMobile && !isPageVisible)
40
71
  return;
41
72
  if (!this.#audioBuffer) {
42
- if (!audioLoader.checkLoaded(this.src)) {
73
+ if (audioLoader.checkCached(this.src)) {
74
+ this.#audioBuffer = audioLoader.getCached(this.src);
75
+ }
76
+ else {
43
77
  console.info(`Audio not preloaded. Loading now: ${this.src}`);
78
+ this.#audioBuffer = await audioLoader.load(this.src);
44
79
  }
45
- this.#audioBuffer = await audioLoader.load(this.src);
46
80
  }
47
81
  if (!this.#audioBuffer)
48
82
  return;
@@ -99,7 +133,7 @@ class MusicPlayer {
99
133
  #volume = 0.7;
100
134
  #currentAudio;
101
135
  constructor() {
102
- const stored = parseFloat(localStorage.getItem('musicVolume') || '');
136
+ const stored = parseFloat(safeStorage.getItem('musicVolume') || '');
103
137
  this.#volume = Number.isNaN(stored) ? this.#volume : stored;
104
138
  if (isMobile) {
105
139
  document.addEventListener('visibilitychange', () => {
@@ -117,7 +151,7 @@ class MusicPlayer {
117
151
  }
118
152
  set volume(volume) {
119
153
  this.#volume = volume;
120
- localStorage.setItem('musicVolume', volume.toString());
154
+ safeStorage.setItem('musicVolume', volume.toString());
121
155
  if (this.#currentAudio)
122
156
  this.#currentAudio.volume = volume;
123
157
  }
@@ -138,7 +172,7 @@ class MusicPlayer {
138
172
  class SfxPlayer {
139
173
  #volume = 1;
140
174
  constructor() {
141
- const stored = parseFloat(localStorage.getItem('sfxVolume') || '');
175
+ const stored = parseFloat(safeStorage.getItem('sfxVolume') || '');
142
176
  this.#volume = Number.isNaN(stored) ? this.#volume : stored;
143
177
  }
144
178
  get volume() {
@@ -146,13 +180,15 @@ class SfxPlayer {
146
180
  }
147
181
  set volume(volume) {
148
182
  this.#volume = volume;
149
- localStorage.setItem('sfxVolume', volume.toString());
183
+ safeStorage.setItem('sfxVolume', volume.toString());
150
184
  }
151
185
  play(src) {
152
186
  new Audio(src, this.#volume, false);
153
187
  }
188
+ playRandom(...srcs) {
189
+ this.play(srcs[Math.floor(Math.random() * srcs.length)]);
190
+ }
154
191
  }
155
- const musicPlayer = new MusicPlayer();
156
- const sfxPlayer = new SfxPlayer();
157
- export { audioContext, musicPlayer, sfxPlayer };
192
+ export const musicPlayer = new MusicPlayer();
193
+ export const sfxPlayer = new SfxPlayer();
158
194
  //# sourceMappingURL=audio.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"audio.js","sourceRoot":"","sources":["../../src/asset/audio.ts"],"names":[],"mappings":"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","sourcesContent":["import { audioLoader } from './loaders/audio';\n\nconst audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();\nwindow.addEventListener('mousedown', () => audioContext.resume());\nwindow.addEventListener('touchend', () => audioContext.resume());\n\nasync function getAvailableContext(): Promise<AudioContext> {\n if (audioContext.state === 'suspended') await audioContext.resume();\n return audioContext;\n}\n\nconst isMobile = /Android|iPhone|iPad|iPod/i.test(navigator.userAgent);\nlet isPageVisible = !document.hidden;\nwindow.addEventListener('visibilitychange', () => isPageVisible = !document.hidden);\n\nclass Audio {\n src: string;\n #volume: number;\n #loop: boolean;\n\n #audioBuffer?: AudioBuffer;\n #audioContext?: AudioContext;\n #gainNode?: GainNode;\n #source?: AudioBufferSourceNode;\n\n #isPlaying = false;\n #isPaused = false;\n #startTime = 0;\n #pauseTime = 0;\n #offset = 0;\n\n constructor(src: string, volume: number, loop: boolean) {\n this.src = src;\n this.#volume = volume;\n this.#loop = loop;\n this.play();\n }\n\n get volume() { return this.#volume; }\n set volume(volume: number) {\n this.#volume = volume;\n if (this.#gainNode) this.#gainNode.gain.value = Math.max(0, Math.min(1, volume));\n }\n\n async play() {\n if (isMobile && !isPageVisible) return;\n\n if (!this.#audioBuffer) {\n if (!audioLoader.checkLoaded(this.src)) {\n console.info(`Audio not preloaded. Loading now: ${this.src}`);\n }\n this.#audioBuffer = await audioLoader.load(this.src);\n }\n if (!this.#audioBuffer) return;\n\n if (this.#isPlaying) this.stop();\n if (!this.#isPaused) this.#offset = 0;\n this.#isPlaying = true;\n this.#isPaused = false;\n if (!this.#audioContext) this.#audioContext = await getAvailableContext();\n if (!this.#isPlaying) return;\n\n if (!this.#gainNode) {\n this.#gainNode = this.#audioContext.createGain();\n this.#gainNode.gain.value = this.#volume;\n this.#gainNode.connect(this.#audioContext.destination);\n }\n\n this.#source = this.#audioContext.createBufferSource();\n this.#source.buffer = this.#audioBuffer;\n this.#source.loop = this.#loop;\n this.#source.connect(this.#gainNode);\n this.#source.start(0, this.#offset);\n this.#startTime = this.#audioContext.currentTime;\n this.#source.onended = () => { if (!this.#isPaused && !this.#loop) this.stop(); };\n }\n\n #clear(): void {\n if (this.#source) {\n this.#source.stop();\n this.#source.disconnect();\n this.#source = undefined;\n }\n }\n\n pause() {\n if (this.#isPlaying && !this.#isPaused) {\n if (this.#audioContext) {\n this.#pauseTime = this.#audioContext.currentTime;\n this.#offset += this.#pauseTime - this.#startTime;\n }\n this.#isPaused = true;\n this.#isPlaying = false;\n this.#clear();\n }\n }\n\n stop() {\n this.#isPlaying = false;\n this.#isPaused = false;\n this.#offset = 0;\n this.#clear();\n }\n}\n\nclass MusicPlayer {\n #volume = 0.7;\n #currentAudio?: Audio;\n\n constructor() {\n const stored = parseFloat(localStorage.getItem('musicVolume') || '');\n this.#volume = Number.isNaN(stored) ? this.#volume : stored;\n\n if (isMobile) {\n document.addEventListener('visibilitychange', () => {\n if (document.hidden) this.pause();\n else {\n isPageVisible = true;\n this.#currentAudio?.play();\n }\n });\n }\n }\n\n get volume() {\n return this.#volume;\n }\n\n set volume(volume: number) {\n this.#volume = volume;\n localStorage.setItem('musicVolume', volume.toString());\n if (this.#currentAudio) this.#currentAudio.volume = volume;\n }\n\n play(src: string) {\n if (this.#currentAudio?.src === src) return;\n this.#currentAudio?.stop();\n this.#currentAudio = new Audio(src, this.#volume, true);\n }\n\n pause() {\n this.#currentAudio?.pause();\n }\n\n stop() {\n this.#currentAudio?.stop();\n this.#currentAudio = undefined;\n }\n}\n\nclass SfxPlayer {\n #volume = 1;\n\n constructor() {\n const stored = parseFloat(localStorage.getItem('sfxVolume') || '');\n this.#volume = Number.isNaN(stored) ? this.#volume : stored;\n }\n\n get volume() {\n return this.#volume;\n }\n\n set volume(volume: number) {\n this.#volume = volume;\n localStorage.setItem('sfxVolume', volume.toString());\n }\n\n play(src: string) {\n new Audio(src, this.#volume, false);\n }\n}\n\nconst musicPlayer = new MusicPlayer();\nconst sfxPlayer = new SfxPlayer();\n\nexport { audioContext, musicPlayer, sfxPlayer };\n"]}
1
+ {"version":3,"file":"audio.js","sourceRoot":"","sources":["../../src/asset/audio.ts"],"names":[],"mappings":"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","sourcesContent":["import { isMobile } from '../utils/device'\nimport { audioLoader } from './loaders/audio'\n\nexport const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)()\nwindow.addEventListener('mousedown', () => audioContext.resume())\nwindow.addEventListener('touchend', () => audioContext.resume())\n\nasync function getAvailableContext(): Promise<AudioContext> {\n if (audioContext.state === 'suspended') await audioContext.resume()\n return audioContext\n}\n\nlet isPageVisible = !document.hidden\nwindow.addEventListener('visibilitychange', () => isPageVisible = !document.hidden)\n\ntype BasicStorage = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>\n\ntype SafeStorage = BasicStorage & {\n persistent: boolean\n}\n\nfunction createSafeStorage(): SafeStorage {\n const memory = (() => {\n const m = new Map<string, string>()\n const api: SafeStorage = {\n persistent: false,\n getItem: (k) => (m.has(k) ? m.get(k)! : null),\n setItem: (k, v) => { m.set(k, String(v)) },\n removeItem: (k) => { m.delete(k) },\n }\n return api\n })()\n\n if (typeof window === 'undefined') return memory\n\n try {\n const ls = window.localStorage\n const probeKey = '__safe_ls_probe__' + Math.random().toString(36).slice(2)\n ls.setItem(probeKey, '1')\n ls.removeItem(probeKey)\n\n const safe: SafeStorage = {\n persistent: true,\n getItem: (k) => ls.getItem(k),\n setItem: (k, v) => ls.setItem(k, v),\n removeItem: (k) => ls.removeItem(k),\n }\n return safe\n } catch {\n return memory\n }\n}\n\nconst safeStorage = createSafeStorage()\n\nclass Audio {\n src: string\n #volume: number\n #loop: boolean\n\n #audioBuffer?: AudioBuffer\n #audioContext?: AudioContext\n #gainNode?: GainNode\n #source?: AudioBufferSourceNode\n\n #isPlaying = false\n #isPaused = false\n #startTime = 0\n #pauseTime = 0\n #offset = 0\n\n constructor(src: string, volume: number, loop: boolean) {\n this.src = src\n this.#volume = volume\n this.#loop = loop\n this.play()\n }\n\n get volume() { return this.#volume }\n set volume(volume: number) {\n this.#volume = volume\n if (this.#gainNode) this.#gainNode.gain.value = Math.max(0, Math.min(1, volume))\n }\n\n async play() {\n if (isMobile && !isPageVisible) return\n\n if (!this.#audioBuffer) {\n if (audioLoader.checkCached(this.src)) {\n this.#audioBuffer = audioLoader.getCached(this.src)\n } else {\n console.info(`Audio not preloaded. Loading now: ${this.src}`)\n this.#audioBuffer = await audioLoader.load(this.src)\n }\n }\n if (!this.#audioBuffer) return\n\n if (this.#isPlaying) this.stop()\n if (!this.#isPaused) this.#offset = 0\n this.#isPlaying = true\n this.#isPaused = false\n if (!this.#audioContext) this.#audioContext = await getAvailableContext()\n if (!this.#isPlaying) return\n\n if (!this.#gainNode) {\n this.#gainNode = this.#audioContext.createGain()\n this.#gainNode.gain.value = this.#volume\n this.#gainNode.connect(this.#audioContext.destination)\n }\n\n this.#source = this.#audioContext.createBufferSource()\n this.#source.buffer = this.#audioBuffer\n this.#source.loop = this.#loop\n this.#source.connect(this.#gainNode)\n this.#source.start(0, this.#offset)\n this.#startTime = this.#audioContext.currentTime\n this.#source.onended = () => { if (!this.#isPaused && !this.#loop) this.stop() }\n }\n\n #clear(): void {\n if (this.#source) {\n this.#source.stop()\n this.#source.disconnect()\n this.#source = undefined\n }\n }\n\n pause() {\n if (this.#isPlaying && !this.#isPaused) {\n if (this.#audioContext) {\n this.#pauseTime = this.#audioContext.currentTime\n this.#offset += this.#pauseTime - this.#startTime\n }\n this.#isPaused = true\n this.#isPlaying = false\n this.#clear()\n }\n }\n\n stop() {\n this.#isPlaying = false\n this.#isPaused = false\n this.#offset = 0\n this.#clear()\n }\n}\n\nclass MusicPlayer {\n #volume = 0.7\n #currentAudio?: Audio\n\n constructor() {\n const stored = parseFloat(safeStorage.getItem('musicVolume') || '')\n this.#volume = Number.isNaN(stored) ? this.#volume : stored\n\n if (isMobile) {\n document.addEventListener('visibilitychange', () => {\n if (document.hidden) this.pause()\n else {\n isPageVisible = true\n this.#currentAudio?.play()\n }\n })\n }\n }\n\n get volume() {\n return this.#volume\n }\n\n set volume(volume: number) {\n this.#volume = volume\n safeStorage.setItem('musicVolume', volume.toString())\n if (this.#currentAudio) this.#currentAudio.volume = volume\n }\n\n play(src: string) {\n if (this.#currentAudio?.src === src) return\n this.#currentAudio?.stop()\n this.#currentAudio = new Audio(src, this.#volume, true)\n }\n\n pause() {\n this.#currentAudio?.pause()\n }\n\n stop() {\n this.#currentAudio?.stop()\n this.#currentAudio = undefined\n }\n}\n\nclass SfxPlayer {\n #volume = 1\n\n constructor() {\n const stored = parseFloat(safeStorage.getItem('sfxVolume') || '')\n this.#volume = Number.isNaN(stored) ? this.#volume : stored\n }\n\n get volume() {\n return this.#volume\n }\n\n set volume(volume: number) {\n this.#volume = volume\n safeStorage.setItem('sfxVolume', volume.toString())\n }\n\n play(src: string) {\n new Audio(src, this.#volume, false)\n }\n\n playRandom(...srcs: string[]) {\n this.play(srcs[Math.floor(Math.random() * srcs.length)])\n }\n}\n\nexport const musicPlayer = new MusicPlayer()\nexport const sfxPlayer = new SfxPlayer()\n"]}
@@ -1,23 +1,23 @@
1
1
  import { audioContext } from '../audio';
2
2
  import { Loader } from './loader';
3
3
  class AudioLoader extends Loader {
4
- async _load(src) {
4
+ async doLoad(src) {
5
5
  const loadingPromise = (async () => {
6
6
  const response = await fetch(src);
7
7
  if (!response.ok) {
8
8
  console.error(`Failed to load audio data: ${src}`);
9
9
  return;
10
10
  }
11
- const arrayBuffer = await response.arrayBuffer();
12
11
  try {
12
+ const arrayBuffer = await response.arrayBuffer();
13
13
  const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
14
14
  this.loadingPromises.delete(src);
15
15
  if (this.hasActiveRef(src)) {
16
- if (this.loadedAssets.has(src)) {
16
+ if (this.cachedAssets.has(src)) {
17
17
  console.error(`Audio buffer already exists: ${src}`);
18
18
  }
19
19
  else {
20
- this.loadedAssets.set(src, audioBuffer);
20
+ this.cachedAssets.set(src, audioBuffer);
21
21
  return audioBuffer;
22
22
  }
23
23
  }
@@ -30,6 +30,9 @@ class AudioLoader extends Loader {
30
30
  this.loadingPromises.set(src, loadingPromise);
31
31
  return await loadingPromise;
32
32
  }
33
+ async load(src) {
34
+ return await super.load(src);
35
+ }
33
36
  }
34
37
  export const audioLoader = new AudioLoader();
35
38
  //# sourceMappingURL=audio.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"audio.js","sourceRoot":"","sources":["../../../src/asset/loaders/audio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,WAAY,SAAQ,MAAmB;IACxB,KAAK,CAAC,KAAK,CAAC,GAAW;QACxC,MAAM,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;YACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAC;gBACnD,OAAO;YACT,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;YAEjD,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;gBAEpE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAEjC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3B,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC/B,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAC;oBACvD,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;wBACxC,OAAO,WAAW,CAAC;oBACrB,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;gBAC5D,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACnC,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAC9C,OAAO,MAAM,cAAc,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC","sourcesContent":["import { audioContext } from '../audio';\nimport { Loader } from './loader';\n\nclass AudioLoader extends Loader<AudioBuffer> {\n protected override async _load(src: string) {\n const loadingPromise = (async () => {\n const response = await fetch(src);\n if (!response.ok) {\n console.error(`Failed to load audio data: ${src}`);\n return;\n }\n\n const arrayBuffer = await response.arrayBuffer();\n\n try {\n const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n\n this.loadingPromises.delete(src);\n\n if (this.hasActiveRef(src)) {\n if (this.loadedAssets.has(src)) {\n console.error(`Audio buffer already exists: ${src}`);\n } else {\n this.loadedAssets.set(src, audioBuffer);\n return audioBuffer;\n }\n }\n } catch (error) {\n console.error(`Failed to decode audio data: ${src}`, error);\n this.loadingPromises.delete(src);\n }\n })();\n\n this.loadingPromises.set(src, loadingPromise);\n return await loadingPromise;\n }\n}\n\nexport const audioLoader = new AudioLoader();\n"]}
1
+ {"version":3,"file":"audio.js","sourceRoot":"","sources":["../../../src/asset/loaders/audio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,MAAM,WAAY,SAAQ,MAAmB;IACxB,KAAK,CAAC,MAAM,CAAC,GAAW;QACzC,MAAM,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;YACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;YACjC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAA;gBAClD,OAAM;YACR,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAA;gBAChD,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC,WAAW,CAAC,CAAA;gBAEnE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBAEhC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3B,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC/B,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAA;oBACtD,CAAC;yBAAM,CAAC;wBACN,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;wBACvC,OAAO,WAAW,CAAA;oBACpB,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,gCAAgC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAA;gBAC3D,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAClC,CAAC;QACH,CAAC,CAAC,EAAE,CAAA;QAEJ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;QAC7C,OAAO,MAAM,cAAc,CAAA;IAC7B,CAAC;IAEQ,KAAK,CAAC,IAAI,CAAC,GAAW;QAC7B,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC9B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAA","sourcesContent":["import { audioContext } from '../audio'\nimport { Loader } from './loader'\n\nclass AudioLoader extends Loader<AudioBuffer> {\n protected override async doLoad(src: string) {\n const loadingPromise = (async () => {\n const response = await fetch(src)\n if (!response.ok) {\n console.error(`Failed to load audio data: ${src}`)\n return\n }\n\n try {\n const arrayBuffer = await response.arrayBuffer()\n const audioBuffer = await audioContext.decodeAudioData(arrayBuffer)\n\n this.loadingPromises.delete(src)\n\n if (this.hasActiveRef(src)) {\n if (this.cachedAssets.has(src)) {\n console.error(`Audio buffer already exists: ${src}`)\n } else {\n this.cachedAssets.set(src, audioBuffer)\n return audioBuffer\n }\n }\n } catch (error) {\n console.error(`Failed to decode audio data: ${src}`, error)\n this.loadingPromises.delete(src)\n }\n })()\n\n this.loadingPromises.set(src, loadingPromise)\n return await loadingPromise\n }\n\n override async load(src: string) {\n return await super.load(src)\n }\n}\n\nexport const audioLoader = new AudioLoader()\n"]}
@@ -1,6 +1,6 @@
1
1
  import { Loader } from './loader';
2
2
  class BinaryLoader extends Loader {
3
- async _load(src) {
3
+ async doLoad(src) {
4
4
  const loadingPromise = (async () => {
5
5
  const response = await fetch(src);
6
6
  if (!response.ok) {
@@ -8,14 +8,14 @@ class BinaryLoader extends Loader {
8
8
  return;
9
9
  }
10
10
  const arrayBuffer = await response.arrayBuffer();
11
- const data = new Uint8Array(arrayBuffer);
12
11
  this.loadingPromises.delete(src);
13
12
  if (this.hasActiveRef(src)) {
14
- if (this.loadedAssets.has(src)) {
13
+ if (this.cachedAssets.has(src)) {
15
14
  console.error(`Binary data already exists: ${src}`);
16
15
  }
17
16
  else {
18
- this.loadedAssets.set(src, data);
17
+ const data = new Uint8Array(arrayBuffer);
18
+ this.cachedAssets.set(src, data);
19
19
  return data;
20
20
  }
21
21
  }
@@ -23,6 +23,9 @@ class BinaryLoader extends Loader {
23
23
  this.loadingPromises.set(src, loadingPromise);
24
24
  return await loadingPromise;
25
25
  }
26
+ async load(src) {
27
+ return await super.load(src);
28
+ }
26
29
  }
27
30
  export const binaryLoader = new BinaryLoader();
28
31
  //# sourceMappingURL=binary.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"binary.js","sourceRoot":"","sources":["../../../src/asset/loaders/binary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,YAAa,SAAQ,MAAkB;IACxB,KAAK,CAAC,KAAK,CAAC,GAAW;QACxC,MAAM,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;YACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;gBACpD,OAAO;YACT,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC;YACjD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;YAEzC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEjC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3B,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC/B,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;gBACtD,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;oBACjC,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAC9C,OAAO,MAAM,cAAc,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC","sourcesContent":["import { Loader } from './loader';\n\nclass BinaryLoader extends Loader<Uint8Array> {\n protected override async _load(src: string) {\n const loadingPromise = (async () => {\n const response = await fetch(src);\n if (!response.ok) {\n console.error(`Failed to load binary data: ${src}`);\n return;\n }\n\n const arrayBuffer = await response.arrayBuffer();\n const data = new Uint8Array(arrayBuffer);\n\n this.loadingPromises.delete(src);\n\n if (this.hasActiveRef(src)) {\n if (this.loadedAssets.has(src)) {\n console.error(`Binary data already exists: ${src}`);\n } else {\n this.loadedAssets.set(src, data);\n return data;\n }\n }\n })();\n\n this.loadingPromises.set(src, loadingPromise);\n return await loadingPromise;\n }\n}\n\nexport const binaryLoader = new BinaryLoader();\n"]}
1
+ {"version":3,"file":"binary.js","sourceRoot":"","sources":["../../../src/asset/loaders/binary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,MAAM,YAAa,SAAQ,MAAkB;IACxB,KAAK,CAAC,MAAM,CAAC,GAAW;QACzC,MAAM,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;YACjC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;YACjC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAA;gBACnD,OAAM;YACR,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAA;YAEhD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAEhC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC3B,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC/B,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAA;gBACrD,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAA;oBACxC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAA;oBAChC,OAAO,IAAI,CAAA;gBACb,CAAC;YACH,CAAC;QACH,CAAC,CAAC,EAAE,CAAA;QAEJ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;QAC7C,OAAO,MAAM,cAAc,CAAA;IAC7B,CAAC;IAEQ,KAAK,CAAC,IAAI,CAAC,GAAW;QAC7B,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC9B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAA","sourcesContent":["import { Loader } from './loader'\n\nclass BinaryLoader extends Loader<Uint8Array> {\n protected override async doLoad(src: string) {\n const loadingPromise = (async () => {\n const response = await fetch(src)\n if (!response.ok) {\n console.error(`Failed to load binary data: ${src}`)\n return\n }\n\n const arrayBuffer = await response.arrayBuffer()\n\n this.loadingPromises.delete(src)\n\n if (this.hasActiveRef(src)) {\n if (this.cachedAssets.has(src)) {\n console.error(`Binary data already exists: ${src}`)\n } else {\n const data = new Uint8Array(arrayBuffer)\n this.cachedAssets.set(src, data)\n return data\n }\n }\n })()\n\n this.loadingPromises.set(src, loadingPromise)\n return await loadingPromise\n }\n\n override async load(src: string) {\n return await super.load(src)\n }\n}\n\nexport const binaryLoader = new BinaryLoader()\n"]}
@@ -0,0 +1,74 @@
1
+ import { Loader } from './loader';
2
+ import { textureLoader } from './texture';
3
+ class BitmapFontLoader extends Loader {
4
+ #fntToSrc = new Map();
5
+ async doLoad(fnt, src) {
6
+ this.#fntToSrc.set(fnt, src);
7
+ const loadingPromise = (async () => {
8
+ const texture = await textureLoader.load(src);
9
+ if (!texture) {
10
+ console.error(`Failed to load texture: ${src}`);
11
+ return;
12
+ }
13
+ const response = await fetch(fnt);
14
+ if (!response.ok) {
15
+ console.error(`Failed to load font xml: ${fnt}`);
16
+ return;
17
+ }
18
+ try {
19
+ const text = await response.text();
20
+ this.loadingPromises.delete(fnt);
21
+ if (this.hasActiveRef(fnt)) {
22
+ if (this.cachedAssets.has(fnt)) {
23
+ textureLoader.release(src);
24
+ console.error(`Bitmap font already exists: ${fnt}`);
25
+ }
26
+ else {
27
+ const parser = new DOMParser();
28
+ const xmlDoc = parser.parseFromString(text, 'application/xml');
29
+ const infoEl = xmlDoc.getElementsByTagName('info')[0];
30
+ const commonEl = xmlDoc.getElementsByTagName('common')[0];
31
+ const charEls = xmlDoc.getElementsByTagName('char');
32
+ const size = parseInt(infoEl.getAttribute('size') || '16', 10);
33
+ const lineHeight = parseInt(commonEl.getAttribute('lineHeight') || '32', 10);
34
+ const chars = {};
35
+ for (let i = 0; i < charEls.length; i++) {
36
+ const charEl = charEls[i];
37
+ const id = parseInt(charEl.getAttribute('id'), 10);
38
+ const x = parseInt(charEl.getAttribute('x'), 10);
39
+ const y = parseInt(charEl.getAttribute('y'), 10);
40
+ const width = parseInt(charEl.getAttribute('width'), 10);
41
+ const height = parseInt(charEl.getAttribute('height'), 10);
42
+ const xoffset = parseInt(charEl.getAttribute('xoffset'), 10);
43
+ const yoffset = parseInt(charEl.getAttribute('yoffset'), 10);
44
+ const xadvance = parseInt(charEl.getAttribute('xadvance'), 10);
45
+ chars[id] = { x, y, width, height, xoffset, yoffset, xadvance };
46
+ }
47
+ const bitmapFont = { src, chars, texture, size, lineHeight };
48
+ this.cachedAssets.set(fnt, bitmapFont);
49
+ return bitmapFont;
50
+ }
51
+ }
52
+ else {
53
+ textureLoader.release(src);
54
+ }
55
+ }
56
+ catch (error) {
57
+ console.error(`Failed to decode font xml: ${fnt}`, error);
58
+ this.loadingPromises.delete(fnt);
59
+ }
60
+ })();
61
+ this.loadingPromises.set(fnt, loadingPromise);
62
+ return await loadingPromise;
63
+ }
64
+ cleanup(fnt) {
65
+ const src = this.#fntToSrc.get(fnt);
66
+ if (src)
67
+ textureLoader.release(src);
68
+ }
69
+ async load(fnt, src) {
70
+ return await super.load(fnt, src);
71
+ }
72
+ }
73
+ export const bitmapFontLoader = new BitmapFontLoader();
74
+ //# sourceMappingURL=bitmap-font.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitmap-font.js","sourceRoot":"","sources":["../../../src/asset/loaders/bitmap-font.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,gBAAiB,SAAQ,MAAkB;IAC/C,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAA;IAElB,KAAK,CAAC,MAAM,CAAC,GAAW,EAAE,GAAW;QACtD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QAE5B,MAAM,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;YACjC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,GAAG,EAAE,CAAC,CAAA;gBAC/C,OAAM;YACR,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;YACjC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO,CAAC,KAAK,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAA;gBAChD,OAAM;YACR,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;gBAElC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBAEhC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC3B,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC/B,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;wBAC1B,OAAO,CAAC,KAAK,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAA;oBACrD,CAAC;yBAAM,CAAC;wBAEN,MAAM,MAAM,GAAG,IAAI,SAAS,EAAE,CAAA;wBAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAA;wBAE9D,MAAM,MAAM,GAAG,MAAM,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;wBACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;wBACzD,MAAM,OAAO,GAAG,MAAM,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAA;wBAEnD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAA;wBAC9D,MAAM,UAAU,GAAG,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAA;wBAE5E,MAAM,KAAK,GAAyB,EAAE,CAAA;wBAEtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;4BACxC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;4BAEzB,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAE,EAAE,EAAE,CAAC,CAAA;4BACnD,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAE,EAAE,EAAE,CAAC,CAAA;4BACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAE,EAAE,EAAE,CAAC,CAAA;4BACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,OAAO,CAAE,EAAE,EAAE,CAAC,CAAA;4BACzD,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAE,EAAE,EAAE,CAAC,CAAA;4BAC3D,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,CAAE,EAAE,EAAE,CAAC,CAAA;4BAC7D,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,SAAS,CAAE,EAAE,EAAE,CAAC,CAAA;4BAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,UAAU,CAAE,EAAE,EAAE,CAAC,CAAA;4BAE/D,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAA;wBACjE,CAAC;wBAED,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;wBAE5D,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;wBACtC,OAAO,UAAU,CAAA;oBACnB,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;gBAC5B,CAAC;YAEH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,GAAG,EAAE,EAAE,KAAK,CAAC,CAAA;gBACzD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAClC,CAAC;QACH,CAAC,CAAC,EAAE,CAAA;QAEJ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,cAAc,CAAC,CAAA;QAC7C,OAAO,MAAM,cAAc,CAAA;IAC7B,CAAC;IAEkB,OAAO,CAAC,GAAW;QACpC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACnC,IAAI,GAAG;YAAE,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACrC,CAAC;IAEQ,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,GAAW;QAC1C,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACnC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAA","sourcesContent":["import { BitmapFont, Char } from '../../types/bitmap-font'\nimport { Loader } from './loader'\nimport { textureLoader } from './texture'\n\nclass BitmapFontLoader extends Loader<BitmapFont> {\n #fntToSrc = new Map<string, string>()\n\n protected override async doLoad(fnt: string, src: string) {\n this.#fntToSrc.set(fnt, src)\n\n const loadingPromise = (async () => {\n const texture = await textureLoader.load(src)\n if (!texture) {\n console.error(`Failed to load texture: ${src}`)\n return\n }\n\n const response = await fetch(fnt)\n if (!response.ok) {\n console.error(`Failed to load font xml: ${fnt}`)\n return\n }\n\n try {\n const text = await response.text()\n\n this.loadingPromises.delete(fnt)\n\n if (this.hasActiveRef(fnt)) {\n if (this.cachedAssets.has(fnt)) {\n textureLoader.release(src)\n console.error(`Bitmap font already exists: ${fnt}`)\n } else {\n\n const parser = new DOMParser()\n const xmlDoc = parser.parseFromString(text, 'application/xml')\n\n const infoEl = xmlDoc.getElementsByTagName('info')[0]\n const commonEl = xmlDoc.getElementsByTagName('common')[0]\n const charEls = xmlDoc.getElementsByTagName('char')\n\n const size = parseInt(infoEl.getAttribute('size') || '16', 10)\n const lineHeight = parseInt(commonEl.getAttribute('lineHeight') || '32', 10)\n\n const chars: Record<number, Char> = {}\n\n for (let i = 0; i < charEls.length; i++) {\n const charEl = charEls[i]\n\n const id = parseInt(charEl.getAttribute('id')!, 10)\n const x = parseInt(charEl.getAttribute('x')!, 10)\n const y = parseInt(charEl.getAttribute('y')!, 10)\n const width = parseInt(charEl.getAttribute('width')!, 10)\n const height = parseInt(charEl.getAttribute('height')!, 10)\n const xoffset = parseInt(charEl.getAttribute('xoffset')!, 10)\n const yoffset = parseInt(charEl.getAttribute('yoffset')!, 10)\n const xadvance = parseInt(charEl.getAttribute('xadvance')!, 10)\n\n chars[id] = { x, y, width, height, xoffset, yoffset, xadvance }\n }\n\n const bitmapFont = { src, chars, texture, size, lineHeight }\n\n this.cachedAssets.set(fnt, bitmapFont)\n return bitmapFont\n }\n } else {\n textureLoader.release(src)\n }\n\n } catch (error) {\n console.error(`Failed to decode font xml: ${fnt}`, error)\n this.loadingPromises.delete(fnt)\n }\n })()\n\n this.loadingPromises.set(fnt, loadingPromise)\n return await loadingPromise\n }\n\n protected override cleanup(fnt: string) {\n const src = this.#fntToSrc.get(fnt)\n if (src) textureLoader.release(src)\n }\n\n override async load(fnt: string, src: string) {\n return await super.load(fnt, src)\n }\n}\n\nexport const bitmapFontLoader = new BitmapFontLoader()\n"]}
@@ -1,6 +1,6 @@
1
1
  import { Loader } from './loader';
2
2
  class FontFamilyLoader extends Loader {
3
- async _load(fontName) {
3
+ async doLoad(fontName) {
4
4
  const loadingPromise = (async () => {
5
5
  if ('fonts' in document) {
6
6
  try {
@@ -22,6 +22,9 @@ class FontFamilyLoader extends Loader {
22
22
  this.loadingPromises.set(fontName, loadingPromise);
23
23
  return await loadingPromise;
24
24
  }
25
+ async load(fontName) {
26
+ return await super.load(fontName);
27
+ }
25
28
  }
26
29
  export const fontFamilyLoader = new FontFamilyLoader();
27
30
  //# sourceMappingURL=font.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"font.js","sourceRoot":"","sources":["../../../src/asset/loaders/font.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,gBAAiB,SAAQ,MAAe;IACzB,KAAK,CAAC,KAAK,CAAC,QAAgB;QAC7C,MAAM,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;YACjC,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;gBACxB,IAAI,CAAC;oBACH,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAC;oBAC7C,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;oBAC3B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACtC,OAAO,IAAI,CAAC;gBACd,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC;oBACzD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;gBACnE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACxC,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACnD,OAAO,MAAM,cAAc,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC","sourcesContent":["import { Loader } from './loader';\n\nclass FontFamilyLoader extends Loader<boolean> {\n protected override async _load(fontName: string) {\n const loadingPromise = (async () => {\n if ('fonts' in document) {\n try {\n await document.fonts.load(`1em ${fontName}`);\n await document.fonts.ready;\n this.loadingPromises.delete(fontName);\n return true;\n } catch (error) {\n console.error(`Failed to load font: ${fontName}`, error);\n this.loadingPromises.delete(fontName);\n }\n } else {\n console.warn(`This browser does not support the Font Loading API`);\n this.loadingPromises.delete(fontName);\n }\n })();\n\n this.loadingPromises.set(fontName, loadingPromise);\n return await loadingPromise;\n }\n}\n\nexport const fontFamilyLoader = new FontFamilyLoader();\n"]}
1
+ {"version":3,"file":"font.js","sourceRoot":"","sources":["../../../src/asset/loaders/font.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,MAAM,gBAAiB,SAAQ,MAAe;IACzB,KAAK,CAAC,MAAM,CAAC,QAAgB;QAC9C,MAAM,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;YACjC,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;gBACxB,IAAI,CAAC;oBACH,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,QAAQ,EAAE,CAAC,CAAA;oBAC5C,MAAM,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAA;oBAC1B,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;oBACrC,OAAO,IAAI,CAAA;gBACb,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAA;oBACxD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;gBACvC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAA;gBAClE,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YACvC,CAAC;QACH,CAAC,CAAC,EAAE,CAAA;QAEJ,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAA;QAClD,OAAO,MAAM,cAAc,CAAA;IAC7B,CAAC;IAEQ,KAAK,CAAC,IAAI,CAAC,QAAgB;QAClC,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACnC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAA","sourcesContent":["import { Loader } from './loader'\n\nclass FontFamilyLoader extends Loader<boolean> {\n protected override async doLoad(fontName: string) {\n const loadingPromise = (async () => {\n if ('fonts' in document) {\n try {\n await document.fonts.load(`1em ${fontName}`)\n await document.fonts.ready\n this.loadingPromises.delete(fontName)\n return true\n } catch (error) {\n console.error(`Failed to load font: ${fontName}`, error)\n this.loadingPromises.delete(fontName)\n }\n } else {\n console.warn(`This browser does not support the Font Loading API`)\n this.loadingPromises.delete(fontName)\n }\n })()\n\n this.loadingPromises.set(fontName, loadingPromise)\n return await loadingPromise\n }\n\n override async load(fontName: string) {\n return await super.load(fontName)\n }\n}\n\nexport const fontFamilyLoader = new FontFamilyLoader()\n"]}
@@ -1,20 +1,26 @@
1
- class Loader {
2
- loadedAssets = new Map();
1
+ export class Loader {
2
+ cachedAssets = new Map();
3
3
  loadingPromises = new Map();
4
4
  #refCount = new Map();
5
5
  #incRefCount(id) { this.#refCount.set(id, (this.#refCount.get(id) || 0) + 1); }
6
6
  hasActiveRef(id) { return this.#refCount.get(id) > 0; }
7
- _dispose(id, asset) { }
8
- checkLoaded(id) {
9
- return this.loadedAssets.has(id);
7
+ cleanup(id, asset) { }
8
+ checkCached(id) {
9
+ return this.cachedAssets.has(id);
10
+ }
11
+ getCached(id) {
12
+ if (!this.checkCached(id))
13
+ throw new Error(`Asset not found: ${id}`);
14
+ this.#incRefCount(id);
15
+ return this.cachedAssets.get(id);
10
16
  }
11
17
  async load(id, ...args) {
12
18
  this.#incRefCount(id);
13
- if (this.checkLoaded(id))
14
- return this.loadedAssets.get(id);
19
+ if (this.checkCached(id))
20
+ return this.cachedAssets.get(id);
15
21
  if (this.loadingPromises.has(id))
16
22
  return await this.loadingPromises.get(id);
17
- return await this._load(id, ...args);
23
+ return await this.doLoad(id, ...args);
18
24
  }
19
25
  release(id) {
20
26
  const refCount = this.#refCount.get(id);
@@ -22,10 +28,10 @@ class Loader {
22
28
  throw new Error(`Asset not found: ${id}`);
23
29
  if (refCount === 1) {
24
30
  this.#refCount.delete(id);
25
- const asset = this.loadedAssets.get(id);
31
+ const asset = this.cachedAssets.get(id);
26
32
  if (asset) {
27
- this._dispose(id, asset);
28
- this.loadedAssets.delete(id);
33
+ this.cleanup(id, asset);
34
+ this.cachedAssets.delete(id);
29
35
  }
30
36
  }
31
37
  else {
@@ -33,5 +39,4 @@ class Loader {
33
39
  }
34
40
  }
35
41
  }
36
- export { Loader };
37
42
  //# sourceMappingURL=loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/asset/loaders/loader.ts"],"names":[],"mappings":"AAAA,MAAe,MAAM;IACT,YAAY,GAAmB,IAAI,GAAG,EAAE,CAAC;IACzC,eAAe,GAAwC,IAAI,GAAG,EAAE,CAAC;IAE3E,SAAS,GAAwB,IAAI,GAAG,EAAE,CAAC;IAC3C,YAAY,CAAC,EAAU,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE7E,YAAY,CAAC,EAAU,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAEhE,QAAQ,CAAC,EAAU,EAAE,KAAQ,IAAqC,CAAC;IAE7E,WAAW,CAAC,EAAU;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAU,EAAE,GAAG,IAAW;QACnC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACtB,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC3D,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5E,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC;QACtE,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACxC,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;gBACzB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;CACF;AAED,OAAO,EAAE,MAAM,EAAE,CAAC","sourcesContent":["abstract class Loader<T> {\n protected loadedAssets: Map<string, T> = new Map();\n protected loadingPromises: Map<string, Promise<T | undefined>> = new Map();\n\n #refCount: Map<string, number> = new Map();\n #incRefCount(id: string) { this.#refCount.set(id, (this.#refCount.get(id) || 0) + 1); }\n\n protected hasActiveRef(id: string) { return this.#refCount.get(id)! > 0; }\n protected abstract _load(id: string, ...args: any[]): Promise<T | undefined>;\n protected _dispose(id: string, asset: T): void { /* override to clean up */ }\n\n checkLoaded(id: string) {\n return this.loadedAssets.has(id);\n }\n\n async load(id: string, ...args: any[]) {\n this.#incRefCount(id);\n if (this.checkLoaded(id)) return this.loadedAssets.get(id);\n if (this.loadingPromises.has(id)) return await this.loadingPromises.get(id);\n return await this._load(id, ...args);\n }\n\n release(id: string) {\n const refCount = this.#refCount.get(id);\n if (refCount === undefined) throw new Error(`Asset not found: ${id}`);\n if (refCount === 1) {\n this.#refCount.delete(id);\n const asset = this.loadedAssets.get(id);\n if (asset) {\n this._dispose(id, asset);\n this.loadedAssets.delete(id);\n }\n } else {\n this.#refCount.set(id, refCount - 1);\n }\n }\n}\n\nexport { Loader };\n"]}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/asset/loaders/loader.ts"],"names":[],"mappings":"AAAA,MAAM,OAAgB,MAAM;IAChB,YAAY,GAAG,IAAI,GAAG,EAAa,CAAA;IACnC,eAAe,GAAG,IAAI,GAAG,EAAkC,CAAA;IAErE,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAA;IACrC,YAAY,CAAC,EAAU,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA,CAAC,CAAC;IAE5E,YAAY,CAAC,EAAU,IAAI,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAE,GAAG,CAAC,CAAA,CAAC,CAAC;IAE/D,OAAO,CAAC,EAAU,EAAE,KAAQ,IAAqC,CAAC;IAE5E,WAAW,CAAC,EAAU;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAClC,CAAC;IAED,SAAS,CAAC,EAAU;QAClB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAA;QACpE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;QACrB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAClC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAU,EAAE,GAAG,IAAW;QACnC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;QACrB,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAAE,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC1D,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC3E,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAA;IACvC,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACvC,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAA;QACrE,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YACvC,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,CAAA;gBACvB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;CACF","sourcesContent":["export abstract class Loader<T> {\n protected cachedAssets = new Map<string, T>()\n protected loadingPromises = new Map<string, Promise<T | undefined>>()\n\n #refCount = new Map<string, number>()\n #incRefCount(id: string) { this.#refCount.set(id, (this.#refCount.get(id) || 0) + 1) }\n\n protected hasActiveRef(id: string) { return this.#refCount.get(id)! > 0 }\n protected abstract doLoad(id: string, ...args: any[]): Promise<T | undefined>\n protected cleanup(id: string, asset: T): void { /* override to clean up */ }\n\n checkCached(id: string) {\n return this.cachedAssets.has(id)\n }\n\n getCached(id: string) {\n if (!this.checkCached(id)) throw new Error(`Asset not found: ${id}`)\n this.#incRefCount(id)\n return this.cachedAssets.get(id)\n }\n\n async load(id: string, ...args: any[]) {\n this.#incRefCount(id)\n if (this.checkCached(id)) return this.cachedAssets.get(id)\n if (this.loadingPromises.has(id)) return await this.loadingPromises.get(id)\n return await this.doLoad(id, ...args)\n }\n\n release(id: string) {\n const refCount = this.#refCount.get(id)\n if (refCount === undefined) throw new Error(`Asset not found: ${id}`)\n if (refCount === 1) {\n this.#refCount.delete(id)\n const asset = this.cachedAssets.get(id)\n if (asset) {\n this.cleanup(id, asset)\n this.cachedAssets.delete(id)\n }\n } else {\n this.#refCount.set(id, refCount - 1)\n }\n }\n}\n"]}