kiwiengine 0.5.2 → 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 (325) hide show
  1. package/README.ko.md +2 -2
  2. package/README.md +2 -2
  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/dom-sprite-test/index.ts +6 -9
  155. package/examples/simple-battle/assets/spritesheets/hero-atlas.json +180 -223
  156. package/examples/simple-battle/assets/spritesheets/orc-atlas.json +180 -223
  157. package/examples/simple-battle/assets/spritesheets/potion-atlas.json +46 -61
  158. package/examples/simple-battle/hud/damage-text.ts +1 -0
  159. package/examples/simple-battle/hud/heal-text.ts +1 -0
  160. package/examples/simple-battle/objects/character.ts +3 -3
  161. package/examples/simple-battle/objects/hero.ts +3 -5
  162. package/examples/simple-battle/objects/orc.ts +3 -5
  163. package/examples/simple-battle/objects/potion.ts +0 -2
  164. package/examples/simple-battle/stage.ts +2 -4
  165. package/examples/sprite-test/index.ts +6 -9
  166. package/examples/webpack.config.js +4 -1
  167. package/lib/asset/loaders/audio.js +4 -1
  168. package/lib/asset/loaders/audio.js.map +1 -1
  169. package/lib/asset/loaders/binary.js +4 -1
  170. package/lib/asset/loaders/binary.js.map +1 -1
  171. package/lib/asset/loaders/bitmap-font.js +24 -21
  172. package/lib/asset/loaders/bitmap-font.js.map +1 -1
  173. package/lib/asset/loaders/font.js +3 -0
  174. package/lib/asset/loaders/font.js.map +1 -1
  175. package/lib/asset/loaders/spritesheet.js +12 -1
  176. package/lib/asset/loaders/spritesheet.js.map +1 -1
  177. package/lib/asset/loaders/text.js +3 -0
  178. package/lib/asset/loaders/text.js.map +1 -1
  179. package/lib/asset/loaders/texture.js +21 -26
  180. package/lib/asset/loaders/texture.js.map +1 -1
  181. package/lib/asset/preload.js.map +1 -1
  182. package/lib/collision/check-collision.js +16 -16
  183. package/lib/collision/check-collision.js.map +1 -1
  184. package/lib/dom/dom-animated-sprite.js +21 -36
  185. package/lib/dom/dom-animated-sprite.js.map +1 -1
  186. package/lib/dom/dom-game-object.js +9 -7
  187. package/lib/dom/dom-game-object.js.map +1 -1
  188. package/lib/dom/dom-particle.js.map +1 -1
  189. package/lib/index.js +1 -0
  190. package/lib/index.js.map +1 -1
  191. package/lib/node/core/dirty-number.js +0 -19
  192. package/lib/node/core/dirty-number.js.map +1 -1
  193. package/lib/node/core/renderable.js +7 -0
  194. package/lib/node/core/renderable.js.map +1 -1
  195. package/lib/node/core/transform.js +22 -11
  196. package/lib/node/core/transform.js.map +1 -1
  197. package/lib/node/ext/animated-sprite.js +3 -22
  198. package/lib/node/ext/animated-sprite.js.map +1 -1
  199. package/lib/node/ext/bitmap-text.js +7 -3
  200. package/lib/node/ext/bitmap-text.js.map +1 -1
  201. package/lib/node/ext/circle.js +18 -3
  202. package/lib/node/ext/circle.js.map +1 -1
  203. package/lib/node/ext/deplay.js +2 -0
  204. package/lib/node/ext/deplay.js.map +1 -1
  205. package/lib/node/ext/dom-container.js +2 -2
  206. package/lib/node/ext/dom-container.js.map +1 -1
  207. package/lib/node/ext/interval.js +2 -0
  208. package/lib/node/ext/interval.js.map +1 -1
  209. package/lib/node/ext/particle.js.map +1 -1
  210. package/lib/node/ext/rectangle.js +24 -4
  211. package/lib/node/ext/rectangle.js.map +1 -1
  212. package/lib/node/physics/physics-object.js +9 -29
  213. package/lib/node/physics/physics-object.js.map +1 -1
  214. package/lib/node/physics/physics-world.js +2 -0
  215. package/lib/node/physics/physics-world.js.map +1 -1
  216. package/lib/node/physics/rigidbodies.js +7 -0
  217. package/lib/node/physics/rigidbodies.js.map +1 -0
  218. package/lib/renderer/renderer.js +3 -2
  219. package/lib/renderer/renderer.js.map +1 -1
  220. package/lib/types/animation-atlas.js +2 -0
  221. package/lib/types/animation-atlas.js.map +1 -0
  222. package/lib/types/asset/loaders/audio.d.ts +1 -0
  223. package/lib/types/asset/loaders/audio.d.ts.map +1 -1
  224. package/lib/types/asset/loaders/binary.d.ts +1 -0
  225. package/lib/types/asset/loaders/binary.d.ts.map +1 -1
  226. package/lib/types/asset/loaders/bitmap-font.d.ts +1 -0
  227. package/lib/types/asset/loaders/bitmap-font.d.ts.map +1 -1
  228. package/lib/types/asset/loaders/font.d.ts +1 -0
  229. package/lib/types/asset/loaders/font.d.ts.map +1 -1
  230. package/lib/types/asset/loaders/spritesheet.d.ts +11 -3
  231. package/lib/types/asset/loaders/spritesheet.d.ts.map +1 -1
  232. package/lib/types/asset/loaders/text.d.ts +1 -0
  233. package/lib/types/asset/loaders/text.d.ts.map +1 -1
  234. package/lib/types/asset/loaders/texture.d.ts +1 -1
  235. package/lib/types/asset/loaders/texture.d.ts.map +1 -1
  236. package/lib/types/asset/preload.d.ts +2 -2
  237. package/lib/types/asset/preload.d.ts.map +1 -1
  238. package/lib/types/atlas copy.js +2 -0
  239. package/lib/types/atlas copy.js.map +1 -0
  240. package/lib/types/atlas.js +2 -0
  241. package/lib/types/atlas.js.map +1 -0
  242. package/lib/types/dom/dom-animated-sprite.d.ts +4 -10
  243. package/lib/types/dom/dom-animated-sprite.d.ts.map +1 -1
  244. package/lib/types/dom/dom-game-object.d.ts +1 -1
  245. package/lib/types/dom/dom-game-object.d.ts.map +1 -1
  246. package/lib/types/dom/dom-particle.d.ts.map +1 -1
  247. package/lib/types/index.d.ts +1 -0
  248. package/lib/types/index.d.ts.map +1 -1
  249. package/lib/types/node/core/dirty-number.d.ts +0 -8
  250. package/lib/types/node/core/dirty-number.d.ts.map +1 -1
  251. package/lib/types/node/core/renderable.d.ts +1 -0
  252. package/lib/types/node/core/renderable.d.ts.map +1 -1
  253. package/lib/types/node/core/transform.d.ts +4 -2
  254. package/lib/types/node/core/transform.d.ts.map +1 -1
  255. package/lib/types/node/ext/animated-sprite.d.ts +4 -10
  256. package/lib/types/node/ext/animated-sprite.d.ts.map +1 -1
  257. package/lib/types/node/ext/bitmap-text.d.ts.map +1 -1
  258. package/lib/types/node/ext/circle.d.ts +3 -3
  259. package/lib/types/node/ext/circle.d.ts.map +1 -1
  260. package/lib/types/node/ext/deplay.d.ts.map +1 -1
  261. package/lib/types/node/ext/dom-container.d.ts +1 -1
  262. package/lib/types/node/ext/dom-container.d.ts.map +1 -1
  263. package/lib/types/node/ext/interval.d.ts.map +1 -1
  264. package/lib/types/node/ext/particle.d.ts.map +1 -1
  265. package/lib/types/node/ext/rectangle.d.ts +4 -4
  266. package/lib/types/node/ext/rectangle.d.ts.map +1 -1
  267. package/lib/types/node/physics/physics-object.d.ts +2 -2
  268. package/lib/types/node/physics/physics-object.d.ts.map +1 -1
  269. package/lib/types/node/physics/physics-world.d.ts.map +1 -1
  270. package/lib/types/node/physics/rigidbodies.d.ts +23 -0
  271. package/lib/types/node/physics/rigidbodies.d.ts.map +1 -0
  272. package/lib/types/renderer/renderer.d.ts.map +1 -1
  273. package/lib/types/sprite-atlas.js +2 -0
  274. package/lib/types/sprite-atlas.js.map +1 -0
  275. package/lib/types/types/animation-atlas.d.ts +14 -0
  276. package/lib/types/types/animation-atlas.d.ts.map +1 -0
  277. package/lib/types/types/atlas copy.d.ts +12 -0
  278. package/lib/types/types/atlas copy.d.ts.map +1 -0
  279. package/lib/types/types/atlas.d.ts +16 -0
  280. package/lib/types/types/atlas.d.ts.map +1 -0
  281. package/lib/types/types/sprite-atlas.d.ts +13 -0
  282. package/lib/types/types/sprite-atlas.d.ts.map +1 -0
  283. package/package.json +1 -1
  284. package/src/asset/loaders/audio.ts +5 -2
  285. package/src/asset/loaders/binary.ts +5 -1
  286. package/src/asset/loaders/bitmap-font.ts +33 -27
  287. package/src/asset/loaders/font.ts +4 -0
  288. package/src/asset/loaders/spritesheet.ts +18 -5
  289. package/src/asset/loaders/text.ts +4 -0
  290. package/src/asset/loaders/texture.ts +19 -27
  291. package/src/asset/preload.ts +4 -8
  292. package/src/collision/check-collision.ts +16 -16
  293. package/src/dom/dom-animated-sprite.ts +24 -45
  294. package/src/dom/dom-game-object.ts +9 -6
  295. package/src/dom/dom-particle.ts +1 -1
  296. package/src/index.ts +1 -0
  297. package/src/node/core/dirty-number.ts +0 -24
  298. package/src/node/core/renderable.ts +7 -0
  299. package/src/node/core/transform.ts +23 -11
  300. package/src/node/ext/animated-sprite.ts +9 -29
  301. package/src/node/ext/bitmap-text.ts +7 -3
  302. package/src/node/ext/circle.ts +18 -3
  303. package/src/node/ext/deplay.ts +1 -0
  304. package/src/node/ext/dom-container.ts +2 -2
  305. package/src/node/ext/interval.ts +1 -0
  306. package/src/node/ext/particle.ts +1 -1
  307. package/src/node/ext/rectangle.ts +24 -4
  308. package/src/node/physics/physics-object.ts +11 -40
  309. package/src/node/physics/physics-world.ts +1 -0
  310. package/src/node/physics/rigidbodies.ts +14 -0
  311. package/src/renderer/renderer.ts +4 -3
  312. package/src/types/atlas.ts +17 -0
  313. package/examples/flappy-cat/assets/bgm/bgm.ogg +0 -0
  314. package/examples/flappy-cat/assets/images/base.png +0 -0
  315. package/examples/flappy-cat/assets/images/bg.png +0 -0
  316. package/examples/flappy-cat/assets/images/cat.png +0 -0
  317. package/examples/flappy-cat/assets/images/pipe-green.png +0 -0
  318. package/examples/flappy-cat/assets/images/pipe-red.png +0 -0
  319. package/examples/flappy-cat/assets/sfx/die.wav +0 -0
  320. package/examples/flappy-cat/assets/sfx/hit.wav +0 -0
  321. package/examples/flappy-cat/assets/sfx/point.wav +0 -0
  322. package/examples/flappy-cat/assets/sfx/wing.wav +0 -0
  323. package/examples/flappy-cat/dist/game.js +0 -0
  324. package/examples/flappy-cat/index.ts +0 -0
  325. /package/examples/{flappy-cat → auto-battle}/index.html +0 -0
@@ -3,44 +3,36 @@ import { Loader } from './loader'
3
3
 
4
4
  class TextureLoader extends Loader<Texture> {
5
5
  protected override async doLoad(src: string) {
6
- const loadingPromise = new Promise<Texture | undefined>((resolve) => {
7
- const image = new Image()
8
- image.crossOrigin = 'anonymous'
9
- image.src = src
6
+ const loadingPromise = (async () => {
7
+ const response = await fetch(src)
8
+ if (!response.ok) {
9
+ console.error(`Failed to load texture: ${src}`)
10
+ return
11
+ }
10
12
 
11
- image.onload = () => {
12
- this.loadingPromises.delete(src)
13
+ const blob = await response.blob()
14
+ const bitmap = await createImageBitmap(blob, { premultiplyAlpha: 'premultiply' })
13
15
 
14
- if (!this.hasActiveRef(src)) {
15
- resolve(undefined)
16
- return
17
- }
16
+ this.loadingPromises.delete(src)
18
17
 
18
+ if (this.hasActiveRef(src)) {
19
19
  if (this.cachedAssets.has(src)) {
20
- console.error(`Texture already loaded: ${src}`)
21
- resolve(undefined)
22
- return
20
+ console.error(`Texture already exists: ${src}`)
21
+ } else {
22
+ const texture = Texture.from(bitmap)
23
+ texture.source.scaleMode = 'nearest'
24
+ this.cachedAssets.set(src, texture)
25
+ return texture
23
26
  }
24
-
25
- const texture = Texture.from(image)
26
- texture.source.scaleMode = 'nearest'
27
- this.cachedAssets.set(src, texture)
28
- resolve(texture)
29
- }
30
-
31
- image.onerror = (error) => {
32
- this.loadingPromises.delete(src)
33
- console.error(`Failed to load texture: ${src}`, error)
34
- resolve(undefined)
35
27
  }
36
- })
28
+ })()
37
29
 
38
30
  this.loadingPromises.set(src, loadingPromise)
39
31
  return await loadingPromise
40
32
  }
41
33
 
42
- protected override cleanup(src: string, texture: Texture) {
43
- texture.destroy(true)
34
+ override async load(src: string) {
35
+ return await super.load(src)
44
36
  }
45
37
  }
46
38
 
@@ -1,4 +1,4 @@
1
- import { SpritesheetData } from 'pixi.js'
1
+ import { Atlas } from '../types/atlas'
2
2
  import { audioLoader } from './loaders/audio'
3
3
  import { binaryLoader } from './loaders/binary'
4
4
  import { bitmapFontLoader } from './loaders/bitmap-font'
@@ -8,13 +8,9 @@ import { getCachedAtlasId, spritesheetLoader } from './loaders/spritesheet'
8
8
  import { textLoader } from './loaders/text'
9
9
  import { textureLoader } from './loaders/texture'
10
10
 
11
- export type AssetSource = string | {
12
- src: string
13
- atlas: SpritesheetData
14
- } | {
15
- fnt: string
16
- src: string
17
- }
11
+ export type AssetSource = string
12
+ | { src: string, atlas: Atlas }
13
+ | { fnt: string, src: string }
18
14
 
19
15
  const loaderForPathMap: Array<{ check: (path: string) => boolean, loader: Loader<any> }> = [
20
16
  { check: (p) => p.endsWith('.json') || p.endsWith('.atlas'), loader: textLoader },
@@ -47,7 +47,7 @@ function checkRectRectCollision(
47
47
  const asx = ta.scaleX.v, asy = ta.scaleY.v
48
48
  const ahx = abs(ca.width * asx) * 0.5
49
49
  const ahy = abs(ca.height * asy) * 0.5
50
- const cA = ta.rotation.cos, sA = ta.rotation.sin
50
+ const cA = ta.cos, sA = ta.sin
51
51
  const aux = cA, auy = sA
52
52
  const avx = -sA, avy = cA
53
53
  // apply rotated local offset for center
@@ -60,7 +60,7 @@ function checkRectRectCollision(
60
60
  const bsx = tb.scaleX.v, bsy = tb.scaleY.v
61
61
  const bhx = abs(cb.width * bsx) * 0.5
62
62
  const bhy = abs(cb.height * bsy) * 0.5
63
- const cB = tb.rotation.cos, sB = tb.rotation.sin
63
+ const cB = tb.cos, sB = tb.sin
64
64
  const bux = cB, buy = sB
65
65
  const bvx = -sB, bvy = cB
66
66
  const box = (cb.x || 0) * bsx
@@ -98,7 +98,7 @@ let _ccx = 0, _ccy = 0
98
98
  function circleCenterScratch(c: CircleCollider, t: WorldTransform): void {
99
99
  // No object/array allocation; scalar math only
100
100
  const sx = t.scaleX.v, sy = t.scaleY.v
101
- const cos = t.rotation.cos, sin = t.rotation.sin
101
+ const cos = t.cos, sin = t.sin
102
102
  // local axes
103
103
  const ux = cos, uy = sin
104
104
  const vx = -sin, vy = cos
@@ -138,7 +138,7 @@ function checkRectCircleCollision(
138
138
  const rsx = tr.scaleX.v, rsy = tr.scaleY.v
139
139
  const rhx = abs(r.width * rsx) * 0.5
140
140
  const rhy = abs(r.height * rsy) * 0.5
141
- const rc = tr.rotation.cos, rs = tr.rotation.sin
141
+ const rc = tr.cos, rs = tr.sin
142
142
  const rux = rc, ruy = rs
143
143
  const rvx = -rs, rvy = rc
144
144
  const rox = (r.x || 0) * rsx
@@ -186,7 +186,7 @@ function checkPolyPolyCollision(
186
186
 
187
187
  // Frame A
188
188
  const asx = ta.scaleX.v, asy = ta.scaleY.v
189
- const acs = ta.rotation.cos, asn = ta.rotation.sin
189
+ const acs = ta.cos, asn = ta.sin
190
190
  const aux = acs, auy = asn
191
191
  const avx = -asn, avy = acs
192
192
  const aox = ((a as any).x || 0) * asx
@@ -196,7 +196,7 @@ function checkPolyPolyCollision(
196
196
 
197
197
  // Frame B
198
198
  const bsx = tb.scaleX.v, bsy = tb.scaleY.v
199
- const bcs = tb.rotation.cos, bsn = tb.rotation.sin
199
+ const bcs = tb.cos, bsn = tb.sin
200
200
  const bux = bcs, buy = bsn
201
201
  const bvx = -bsn, bvy = bcs
202
202
  const box = ((b as any).x || 0) * bsx
@@ -284,7 +284,7 @@ function checkPolyCircleCollision(poly: PolygonCollider, tp: WorldTransform, c:
284
284
 
285
285
  // Poly frame
286
286
  const psx = tp.scaleX.v, psy = tp.scaleY.v
287
- const pcs = tp.rotation.cos, psn = tp.rotation.sin
287
+ const pcs = tp.cos, psn = tp.sin
288
288
  const pux = pcs, puy = psn
289
289
  const pvx = -psn, pvy = pcs
290
290
  const pox = ((poly as any).x || 0) * psx
@@ -361,7 +361,7 @@ function checkPolyRectCollision(poly: PolygonCollider, tp: WorldTransform, r: Re
361
361
 
362
362
  // Poly frame
363
363
  const psx = tp.scaleX.v, psy = tp.scaleY.v
364
- const pcs = tp.rotation.cos, psn = tp.rotation.sin
364
+ const pcs = tp.cos, psn = tp.sin
365
365
  const pux = pcs, puy = psn
366
366
  const pvx = -psn, pvy = pcs
367
367
  const pox = ((poly as any).x || 0) * psx
@@ -373,7 +373,7 @@ function checkPolyRectCollision(poly: PolygonCollider, tp: WorldTransform, r: Re
373
373
  const rsx = tr.scaleX.v, rsy = tr.scaleY.v
374
374
  const rhx = abs(r.width * rsx) * 0.5
375
375
  const rhy = abs(r.height * rsy) * 0.5
376
- const rc = tr.rotation.cos, rs = tr.rotation.sin
376
+ const rc = tr.cos, rs = tr.sin
377
377
  const rux = rc, ruy = rs
378
378
  const rvx = -rs, rvy = rc
379
379
  const rox = (r.x || 0) * rsx, roy = (r.y || 0) * rsy
@@ -651,7 +651,7 @@ function checkEllipseRectCollision(
651
651
  const esx = te.scaleX.v, esy = te.scaleY.v
652
652
  _Arx = abs(e.width * esx) * 0.5
653
653
  _Ary = abs(e.height * esy) * 0.5
654
- const ecs = te.rotation.cos, esn = te.rotation.sin
654
+ const ecs = te.cos, esn = te.sin
655
655
  _Aux = ecs; _Auy = esn; _Avx = -esn; _Avy = ecs
656
656
  const eox = (e.x || 0) * esx, eoy = (e.y || 0) * esy
657
657
  _Acx = te.x.v + _Aux * eox + _Avx * eoy
@@ -663,7 +663,7 @@ function checkEllipseRectCollision(
663
663
  const rsx = tr.scaleX.v, rsy = tr.scaleY.v
664
664
  _Bhx = abs(r.width * rsx) * 0.5
665
665
  _Bhy = abs(r.height * rsy) * 0.5
666
- const rcs = tr.rotation.cos, rsn = tr.rotation.sin
666
+ const rcs = tr.cos, rsn = tr.sin
667
667
  _Bux = rcs; _Buy = rsn; _Bvx = -rsn; _Bvy = rcs
668
668
  const rox = (r.x || 0) * rsx, roy = (r.y || 0) * rsy
669
669
  _Bcx = tr.x.v + _Bux * rox + _Bvx * roy
@@ -682,7 +682,7 @@ function checkEllipseCircleCollision(
682
682
  const esx = te.scaleX.v, esy = te.scaleY.v
683
683
  _Arx = abs(e.width * esx) * 0.5
684
684
  _Ary = abs(e.height * esy) * 0.5
685
- const ecs = te.rotation.cos, esn = te.rotation.sin
685
+ const ecs = te.cos, esn = te.sin
686
686
  _Aux = ecs; _Auy = esn; _Avx = -esn; _Avy = ecs
687
687
  const eox = (e.x || 0) * esx, eoy = (e.y || 0) * esy
688
688
  _Acx = te.x.v + _Aux * eox + _Avx * eoy
@@ -708,7 +708,7 @@ function checkEllipseEllipseCollision(
708
708
  const asx = ta.scaleX.v, asy = ta.scaleY.v
709
709
  _Arx = abs(a.width * asx) * 0.5
710
710
  _Ary = abs(a.height * asy) * 0.5
711
- const acs = ta.rotation.cos, asn = ta.rotation.sin
711
+ const acs = ta.cos, asn = ta.sin
712
712
  _Aux = acs; _Auy = asn; _Avx = -asn; _Avy = acs
713
713
  const aox = (a.x || 0) * asx, aoy = (a.y || 0) * asy
714
714
  _Acx = ta.x.v + _Aux * aox + _Avx * aoy
@@ -720,7 +720,7 @@ function checkEllipseEllipseCollision(
720
720
  const bsx = tb.scaleX.v, bsy = tb.scaleY.v
721
721
  _Brx = abs(b.width * bsx) * 0.5
722
722
  _Bry = abs(b.height * bsy) * 0.5
723
- const bcs = tb.rotation.cos, bsn = tb.rotation.sin
723
+ const bcs = tb.cos, bsn = tb.sin
724
724
  _Bux = bcs; _Buy = bsn; _Bvx = -bsn; _Bvy = bcs
725
725
  const box = (b.x || 0) * bsx, boy = (b.y || 0) * bsy
726
726
  _Bcx = tb.x.v + _Bux * box + _Bvx * boy
@@ -735,7 +735,7 @@ function checkEllipseEllipseCollision(
735
735
  function checkPolyEllipseCollision(poly: PolygonCollider, tp: WorldTransform, e: EllipseCollider, te: WorldTransform): boolean {
736
736
  // A = Poly (LOCAL + Transform) → use PolyLocal support; reuse A scratch slots
737
737
  const psx = tp.scaleX.v, psy = tp.scaleY.v
738
- const pcs = tp.rotation.cos, psn = tp.rotation.sin
738
+ const pcs = tp.cos, psn = tp.sin
739
739
  const pux = pcs, puy = psn
740
740
  const pvx = -psn, pvy = pcs
741
741
  const pox = ((poly as any).x || 0) * psx
@@ -751,7 +751,7 @@ function checkPolyEllipseCollision(poly: PolygonCollider, tp: WorldTransform, e:
751
751
  const esx = te.scaleX.v, esy = te.scaleY.v
752
752
  _Brx = abs(e.width * esx) * 0.5
753
753
  _Bry = abs(e.height * esy) * 0.5
754
- const ecs = te.rotation.cos, esn = te.rotation.sin
754
+ const ecs = te.cos, esn = te.sin
755
755
  _Bux = ecs; _Buy = esn; _Bvx = -esn; _Bvy = ecs
756
756
  const eox = (e.x || 0) * esx, eoy = (e.y || 0) * esy
757
757
  _Bcx = te.x.v + _Bux * eox + _Bvx * eoy
@@ -1,29 +1,24 @@
1
1
  import { EventMap } from '@webtaku/event-emitter'
2
- import { SpritesheetData } from 'pixi.js'
2
+ import { Animation, Atlas } from '../types/atlas'
3
3
  import { DomGameObject, DomGameObjectOptions } from './dom-game-object'
4
4
  import { domTextureLoader } from './dom-texture-loader'
5
5
  import { setStyle } from './dom-utils'
6
6
 
7
7
  export type DomAnimatedSpriteNodeOptions = {
8
8
  src: string
9
- atlas: SpritesheetData
9
+ atlas: Atlas
10
10
  animation: string
11
- fps: number
12
- loop?: boolean
13
11
  } & DomGameObjectOptions
14
12
 
15
13
  export class DomAnimatedSpriteNode<E extends EventMap = EventMap> extends DomGameObject<E & {
16
14
  animationend: (animation: string) => void
17
15
  }> {
18
16
  #src: string
19
- #atlas: SpritesheetData
17
+ #atlas: Atlas
20
18
  #animation: string
21
- #fps: number
22
- #loop: boolean
23
19
 
24
- #frames: string[] = []
20
+ #animationData?: Animation
25
21
  #frameDuration?: number
26
- #textureScale = 1
27
22
  #elapsedTime = 0
28
23
  #currentFrameIdx = 0
29
24
 
@@ -32,8 +27,6 @@ export class DomAnimatedSpriteNode<E extends EventMap = EventMap> extends DomGam
32
27
  this.#src = options.src
33
28
  this.#atlas = options.atlas
34
29
  this.#animation = options.animation
35
- this.#fps = options.fps
36
- this.#loop = options.loop ?? true
37
30
  this.#load()
38
31
  }
39
32
 
@@ -46,31 +39,30 @@ export class DomAnimatedSpriteNode<E extends EventMap = EventMap> extends DomGam
46
39
  texture = await domTextureLoader.load(this.#src)
47
40
  }
48
41
 
49
- const S = this.#atlas.meta.scale === 'auto' ? 1 : Number(this.#atlas.meta.scale)
42
+ const a = this.#atlas.animations[this.#animation]
43
+ this.#animationData = a
44
+ this.#frameDuration = 1 / a.fps
50
45
 
51
- this.#frameDuration = 1 / this.#fps
52
- this.#frames = this.#atlas.animations?.[this.#animation] ?? []
53
- this.#textureScale = S
54
-
55
- const frameName = this.#frames[this.#currentFrameIdx]
56
- const frame = this.#atlas.frames[frameName].frame
46
+ const frameName = a.frames[this.#currentFrameIdx]
47
+ const frame = this.#atlas.frames[frameName]
57
48
 
58
49
  setStyle(this.el, !frameName || !texture ? { backgroundImage: 'none' } : {
59
50
  backgroundImage: `url(${this.#src})`,
60
- width: `${frame.w * S}px`,
61
- height: `${frame.h * S}px`,
62
- backgroundSize: `${texture.width * S}px ${texture.height * S}px`,
63
- backgroundPosition: `-${frame.x * S}px -${frame.y * S}px`
51
+ width: `${frame.w}px`,
52
+ height: `${frame.h}px`,
53
+ backgroundSize: `${texture.width}px ${texture.height}px`,
54
+ backgroundPosition: `-${frame.x}px -${frame.y}px`
64
55
  })
65
56
  }
66
57
 
67
58
  override render(dt: number) {
68
59
  super.render(dt)
69
60
 
70
- if (this.#frameDuration === undefined || this.#frames.length === 0) return
61
+ const a = this.#animationData
62
+ if (!a || a.frames.length === 0 || this.#frameDuration === undefined) return
71
63
 
72
- const lastIndex = this.#frames.length - 1
73
- if (!this.#loop && this.#currentFrameIdx === lastIndex) return
64
+ const lastIndex = a.frames.length - 1
65
+ if (!a.loop && this.#currentFrameIdx === lastIndex) return
74
66
 
75
67
  this.#elapsedTime += dt
76
68
  if (this.#elapsedTime < this.#frameDuration) return
@@ -81,7 +73,7 @@ export class DomAnimatedSpriteNode<E extends EventMap = EventMap> extends DomGam
81
73
  if (this.#currentFrameIdx === lastIndex) {
82
74
  (this as any).emit('animationend', this.#animation)
83
75
 
84
- if (this.#loop) {
76
+ if (a.loop) {
85
77
  this.#currentFrameIdx = 0
86
78
  } else {
87
79
  this.#elapsedTime = 0
@@ -92,14 +84,13 @@ export class DomAnimatedSpriteNode<E extends EventMap = EventMap> extends DomGam
92
84
  }
93
85
  }
94
86
 
95
- const S = this.#textureScale
96
- const frameName = this.#frames[this.#currentFrameIdx]
97
- const frame = this.#atlas.frames[frameName].frame
87
+ const frameName = a.frames[this.#currentFrameIdx]
88
+ const frame = this.#atlas.frames[frameName]
98
89
 
99
90
  setStyle(this.el, {
100
- width: `${frame.w * S}px`,
101
- height: `${frame.h * S}px`,
102
- backgroundPosition: `-${frame.x * S}px -${frame.y * S}px`
91
+ width: `${frame.w}px`,
92
+ height: `${frame.h}px`,
93
+ backgroundPosition: `-${frame.x}px -${frame.y}px`
103
94
  })
104
95
  }
105
96
 
@@ -126,7 +117,7 @@ export class DomAnimatedSpriteNode<E extends EventMap = EventMap> extends DomGam
126
117
  set animation(animation) {
127
118
  if (this.#animation !== animation) {
128
119
  this.#animation = animation
129
- this.#frames = this.#atlas.animations?.[animation] ?? []
120
+ this.#animationData = this.#atlas.animations[animation]
130
121
  this.#currentFrameIdx = 0
131
122
  this.#elapsedTime = 0
132
123
  }
@@ -134,18 +125,6 @@ export class DomAnimatedSpriteNode<E extends EventMap = EventMap> extends DomGam
134
125
 
135
126
  get animation() { return this.#animation }
136
127
 
137
- set fps(fps) {
138
- if (this.#fps !== fps) {
139
- this.#fps = fps
140
- this.#frameDuration = 1 / fps
141
- }
142
- }
143
-
144
- get fps() { return this.#fps }
145
-
146
- set loop(loop) { this.#loop = loop }
147
- get loop() { return this.#loop }
148
-
149
128
  override remove() {
150
129
  domTextureLoader.release(this.#src)
151
130
  super.remove()
@@ -1,10 +1,13 @@
1
1
  import { EventMap } from '@webtaku/event-emitter'
2
2
  import { DirtyNumber } from '../node/core/dirty-number'
3
3
  import { GameNode } from '../node/core/game-node'
4
- import { isRenderableNode } from '../node/core/renderable'
5
4
  import { LocalTransform, WorldTransform } from '../node/core/transform'
6
5
  import { setStyle } from './dom-utils'
7
6
 
7
+ export function isDomGameObject(v: unknown): v is DomGameObject {
8
+ return (v as DomGameObject).worldTransform !== undefined
9
+ }
10
+
8
11
  export type DomGameObjectOptions = {
9
12
  x?: number
10
13
  y?: number
@@ -68,12 +71,12 @@ export class DomGameObject<E extends EventMap = EventMap> extends GameNode<E> {
68
71
 
69
72
  render(dt: number) {
70
73
  this.update(dt)
71
- this._updateWorldTransform()
74
+ this.#updateWorldTransform()
72
75
  }
73
76
 
74
- protected _updateWorldTransform() {
77
+ #updateWorldTransform() {
75
78
  const parent = this.parent
76
- if (parent && isRenderableNode(parent)) {
79
+ if (parent && isDomGameObject(parent)) {
77
80
  this.worldTransform.update(parent.worldTransform, this.#localTransform)
78
81
  this.worldAlpha.v = parent.worldAlpha.v * this.alpha
79
82
  }
@@ -93,7 +96,7 @@ export class DomGameObject<E extends EventMap = EventMap> extends GameNode<E> {
93
96
  if (this.worldAlpha.dirty) this.el.style.opacity = this.worldAlpha.v.toString()
94
97
 
95
98
  for (const child of this.children) {
96
- if (isRenderableNode(child)) child._updateWorldTransform()
99
+ if (isDomGameObject(child)) child.#updateWorldTransform()
97
100
  }
98
101
  this.worldTransform.resetDirty()
99
102
  }
@@ -101,7 +104,7 @@ export class DomGameObject<E extends EventMap = EventMap> extends GameNode<E> {
101
104
  attachTo(target: HTMLElement) {
102
105
  target.appendChild(this.el)
103
106
  this.parent = new DomRootNode()
104
- this._updateWorldTransform()
107
+ this.#updateWorldTransform()
105
108
  return this
106
109
  }
107
110
 
@@ -120,7 +120,7 @@ export class DomParticleSystem extends DomGameObject {
120
120
  }
121
121
  }
122
122
 
123
- protected update(dt: number) {
123
+ protected override update(dt: number) {
124
124
  super.update(dt)
125
125
 
126
126
  const ps = this.#particles
package/src/index.ts CHANGED
@@ -28,6 +28,7 @@ export { SpriteNode, SpriteNodeOptions } from './node/ext/sprite'
28
28
  // Physics
29
29
  export { PhysicsObject, PhysicsObjectOptions } from './node/physics/physics-object'
30
30
  export { PhysicsWorld } from './node/physics/physics-world'
31
+ export { CircleRigidbody, PolygonRigidbody, RectangleRigidbody, Rigidbody, RigidbodyType } from './node/physics/rigidbodies'
31
32
 
32
33
  // DOM Nodes
33
34
  export { DomAnimatedSpriteNode } from './dom/dom-animated-sprite'
@@ -19,27 +19,3 @@ export class DirtyNumber {
19
19
  this.#isDirty = false
20
20
  }
21
21
  }
22
-
23
- export class DirtyRadian extends DirtyNumber {
24
- #cos: number
25
- #sin: number
26
-
27
- constructor(initialValue: number) {
28
- super(initialValue)
29
- this.#cos = Math.cos(initialValue)
30
- this.#sin = Math.sin(initialValue)
31
- }
32
-
33
- get cos() { return this.#cos }
34
- get sin() { return this.#sin }
35
-
36
- override set v(newValue: number) {
37
- if (super.v !== newValue) {
38
- this.#cos = Math.cos(newValue)
39
- this.#sin = Math.sin(newValue)
40
- }
41
- super.v = newValue
42
- }
43
-
44
- override get v() { return super.v }
45
- }
@@ -57,7 +57,14 @@ export abstract class RenderableNode<C extends PixiContainer, E extends EventMap
57
57
  for (const child of this.children) {
58
58
  if (isRenderableNode(child)) child._updateWorldTransform()
59
59
  }
60
+ }
61
+
62
+ _resetWorldTransformDirty() {
63
+ for (const child of this.children) {
64
+ if (isRenderableNode(child)) child._resetWorldTransformDirty()
65
+ }
60
66
  this.worldTransform.resetDirty()
67
+ this.worldAlpha.resetDirty()
61
68
  }
62
69
 
63
70
  set tint(t) { this._pixiContainer.tint = t }
@@ -1,4 +1,4 @@
1
- import { DirtyNumber, DirtyRadian } from './dirty-number'
1
+ import { DirtyNumber } from './dirty-number'
2
2
 
3
3
  export class LocalTransform {
4
4
  x = 0
@@ -26,30 +26,42 @@ export class LocalTransform {
26
26
  }
27
27
 
28
28
  export class WorldTransform {
29
- x = new DirtyNumber(Number.NEGATIVE_INFINITY)
30
- y = new DirtyNumber(Number.NEGATIVE_INFINITY)
29
+ x = new DirtyNumber(NaN)
30
+ y = new DirtyNumber(NaN)
31
31
  scaleX = new DirtyNumber(1)
32
32
  scaleY = new DirtyNumber(1)
33
- rotation = new DirtyRadian(0)
33
+ rotation = new DirtyNumber(0)
34
+ cos = 1
35
+ sin = 0
34
36
 
35
37
  update(parent: WorldTransform, local: LocalTransform) {
36
38
  const rx = local.x * parent.scaleX.v
37
39
  const ry = local.y * parent.scaleY.v
38
- const pCos = parent.rotation.cos
39
- const pSin = parent.rotation.sin
40
+ const pCos = parent.cos
41
+ const pSin = parent.sin
40
42
 
41
43
  this.scaleX.v = parent.scaleX.v * local.scaleX
42
44
  this.scaleY.v = parent.scaleY.v * local.scaleY
43
45
 
44
46
  const pivotX = local.pivotX * this.scaleX.v
45
47
  const pivotY = local.pivotY * this.scaleY.v
46
- const cos = local.cos
47
- const sin = local.sin
48
48
 
49
- this.x.v = parent.x.v + (rx * pCos - ry * pSin) - (pivotX * cos - pivotY * sin)
50
- this.y.v = parent.y.v + (rx * pSin + ry * pCos) - (pivotX * sin + pivotY * cos)
49
+ // 로컬 회전
50
+ const lCos = local.cos
51
+ const lSin = local.sin
52
+ // 월드 회전(부모+자식) cos/sin — 덧셈정리
53
+ const wCos = pCos * lCos - pSin * lSin
54
+ const wSin = pSin * lCos + pCos * lSin
51
55
 
52
- this.rotation.v = parent.rotation.v + local.rotation
56
+ // 위치: 부모 회전으로 (rx,ry) 회전 + 월드 회전으로 피벗 보정
57
+ this.x.v = parent.x.v + (rx * pCos - ry * pSin) - (pivotX * wCos - pivotY * wSin)
58
+ this.y.v = parent.y.v + (rx * pSin + ry * pCos) - (pivotX * wSin + pivotY * wCos)
59
+
60
+ // 회전(스칼라 값)
61
+ const rot = parent.rotation.v + local.rotation
62
+ this.rotation.v = rot
63
+ this.cos = wCos
64
+ this.sin = wSin
53
65
  }
54
66
 
55
67
  get dirty() {
@@ -1,24 +1,21 @@
1
1
  import { EventMap } from '@webtaku/event-emitter'
2
- import { AnimatedSprite as PixiAnimatedSprite, Spritesheet, SpritesheetData } from 'pixi.js'
2
+ import { AnimatedSprite as PixiAnimatedSprite, Spritesheet } from 'pixi.js'
3
3
  import { getCachedAtlasId, spritesheetLoader } from '../../asset/loaders/spritesheet'
4
+ import { Atlas } from '../../types/atlas'
4
5
  import { GameObject, GameObjectOptions } from '../core/game-object'
5
6
 
6
7
  export type AnimatedSpriteNodeOptions = {
7
8
  src: string
8
- atlas: SpritesheetData
9
+ atlas: Atlas
9
10
  animation: string
10
- fps: number
11
- loop?: boolean
12
11
  } & GameObjectOptions
13
12
 
14
13
  export class AnimatedSpriteNode<E extends EventMap = EventMap> extends GameObject<E & {
15
14
  animationend: (animation: string) => void
16
15
  }> {
17
16
  #src: string
18
- #atlas: SpritesheetData
17
+ #atlas: Atlas
19
18
  #animation: string
20
- #fps: number
21
- #loop: boolean
22
19
 
23
20
  #atlasId!: string
24
21
  #sheet?: Spritesheet
@@ -29,8 +26,6 @@ export class AnimatedSpriteNode<E extends EventMap = EventMap> extends GameObjec
29
26
  this.#src = options.src
30
27
  this.#atlas = options.atlas
31
28
  this.#animation = options.animation
32
- this.#fps = options.fps
33
- this.#loop = options.loop ?? true
34
29
  this.#load()
35
30
  }
36
31
 
@@ -57,13 +52,16 @@ export class AnimatedSpriteNode<E extends EventMap = EventMap> extends GameObjec
57
52
  return
58
53
  }
59
54
 
55
+ const a = this.#atlas.animations[this.#animation]
60
56
  const s = new PixiAnimatedSprite(this.#sheet.animations[this.#animation])
57
+
61
58
  s.anchor.set(0.5, 0.5)
62
- s.loop = this.#loop
63
- s.animationSpeed = (this.#fps ?? 0) / 60
59
+ s.loop = a.loop
60
+ s.animationSpeed = a.fps / 60
64
61
  s.play()
65
62
  s.onLoop = () => (this as any).emit('animationend', this.#animation)
66
63
  s.onComplete = () => (this as any).emit('animationend', this.#animation)
64
+
67
65
  this._pixiContainer.addChild(s)
68
66
  this.#sprite = s
69
67
  }
@@ -98,24 +96,6 @@ export class AnimatedSpriteNode<E extends EventMap = EventMap> extends GameObjec
98
96
 
99
97
  get animation() { return this.#animation }
100
98
 
101
- set fps(fps) {
102
- if (this.#fps !== fps) {
103
- this.#fps = fps
104
- if (this.#sprite) this.#sprite.animationSpeed = (fps ?? 0) / 60
105
- }
106
- }
107
-
108
- get fps() { return this.#fps }
109
-
110
- set loop(loop) {
111
- if (this.#loop !== loop) {
112
- this.#loop = loop
113
- if (this.#sprite) this.#sprite.loop = loop
114
- }
115
- }
116
-
117
- get loop() { return this.#loop }
118
-
119
99
  remove() {
120
100
  spritesheetLoader.release(this.#atlasId)
121
101
  super.remove()
@@ -13,6 +13,7 @@ export class BitmapTextNode<E extends EventMap = EventMap> extends GameObject<E>
13
13
  #fnt: string
14
14
  #src: string
15
15
  #text: string
16
+ #sprites: PixiSprite[] = []
16
17
 
17
18
  constructor(options: BitmapTextNodeOptions) {
18
19
  super(options)
@@ -32,7 +33,10 @@ export class BitmapTextNode<E extends EventMap = EventMap> extends GameObject<E>
32
33
  }
33
34
  if (!font) return
34
35
 
35
- const sprites: PixiSprite[] = []
36
+ for (const sprite of this.#sprites) {
37
+ sprite.destroy()
38
+ }
39
+ this.#sprites = []
36
40
 
37
41
  let xPos = 0, yPos = 0
38
42
  let minX = Infinity, minY = Infinity
@@ -60,7 +64,7 @@ export class BitmapTextNode<E extends EventMap = EventMap> extends GameObject<E>
60
64
  sprite.x = x0
61
65
  sprite.y = y0
62
66
 
63
- sprites.push(sprite)
67
+ this.#sprites.push(sprite)
64
68
 
65
69
  const x1 = x0 + c.width
66
70
  const y1 = y0 + c.height
@@ -86,7 +90,7 @@ export class BitmapTextNode<E extends EventMap = EventMap> extends GameObject<E>
86
90
  const width = maxX - minX
87
91
  const height = maxY - minY
88
92
 
89
- for (const s of sprites) {
93
+ for (const s of this.#sprites) {
90
94
  s.x -= width / 2
91
95
  s.y -= height / 2
92
96
  this._pixiContainer.addChild(s)