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.
- package/README.ko.md +550 -0
- package/README.md +575 -4
- package/examples/auto-battle/assets/bgm/battle.mp3 +0 -0
- package/examples/auto-battle/assets/bitmap-fonts/white-peaberry.fnt +107 -0
- package/examples/auto-battle/assets/bitmap-fonts/white-peaberry.png +0 -0
- package/examples/auto-battle/assets/joystick/joystick.png +0 -0
- package/examples/auto-battle/assets/joystick/knob.png +0 -0
- package/examples/auto-battle/assets/sfx/hero/die/die.wav +0 -0
- package/examples/auto-battle/assets/sfx/hero/heal/heal.wav +0 -0
- package/examples/auto-battle/assets/sfx/hero/hit/hit1.wav +0 -0
- package/examples/auto-battle/assets/sfx/hero/hit/hit2.wav +0 -0
- package/examples/auto-battle/assets/sfx/hero/hit/hit3.wav +0 -0
- package/examples/auto-battle/assets/sfx/hero/miss/miss1.wav +0 -0
- package/examples/auto-battle/assets/sfx/hero/miss/miss2.wav +0 -0
- package/examples/auto-battle/assets/sfx/hero/miss/miss3.wav +0 -0
- package/examples/auto-battle/assets/sfx/orc/die/die.wav +0 -0
- package/examples/auto-battle/assets/sfx/orc/hit/hit1.wav +0 -0
- package/examples/auto-battle/assets/sfx/orc/hit/hit2.wav +0 -0
- package/examples/auto-battle/assets/sfx/orc/hit/hit3.wav +0 -0
- package/examples/auto-battle/assets/sfx/orc/miss/miss1.wav +0 -0
- package/examples/auto-battle/assets/sfx/orc/miss/miss2.wav +0 -0
- package/examples/auto-battle/assets/sfx/orc/miss/miss3.wav +0 -0
- package/examples/auto-battle/assets/spritesheets/hero-atlas.json +246 -0
- package/examples/auto-battle/assets/spritesheets/hero.png +0 -0
- package/examples/auto-battle/assets/spritesheets/orc-atlas.json +246 -0
- package/examples/auto-battle/assets/spritesheets/orc.png +0 -0
- package/examples/auto-battle/assets/spritesheets/potion-atlas.json +68 -0
- package/examples/auto-battle/assets/spritesheets/potion.png +0 -0
- package/examples/auto-battle/dist/game.js +2 -0
- package/examples/auto-battle/dist/game.js.LICENSE.txt +35 -0
- package/examples/auto-battle/hud/damage-text.ts +46 -0
- package/examples/auto-battle/hud/heal-text.ts +46 -0
- package/examples/auto-battle/hud/hp-bar.ts +38 -0
- package/examples/auto-battle/index.ts +41 -0
- package/examples/auto-battle/objects/character.ts +95 -0
- package/examples/auto-battle/objects/hero.ts +119 -0
- package/examples/auto-battle/objects/orc.ts +107 -0
- package/examples/auto-battle/objects/potion.ts +27 -0
- package/examples/auto-battle/stage.ts +366 -0
- package/examples/battle-benchmark-matterjs/assets/bgm/battle.mp3 +0 -0
- package/examples/battle-benchmark-matterjs/assets/bitmap-fonts/white-peaberry.fnt +107 -0
- package/examples/battle-benchmark-matterjs/assets/bitmap-fonts/white-peaberry.png +0 -0
- package/examples/battle-benchmark-matterjs/assets/joystick/joystick.png +0 -0
- package/examples/battle-benchmark-matterjs/assets/joystick/knob.png +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/hero/die/die.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/hero/heal/heal.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/hero/hit/hit1.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/hero/hit/hit2.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/hero/hit/hit3.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/hero/miss/miss1.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/hero/miss/miss2.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/hero/miss/miss3.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/orc/die/die.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/orc/hit/hit1.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/orc/hit/hit2.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/orc/hit/hit3.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/orc/miss/miss1.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/orc/miss/miss2.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/sfx/orc/miss/miss3.wav +0 -0
- package/examples/battle-benchmark-matterjs/assets/spritesheets/hero-atlas.json +246 -0
- package/examples/battle-benchmark-matterjs/assets/spritesheets/hero.png +0 -0
- package/examples/battle-benchmark-matterjs/assets/spritesheets/orc-atlas.json +246 -0
- package/examples/battle-benchmark-matterjs/assets/spritesheets/orc.png +0 -0
- package/examples/battle-benchmark-matterjs/assets/spritesheets/potion-atlas.json +68 -0
- package/examples/battle-benchmark-matterjs/assets/spritesheets/potion.png +0 -0
- package/examples/battle-benchmark-matterjs/dist/game.js +2 -0
- package/examples/battle-benchmark-matterjs/dist/game.js.LICENSE.txt +35 -0
- package/examples/battle-benchmark-matterjs/hud/damage-text.ts +46 -0
- package/examples/battle-benchmark-matterjs/hud/heal-text.ts +46 -0
- package/examples/battle-benchmark-matterjs/hud/hp-bar.ts +38 -0
- package/examples/battle-benchmark-matterjs/index.html +24 -0
- package/examples/battle-benchmark-matterjs/index.ts +41 -0
- package/examples/battle-benchmark-matterjs/objects/character.ts +95 -0
- package/examples/battle-benchmark-matterjs/objects/hero.ts +111 -0
- package/examples/battle-benchmark-matterjs/objects/orc.ts +107 -0
- package/examples/battle-benchmark-matterjs/objects/potion.ts +27 -0
- package/examples/battle-benchmark-matterjs/stage.ts +177 -0
- package/examples/battle-benchmark-separation/assets/bgm/battle.mp3 +0 -0
- package/examples/battle-benchmark-separation/assets/bitmap-fonts/white-peaberry.fnt +107 -0
- package/examples/battle-benchmark-separation/assets/bitmap-fonts/white-peaberry.png +0 -0
- package/examples/battle-benchmark-separation/assets/joystick/joystick.png +0 -0
- package/examples/battle-benchmark-separation/assets/joystick/knob.png +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/hero/die/die.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/hero/heal/heal.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/hero/hit/hit1.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/hero/hit/hit2.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/hero/hit/hit3.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/hero/miss/miss1.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/hero/miss/miss2.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/hero/miss/miss3.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/orc/die/die.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/orc/hit/hit1.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/orc/hit/hit2.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/orc/hit/hit3.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/orc/miss/miss1.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/orc/miss/miss2.wav +0 -0
- package/examples/battle-benchmark-separation/assets/sfx/orc/miss/miss3.wav +0 -0
- package/examples/battle-benchmark-separation/assets/spritesheets/hero-atlas.json +246 -0
- package/examples/battle-benchmark-separation/assets/spritesheets/hero.png +0 -0
- package/examples/battle-benchmark-separation/assets/spritesheets/orc-atlas.json +246 -0
- package/examples/battle-benchmark-separation/assets/spritesheets/orc.png +0 -0
- package/examples/battle-benchmark-separation/assets/spritesheets/potion-atlas.json +68 -0
- package/examples/battle-benchmark-separation/assets/spritesheets/potion.png +0 -0
- package/examples/battle-benchmark-separation/dist/game.js +2 -0
- package/examples/battle-benchmark-separation/dist/game.js.LICENSE.txt +35 -0
- package/examples/battle-benchmark-separation/hud/damage-text.ts +46 -0
- package/examples/battle-benchmark-separation/hud/heal-text.ts +46 -0
- package/examples/battle-benchmark-separation/hud/hp-bar.ts +38 -0
- package/examples/battle-benchmark-separation/index.html +24 -0
- package/examples/battle-benchmark-separation/index.ts +41 -0
- package/examples/battle-benchmark-separation/objects/character.ts +225 -0
- package/examples/battle-benchmark-separation/objects/hero.ts +110 -0
- package/examples/battle-benchmark-separation/objects/orc.ts +213 -0
- package/examples/battle-benchmark-separation/objects/potion.ts +27 -0
- package/examples/battle-benchmark-separation/stage.ts +178 -0
- package/examples/battle-benchmark-separation2/assets/bgm/battle.mp3 +0 -0
- package/examples/battle-benchmark-separation2/assets/bitmap-fonts/white-peaberry.fnt +107 -0
- package/examples/battle-benchmark-separation2/assets/bitmap-fonts/white-peaberry.png +0 -0
- package/examples/battle-benchmark-separation2/assets/joystick/joystick.png +0 -0
- package/examples/battle-benchmark-separation2/assets/joystick/knob.png +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/hero/die/die.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/hero/heal/heal.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/hero/hit/hit1.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/hero/hit/hit2.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/hero/hit/hit3.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/hero/miss/miss1.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/hero/miss/miss2.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/hero/miss/miss3.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/orc/die/die.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/orc/hit/hit1.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/orc/hit/hit2.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/orc/hit/hit3.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/orc/miss/miss1.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/orc/miss/miss2.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/sfx/orc/miss/miss3.wav +0 -0
- package/examples/battle-benchmark-separation2/assets/spritesheets/hero-atlas.json +246 -0
- package/examples/battle-benchmark-separation2/assets/spritesheets/hero.png +0 -0
- package/examples/battle-benchmark-separation2/assets/spritesheets/orc-atlas.json +246 -0
- package/examples/battle-benchmark-separation2/assets/spritesheets/orc.png +0 -0
- package/examples/battle-benchmark-separation2/assets/spritesheets/potion-atlas.json +68 -0
- package/examples/battle-benchmark-separation2/assets/spritesheets/potion.png +0 -0
- package/examples/battle-benchmark-separation2/dist/game.js +2 -0
- package/examples/battle-benchmark-separation2/dist/game.js.LICENSE.txt +35 -0
- package/examples/battle-benchmark-separation2/hud/damage-text.ts +46 -0
- package/examples/battle-benchmark-separation2/hud/heal-text.ts +46 -0
- package/examples/battle-benchmark-separation2/hud/hp-bar.ts +38 -0
- package/examples/battle-benchmark-separation2/index.html +24 -0
- package/examples/battle-benchmark-separation2/index.ts +41 -0
- package/examples/battle-benchmark-separation2/objects/character.ts +195 -0
- package/examples/battle-benchmark-separation2/objects/hero.ts +110 -0
- package/examples/battle-benchmark-separation2/objects/orc.ts +213 -0
- package/examples/battle-benchmark-separation2/objects/potion.ts +27 -0
- package/examples/battle-benchmark-separation2/stage.ts +178 -0
- package/examples/collision-test/assets/cat.png +0 -0
- package/examples/collision-test/dist/game.js +2 -0
- package/examples/collision-test/dist/game.js.LICENSE.txt +35 -0
- package/examples/collision-test/index.html +24 -0
- package/examples/collision-test/index.ts +30 -0
- package/examples/dom-particle-test/assets/bird.png +0 -0
- package/examples/dom-particle-test/dist/game.js +2 -0
- package/examples/dom-particle-test/dist/game.js.LICENSE.txt +35 -0
- package/examples/dom-particle-test/index.html +24 -0
- package/examples/dom-particle-test/index.ts +27 -0
- package/examples/dom-sprite-test/assets/bird.png +0 -0
- package/examples/dom-sprite-test/assets/fire.png +0 -0
- package/examples/dom-sprite-test/assets/run.png +0 -0
- package/examples/dom-sprite-test/dist/game.js +2 -0
- package/examples/dom-sprite-test/dist/game.js.LICENSE.txt +35 -0
- package/examples/dom-sprite-test/index.html +24 -0
- package/examples/dom-sprite-test/index.ts +35 -0
- package/examples/dom-test/dist/game.js +2 -0
- package/examples/dom-test/dist/game.js.LICENSE.txt +35 -0
- package/examples/dom-test/index.html +24 -0
- package/examples/dom-test/index.ts +22 -0
- package/examples/particle-test/assets/bird.png +0 -0
- package/examples/particle-test/dist/game.js +2 -0
- package/examples/particle-test/dist/game.js.LICENSE.txt +35 -0
- package/examples/particle-test/index.html +24 -0
- package/examples/particle-test/index.ts +30 -0
- package/examples/renderer-test/dist/game.js +2 -0
- package/examples/renderer-test/dist/game.js.LICENSE.txt +35 -0
- package/examples/renderer-test/index.html +24 -0
- package/examples/renderer-test/index.ts +9 -0
- package/examples/simple-battle/assets/bgm/battle.mp3 +0 -0
- package/examples/simple-battle/assets/bitmap-fonts/white-peaberry.fnt +107 -0
- package/examples/simple-battle/assets/bitmap-fonts/white-peaberry.png +0 -0
- package/examples/simple-battle/assets/joystick/joystick.png +0 -0
- package/examples/simple-battle/assets/joystick/knob.png +0 -0
- package/examples/simple-battle/assets/sfx/hero/die/die.wav +0 -0
- package/examples/simple-battle/assets/sfx/hero/heal/heal.wav +0 -0
- package/examples/simple-battle/assets/sfx/hero/hit/hit1.wav +0 -0
- package/examples/simple-battle/assets/sfx/hero/hit/hit2.wav +0 -0
- package/examples/simple-battle/assets/sfx/hero/hit/hit3.wav +0 -0
- package/examples/simple-battle/assets/sfx/hero/miss/miss1.wav +0 -0
- package/examples/simple-battle/assets/sfx/hero/miss/miss2.wav +0 -0
- package/examples/simple-battle/assets/sfx/hero/miss/miss3.wav +0 -0
- package/examples/simple-battle/assets/sfx/orc/die/die.wav +0 -0
- package/examples/simple-battle/assets/sfx/orc/hit/hit1.wav +0 -0
- package/examples/simple-battle/assets/sfx/orc/hit/hit2.wav +0 -0
- package/examples/simple-battle/assets/sfx/orc/hit/hit3.wav +0 -0
- package/examples/simple-battle/assets/sfx/orc/miss/miss1.wav +0 -0
- package/examples/simple-battle/assets/sfx/orc/miss/miss2.wav +0 -0
- package/examples/simple-battle/assets/sfx/orc/miss/miss3.wav +0 -0
- package/examples/simple-battle/assets/spritesheets/hero-atlas.json +246 -0
- package/examples/simple-battle/assets/spritesheets/hero.png +0 -0
- package/examples/simple-battle/assets/spritesheets/orc-atlas.json +246 -0
- package/examples/simple-battle/assets/spritesheets/orc.png +0 -0
- package/examples/simple-battle/assets/spritesheets/potion-atlas.json +68 -0
- package/examples/simple-battle/assets/spritesheets/potion.png +0 -0
- package/examples/simple-battle/dist/game.js +2 -0
- package/examples/simple-battle/dist/game.js.LICENSE.txt +35 -0
- package/examples/simple-battle/hud/damage-text.ts +46 -0
- package/examples/simple-battle/hud/heal-text.ts +46 -0
- package/examples/simple-battle/hud/hp-bar.ts +38 -0
- package/examples/simple-battle/index.html +24 -0
- package/examples/simple-battle/index.ts +41 -0
- package/examples/simple-battle/objects/character.ts +95 -0
- package/examples/simple-battle/objects/hero.ts +111 -0
- package/examples/simple-battle/objects/orc.ts +107 -0
- package/examples/simple-battle/objects/potion.ts +27 -0
- package/examples/simple-battle/stage.ts +174 -0
- package/examples/spine-test/assets/spine/spineboy.atlas +95 -0
- package/examples/spine-test/assets/spine/spineboy.png +0 -0
- package/examples/spine-test/assets/spine/spineboy.skel +0 -0
- package/examples/spine-test/dist/game.js +2 -0
- package/examples/spine-test/dist/game.js.LICENSE.txt +35 -0
- package/examples/spine-test/index.html +24 -0
- package/examples/spine-test/index.ts +29 -0
- package/examples/sprite-test/assets/bird.png +0 -0
- package/examples/sprite-test/assets/fire.png +0 -0
- package/examples/sprite-test/dist/game.js +2 -0
- package/examples/sprite-test/dist/game.js.LICENSE.txt +35 -0
- package/examples/sprite-test/index.html +24 -0
- package/examples/sprite-test/index.ts +38 -0
- package/examples/tsconfig.json +2 -1
- package/examples/webpack.config.js +17 -3
- package/jest.config.ts +10 -0
- package/lib/asset/audio.js +47 -11
- package/lib/asset/audio.js.map +1 -1
- package/lib/asset/loaders/audio.js +7 -4
- package/lib/asset/loaders/audio.js.map +1 -1
- package/lib/asset/loaders/binary.js +7 -4
- package/lib/asset/loaders/binary.js.map +1 -1
- package/lib/asset/loaders/bitmap-font.js +74 -0
- package/lib/asset/loaders/bitmap-font.js.map +1 -0
- package/lib/asset/loaders/font.js +4 -1
- package/lib/asset/loaders/font.js.map +1 -1
- package/lib/asset/loaders/loader.js +17 -12
- package/lib/asset/loaders/loader.js.map +1 -1
- package/lib/asset/loaders/spritesheet.js +18 -8
- package/lib/asset/loaders/spritesheet.js.map +1 -1
- package/lib/asset/loaders/text.js +6 -3
- package/lib/asset/loaders/text.js.map +1 -1
- package/lib/asset/loaders/texture.js +22 -26
- package/lib/asset/loaders/texture.js.map +1 -1
- package/lib/asset/preload.js +60 -56
- package/lib/asset/preload.js.map +1 -1
- package/lib/collision/check-collision.js +804 -0
- package/lib/collision/check-collision.js.map +1 -0
- package/lib/collision/check-collision.test.js +300 -0
- package/lib/collision/check-collision.test.js.map +1 -0
- package/lib/collision/colliders.js +8 -0
- package/lib/collision/colliders.js.map +1 -0
- package/lib/debug.js.map +1 -0
- package/lib/dom/dom-animated-sprite.js +106 -0
- package/lib/dom/dom-animated-sprite.js.map +1 -0
- package/lib/dom/dom-game-object.js +108 -0
- package/lib/dom/dom-game-object.js.map +1 -0
- package/lib/dom/dom-particle.js +105 -0
- package/lib/dom/dom-particle.js.map +1 -0
- package/lib/dom/dom-preload.js +43 -0
- package/lib/dom/dom-preload.js.map +1 -0
- package/lib/dom/dom-sprite.js +40 -0
- package/lib/dom/dom-sprite.js.map +1 -0
- package/lib/dom/dom-texture-loader.js +36 -0
- package/lib/dom/dom-texture-loader.js.map +1 -0
- package/lib/dom/dom-utils.js +20 -0
- package/lib/dom/dom-utils.js.map +1 -0
- package/lib/index copy.js +16 -0
- package/lib/index copy.js.map +1 -0
- package/lib/index.js +36 -10
- package/lib/index.js.map +1 -1
- package/lib/input/joystick.js +262 -0
- package/lib/input/joystick.js.map +1 -0
- package/lib/node/core/dirty-number.js +19 -0
- package/lib/node/core/dirty-number.js.map +1 -0
- package/lib/node/core/game-node.js +63 -0
- package/lib/node/core/game-node.js.map +1 -0
- package/lib/node/core/game-object.js +8 -0
- package/lib/node/core/game-object.js.map +1 -0
- package/lib/node/core/renderable.js +59 -0
- package/lib/node/core/renderable.js.map +1 -0
- package/lib/node/core/transform.js +70 -0
- package/lib/node/core/transform.js.map +1 -0
- package/lib/node/core/transformable.js +85 -0
- package/lib/node/core/transformable.js.map +1 -0
- package/lib/node/ext/animated-sprite.js +77 -0
- package/lib/node/ext/animated-sprite.js.map +1 -0
- package/lib/node/ext/bitmap-text.js +93 -0
- package/lib/node/ext/bitmap-text.js.map +1 -0
- package/lib/node/ext/circle.js +43 -0
- package/lib/node/ext/circle.js.map +1 -0
- package/lib/node/ext/deplay.js +22 -0
- package/lib/node/ext/deplay.js.map +1 -0
- package/lib/node/ext/dom-container.js +51 -0
- package/lib/node/ext/dom-container.js.map +1 -0
- package/lib/node/ext/interval.js +22 -0
- package/lib/node/ext/interval.js.map +1 -0
- package/lib/node/ext/particle.js +98 -0
- package/lib/node/ext/particle.js.map +1 -0
- package/lib/node/ext/rectangle.js +52 -0
- package/lib/node/ext/rectangle.js.map +1 -0
- package/lib/node/ext/spine.js +272 -0
- package/lib/node/ext/spine.js.map +1 -0
- package/lib/node/ext/sprite.js +42 -0
- package/lib/node/ext/sprite.js.map +1 -0
- package/lib/node/physics/physics-object.js +92 -0
- package/lib/node/physics/physics-object.js.map +1 -0
- package/lib/node/physics/physics-world.js +29 -0
- package/lib/node/physics/physics-world.js.map +1 -0
- package/lib/node/physics/rigidbodies.js +7 -0
- package/lib/node/physics/rigidbodies.js.map +1 -0
- package/lib/renderer/camera.js +19 -0
- package/lib/renderer/camera.js.map +1 -0
- package/lib/renderer/container-manager.js +29 -0
- package/lib/renderer/container-manager.js.map +1 -0
- package/lib/renderer/fps-display.js +18 -0
- package/lib/renderer/fps-display.js.map +1 -0
- package/lib/renderer/layer.js +12 -0
- package/lib/renderer/layer.js.map +1 -0
- package/lib/renderer/renderer.js +146 -0
- package/lib/renderer/renderer.js.map +1 -0
- package/lib/renderer/ticker.js +56 -0
- package/lib/renderer/ticker.js.map +1 -0
- package/lib/renderer/ticker.test.js +241 -0
- package/lib/renderer/ticker.test.js.map +1 -0
- package/lib/types/animation-atlas.js +2 -0
- package/lib/types/animation-atlas.js.map +1 -0
- package/lib/types/asset/audio.d.ts +5 -4
- package/lib/types/asset/audio.d.ts.map +1 -1
- package/lib/types/asset/loaders/audio.d.ts +2 -1
- package/lib/types/asset/loaders/audio.d.ts.map +1 -1
- package/lib/types/asset/loaders/binary.d.ts +2 -1
- package/lib/types/asset/loaders/binary.d.ts.map +1 -1
- package/lib/types/asset/loaders/bitmap-font.d.ts +17 -0
- package/lib/types/asset/loaders/bitmap-font.d.ts.map +1 -0
- package/lib/types/asset/loaders/font.d.ts +2 -1
- package/lib/types/asset/loaders/font.d.ts.map +1 -1
- package/lib/types/asset/loaders/loader.d.ts +6 -6
- package/lib/types/asset/loaders/loader.d.ts.map +1 -1
- package/lib/types/asset/loaders/spritesheet.d.ts +14 -6
- package/lib/types/asset/loaders/spritesheet.d.ts.map +1 -1
- package/lib/types/asset/loaders/text.d.ts +2 -1
- package/lib/types/asset/loaders/text.d.ts.map +1 -1
- package/lib/types/asset/loaders/texture.d.ts +2 -2
- package/lib/types/asset/loaders/texture.d.ts.map +1 -1
- package/lib/types/asset/preload.d.ts +7 -5
- package/lib/types/asset/preload.d.ts.map +1 -1
- package/lib/types/atlas copy.js +2 -0
- package/lib/types/atlas copy.js.map +1 -0
- package/lib/types/atlas.js +2 -0
- package/lib/types/atlas.js.map +1 -0
- package/lib/types/bitmap-font.js +2 -0
- package/lib/types/bitmap-font.js.map +1 -0
- package/lib/types/collision/check-collision.d.ts +4 -0
- package/lib/types/collision/check-collision.d.ts.map +1 -0
- package/lib/types/collision/check-collision.test.d.ts +2 -0
- package/lib/types/collision/check-collision.test.d.ts.map +1 -0
- package/lib/types/collision/colliders.d.ts +34 -0
- package/lib/types/collision/colliders.d.ts.map +1 -0
- package/lib/types/debug.d.ts.map +1 -0
- package/lib/types/dom/dom-animated-sprite.d.ts +23 -0
- package/lib/types/dom/dom-animated-sprite.d.ts.map +1 -0
- package/lib/types/dom/dom-game-object.d.ts +44 -0
- package/lib/types/dom/dom-game-object.d.ts.map +1 -0
- package/lib/types/dom/dom-particle.d.ts +30 -0
- package/lib/types/dom/dom-particle.d.ts.map +1 -0
- package/lib/types/dom/dom-preload.d.ts +2 -0
- package/lib/types/dom/dom-preload.d.ts.map +1 -0
- package/lib/types/dom/dom-sprite.d.ts +13 -0
- package/lib/types/dom/dom-sprite.d.ts.map +1 -0
- package/lib/types/dom/dom-texture-loader.d.ts +8 -0
- package/lib/types/dom/dom-texture-loader.d.ts.map +1 -0
- package/lib/types/dom/dom-utils.d.ts +3 -0
- package/lib/types/dom/dom-utils.d.ts.map +1 -0
- package/lib/types/index copy.d.ts +16 -0
- package/lib/types/index copy.d.ts.map +1 -0
- package/lib/types/index.d.ts +26 -11
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/input/joystick.d.ts +28 -0
- package/lib/types/input/joystick.d.ts.map +1 -0
- package/lib/types/node/core/dirty-number.d.ts +9 -0
- package/lib/types/node/core/dirty-number.d.ts.map +1 -0
- package/lib/types/node/core/game-node.d.ts +16 -0
- package/lib/types/node/core/game-node.d.ts.map +1 -0
- package/lib/types/node/core/game-object.d.ts +8 -0
- package/lib/types/node/core/game-object.d.ts.map +1 -0
- package/lib/types/node/core/renderable.d.ts +23 -0
- package/lib/types/node/core/renderable.d.ts.map +1 -0
- package/lib/types/node/core/transform.d.ts +27 -0
- package/lib/types/node/core/transform.d.ts.map +1 -0
- package/lib/types/node/core/transformable.d.ts +44 -0
- package/lib/types/node/core/transformable.d.ts.map +1 -0
- package/lib/types/node/ext/animated-sprite.d.ts +22 -0
- package/lib/types/node/ext/animated-sprite.d.ts.map +1 -0
- package/lib/types/node/ext/bitmap-text.d.ts +14 -0
- package/lib/types/node/ext/bitmap-text.d.ts.map +1 -0
- package/lib/types/node/ext/circle.d.ts +19 -0
- package/lib/types/node/ext/circle.d.ts.map +1 -0
- package/lib/types/node/ext/deplay.d.ts +8 -0
- package/lib/types/node/ext/deplay.d.ts.map +1 -0
- package/lib/types/node/ext/dom-container.d.ts +12 -0
- package/lib/types/node/ext/dom-container.d.ts.map +1 -0
- package/lib/types/node/ext/interval.d.ts +9 -0
- package/lib/types/node/ext/interval.d.ts.map +1 -0
- package/lib/types/node/ext/particle.d.ts +30 -0
- package/lib/types/node/ext/particle.d.ts.map +1 -0
- package/lib/types/node/ext/rectangle.d.ts +22 -0
- package/lib/types/node/ext/rectangle.d.ts.map +1 -0
- package/lib/types/node/ext/spine.d.ts +36 -0
- package/lib/types/node/ext/spine.d.ts.map +1 -0
- package/lib/types/node/ext/sprite.d.ts +13 -0
- package/lib/types/node/ext/sprite.d.ts.map +1 -0
- package/lib/types/node/physics/physics-object.d.ts +38 -0
- package/lib/types/node/physics/physics-object.d.ts.map +1 -0
- package/lib/types/node/physics/physics-world.d.ts +18 -0
- package/lib/types/node/physics/physics-world.d.ts.map +1 -0
- package/lib/types/node/physics/rigidbodies.d.ts +23 -0
- package/lib/types/node/physics/rigidbodies.d.ts.map +1 -0
- package/lib/types/renderer/camera.d.ts +13 -0
- package/lib/types/renderer/camera.d.ts.map +1 -0
- package/lib/types/renderer/container-manager.d.ts +9 -0
- package/lib/types/renderer/container-manager.d.ts.map +1 -0
- package/lib/types/renderer/fps-display.d.ts +7 -0
- package/lib/types/renderer/fps-display.d.ts.map +1 -0
- package/lib/types/renderer/layer.d.ts +7 -0
- package/lib/types/renderer/layer.d.ts.map +1 -0
- package/lib/types/renderer/renderer.d.ts +40 -0
- package/lib/types/renderer/renderer.d.ts.map +1 -0
- package/lib/types/renderer/ticker.d.ts +6 -0
- package/lib/types/renderer/ticker.d.ts.map +1 -0
- package/lib/types/renderer/ticker.test.d.ts +40 -0
- package/lib/types/renderer/ticker.test.d.ts.map +1 -0
- package/lib/types/sprite-atlas.js +2 -0
- package/lib/types/sprite-atlas.js.map +1 -0
- package/lib/types/types/animation-atlas.d.ts +14 -0
- package/lib/types/types/animation-atlas.d.ts.map +1 -0
- package/lib/types/types/atlas copy.d.ts +12 -0
- package/lib/types/types/atlas copy.d.ts.map +1 -0
- package/lib/types/types/atlas.d.ts +16 -0
- package/lib/types/types/atlas.d.ts.map +1 -0
- package/lib/types/types/bitmap-font.d.ts +18 -0
- package/lib/types/types/bitmap-font.d.ts.map +1 -0
- package/lib/types/types/sprite-atlas.d.ts +13 -0
- package/lib/types/types/sprite-atlas.d.ts.map +1 -0
- package/lib/types/utils/device.d.ts +2 -0
- package/lib/types/utils/device.d.ts.map +1 -0
- package/lib/utils/device.js +2 -0
- package/lib/utils/device.js.map +1 -0
- package/package.json +8 -7
- package/src/asset/audio.ts +134 -90
- package/src/asset/loaders/audio.ts +23 -20
- package/src/asset/loaders/binary.ts +20 -16
- package/src/asset/loaders/bitmap-font.ts +91 -0
- package/src/asset/loaders/font.ts +18 -14
- package/src/asset/loaders/loader.ts +27 -23
- package/src/asset/loaders/spritesheet.ts +47 -36
- package/src/asset/loaders/text.ts +19 -15
- package/src/asset/loaders/texture.ts +30 -37
- package/src/asset/preload.ts +71 -64
- package/src/collision/check-collision.test.ts +349 -0
- package/src/collision/check-collision.ts +821 -0
- package/src/collision/colliders.ts +19 -0
- package/src/debug.ts +5 -0
- package/src/dom/dom-animated-sprite.ts +132 -0
- package/src/dom/dom-game-object.ts +134 -0
- package/src/dom/dom-particle.ts +151 -0
- package/src/dom/dom-preload.ts +54 -0
- package/src/dom/dom-sprite.ts +50 -0
- package/src/dom/dom-texture-loader.ts +44 -0
- package/src/dom/dom-utils.ts +19 -0
- package/src/index.ts +47 -13
- package/src/input/joystick.ts +316 -0
- package/src/node/core/dirty-number.ts +21 -0
- package/src/node/core/game-node.ts +74 -0
- package/src/node/core/game-object.ts +11 -0
- package/src/node/core/renderable.ts +72 -0
- package/src/node/core/transform.ts +82 -0
- package/src/node/core/transformable.ts +111 -0
- package/src/node/ext/animated-sprite.ts +103 -0
- package/src/node/ext/bitmap-text.ts +113 -0
- package/src/node/ext/circle.ts +55 -0
- package/src/node/ext/deplay.ts +25 -0
- package/src/node/ext/dom-container.ts +62 -0
- package/src/node/ext/interval.ts +25 -0
- package/src/node/ext/particle.ts +142 -0
- package/src/node/ext/rectangle.ts +71 -0
- package/src/node/ext/spine.ts +323 -0
- package/src/node/ext/sprite.ts +53 -0
- package/src/node/physics/physics-object.ts +127 -0
- package/src/node/physics/physics-world.ts +41 -0
- package/src/node/physics/rigidbodies.ts +14 -0
- package/src/renderer/camera.ts +25 -0
- package/src/renderer/container-manager.ts +36 -0
- package/src/renderer/fps-display.ts +21 -0
- package/src/renderer/layer.ts +15 -0
- package/src/renderer/renderer.ts +181 -0
- package/src/renderer/ticker.test.ts +325 -0
- package/src/renderer/ticker.ts +54 -0
- package/src/types/atlas.ts +17 -0
- package/src/types/bitmap-font.ts +19 -0
- package/src/utils/device.ts +1 -0
- package/examples/test-dom/index.ts +0 -21
- package/lib/game-object/game-object-physics.js +0 -188
- package/lib/game-object/game-object-physics.js.map +0 -1
- package/lib/game-object/game-object-rendering.js +0 -35
- package/lib/game-object/game-object-rendering.js.map +0 -1
- package/lib/game-object/game-object.js +0 -162
- package/lib/game-object/game-object.js.map +0 -1
- package/lib/game-object/transform.js +0 -118
- package/lib/game-object/transform.js.map +0 -1
- package/lib/game-object-ext/animated-sprite.js +0 -117
- package/lib/game-object-ext/animated-sprite.js.map +0 -1
- package/lib/game-object-ext/dom-container.js +0 -56
- package/lib/game-object-ext/dom-container.js.map +0 -1
- package/lib/game-object-ext/rect.js +0 -30
- package/lib/game-object-ext/rect.js.map +0 -1
- package/lib/game-object-ext/spine.js +0 -206
- package/lib/game-object-ext/spine.js.map +0 -1
- package/lib/game-object-ext/sprite.js +0 -46
- package/lib/game-object-ext/sprite.js.map +0 -1
- package/lib/game-object-ext/text.js +0 -68
- package/lib/game-object-ext/text.js.map +0 -1
- package/lib/game-object-ext/tiling-sprite.js +0 -64
- package/lib/game-object-ext/tiling-sprite.js.map +0 -1
- package/lib/types/game-object/game-object-physics.d.ts +0 -42
- package/lib/types/game-object/game-object-physics.d.ts.map +0 -1
- package/lib/types/game-object/game-object-rendering.d.ts +0 -15
- package/lib/types/game-object/game-object-rendering.d.ts.map +0 -1
- package/lib/types/game-object/game-object.d.ts +0 -81
- package/lib/types/game-object/game-object.d.ts.map +0 -1
- package/lib/types/game-object/transform.d.ts +0 -43
- package/lib/types/game-object/transform.d.ts.map +0 -1
- package/lib/types/game-object-ext/animated-sprite.d.ts +0 -29
- package/lib/types/game-object-ext/animated-sprite.d.ts.map +0 -1
- package/lib/types/game-object-ext/dom-container.d.ts +0 -16
- package/lib/types/game-object-ext/dom-container.d.ts.map +0 -1
- package/lib/types/game-object-ext/rect.d.ts +0 -17
- package/lib/types/game-object-ext/rect.d.ts.map +0 -1
- package/lib/types/game-object-ext/spine.d.ts +0 -35
- package/lib/types/game-object-ext/spine.d.ts.map +0 -1
- package/lib/types/game-object-ext/sprite.d.ts +0 -14
- package/lib/types/game-object-ext/sprite.d.ts.map +0 -1
- package/lib/types/game-object-ext/text.d.ts +0 -26
- package/lib/types/game-object-ext/text.d.ts.map +0 -1
- package/lib/types/game-object-ext/tiling-sprite.d.ts +0 -20
- package/lib/types/game-object-ext/tiling-sprite.d.ts.map +0 -1
- package/lib/types/utils/debug.d.ts.map +0 -1
- package/lib/types/utils/go.d.ts +0 -26
- package/lib/types/utils/go.d.ts.map +0 -1
- package/lib/types/world/world-debug.d.ts +0 -11
- package/lib/types/world/world-debug.d.ts.map +0 -1
- package/lib/types/world/world-physics.d.ts +0 -16
- package/lib/types/world/world-physics.d.ts.map +0 -1
- package/lib/types/world/world-rendering.d.ts +0 -28
- package/lib/types/world/world-rendering.d.ts.map +0 -1
- package/lib/types/world/world.d.ts +0 -38
- package/lib/types/world/world.d.ts.map +0 -1
- package/lib/utils/debug.js.map +0 -1
- package/lib/utils/go.js +0 -33
- package/lib/utils/go.js.map +0 -1
- package/lib/world/world-debug.js +0 -89
- package/lib/world/world-debug.js.map +0 -1
- package/lib/world/world-physics.js +0 -45
- package/lib/world/world-physics.js.map +0 -1
- package/lib/world/world-rendering.js +0 -123
- package/lib/world/world-rendering.js.map +0 -1
- package/lib/world/world.js +0 -147
- package/lib/world/world.js.map +0 -1
- package/src/game-object/game-object-physics.ts +0 -191
- package/src/game-object/game-object-rendering.ts +0 -27
- package/src/game-object/game-object.ts +0 -190
- package/src/game-object/transform.ts +0 -164
- package/src/game-object-ext/animated-sprite.ts +0 -140
- package/src/game-object-ext/dom-container.ts +0 -67
- package/src/game-object-ext/rect.ts +0 -40
- package/src/game-object-ext/spine.ts +0 -235
- package/src/game-object-ext/sprite.ts +0 -55
- package/src/game-object-ext/text.ts +0 -83
- package/src/game-object-ext/tiling-sprite.ts +0 -73
- package/src/utils/debug.ts +0 -5
- package/src/utils/go.ts +0 -53
- package/src/world/world-debug.ts +0 -114
- package/src/world/world-physics.ts +0 -52
- package/src/world/world-rendering.ts +0 -145
- package/src/world/world.ts +0 -171
- /package/examples/{test-dom → auto-battle}/index.html +0 -0
- /package/lib/{utils/debug.js → debug.js} +0 -0
- /package/lib/types/{utils/debug.d.ts → debug.d.ts} +0 -0
|
@@ -0,0 +1,821 @@
|
|
|
1
|
+
import { WorldTransform } from '../node/core/transform'
|
|
2
|
+
import { CircleCollider, Collider, ColliderType, EllipseCollider, PolygonCollider, RectangleCollider } from './colliders'
|
|
3
|
+
|
|
4
|
+
// =====================================================================================
|
|
5
|
+
// Utilities (scalar-only, no allocations at runtime)
|
|
6
|
+
// =====================================================================================
|
|
7
|
+
|
|
8
|
+
const abs = (v: number) => (v < 0 ? -v : v)
|
|
9
|
+
|
|
10
|
+
// =====================================================================================
|
|
11
|
+
// OBB helpers (scalar-only)
|
|
12
|
+
// =====================================================================================
|
|
13
|
+
|
|
14
|
+
function obbRadiusOnAxis(
|
|
15
|
+
Lx: number, Ly: number,
|
|
16
|
+
ux: number, uy: number, vx: number, vy: number, hx: number, hy: number
|
|
17
|
+
) {
|
|
18
|
+
// hx, hy must be >= 0; project axis onto OBB's local axes and scale by half extents.
|
|
19
|
+
const Lu = Lx * ux + Ly * uy
|
|
20
|
+
const Lv = Lx * vx + Ly * vy
|
|
21
|
+
const a = hx * (Lu < 0 ? -Lu : Lu)
|
|
22
|
+
const b = hy * (Lv < 0 ? -Lv : Lv)
|
|
23
|
+
return a + b
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function axisSeparates(
|
|
27
|
+
Lx: number, Ly: number, dx: number, dy: number,
|
|
28
|
+
aux: number, auy: number, avx: number, avy: number, ahx: number, ahy: number,
|
|
29
|
+
bux: number, buy: number, bvx: number, bvy: number, bhx: number, bhy: number
|
|
30
|
+
) {
|
|
31
|
+
const dist = dx * Lx + dy * Ly
|
|
32
|
+
const ad = dist < 0 ? -dist : dist
|
|
33
|
+
const rA = obbRadiusOnAxis(Lx, Ly, aux, auy, avx, avy, ahx, ahy)
|
|
34
|
+
const rB = obbRadiusOnAxis(Lx, Ly, bux, buy, bvx, bvy, bhx, bhy)
|
|
35
|
+
return ad > (rA + rB)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// =====================================================================================
|
|
39
|
+
// Rectangle–Rectangle (OBB–OBB) — SAT with 4 axes (no allocations)
|
|
40
|
+
// =====================================================================================
|
|
41
|
+
|
|
42
|
+
function checkRectRectCollision(
|
|
43
|
+
ca: RectangleCollider, ta: WorldTransform,
|
|
44
|
+
cb: RectangleCollider, tb: WorldTransform
|
|
45
|
+
): boolean {
|
|
46
|
+
// A frame (half extents must be non-negative)
|
|
47
|
+
const asx = ta.scaleX.v, asy = ta.scaleY.v
|
|
48
|
+
const ahx = abs(ca.width * asx) * 0.5
|
|
49
|
+
const ahy = abs(ca.height * asy) * 0.5
|
|
50
|
+
const cA = ta.cos, sA = ta.sin
|
|
51
|
+
const aux = cA, auy = sA
|
|
52
|
+
const avx = -sA, avy = cA
|
|
53
|
+
// apply rotated local offset for center
|
|
54
|
+
const aox = (ca.x || 0) * asx
|
|
55
|
+
const aoy = (ca.y || 0) * asy
|
|
56
|
+
const ax = ta.x.v + aux * aox + avx * aoy
|
|
57
|
+
const ay = ta.y.v + auy * aox + avy * aoy
|
|
58
|
+
|
|
59
|
+
// B frame
|
|
60
|
+
const bsx = tb.scaleX.v, bsy = tb.scaleY.v
|
|
61
|
+
const bhx = abs(cb.width * bsx) * 0.5
|
|
62
|
+
const bhy = abs(cb.height * bsy) * 0.5
|
|
63
|
+
const cB = tb.cos, sB = tb.sin
|
|
64
|
+
const bux = cB, buy = sB
|
|
65
|
+
const bvx = -sB, bvy = cB
|
|
66
|
+
const box = (cb.x || 0) * bsx
|
|
67
|
+
const boy = (cb.y || 0) * bsy
|
|
68
|
+
const bx = tb.x.v + bux * box + bvx * boy
|
|
69
|
+
const by = tb.y.v + buy * box + bvy * boy
|
|
70
|
+
|
|
71
|
+
// Fast axis-aligned branch if both rotations are zero
|
|
72
|
+
const rotA = ta.rotation.v, rotB = tb.rotation.v
|
|
73
|
+
if ((rotA === 0 || rotA === 0.0) && (rotB === 0 || rotB === 0.0)) {
|
|
74
|
+
const dx0 = bx - ax; const adx0 = dx0 < 0 ? -dx0 : dx0
|
|
75
|
+
const dy0 = by - ay; const ady0 = dy0 < 0 ? -dy0 : dy0
|
|
76
|
+
return (adx0 <= ahx + bhx) && (ady0 <= ahy + bhy)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const dx = bx - ax
|
|
80
|
+
const dy = by - ay
|
|
81
|
+
|
|
82
|
+
if (axisSeparates(aux, auy, dx, dy, aux, auy, avx, avy, ahx, ahy, bux, buy, bvx, bvy, bhx, bhy)) return false
|
|
83
|
+
if (axisSeparates(avx, avy, dx, dy, aux, auy, avx, avy, ahx, ahy, bux, buy, bvx, bvy, bhx, bhy)) return false
|
|
84
|
+
if (axisSeparates(bux, buy, dx, dy, aux, auy, avx, avy, ahx, ahy, bux, buy, bvx, bvy, bhx, bhy)) return false
|
|
85
|
+
if (axisSeparates(bvx, bvy, dx, dy, aux, auy, avx, avy, ahx, ahy, bux, buy, bvx, bvy, bhx, bhy)) return false
|
|
86
|
+
|
|
87
|
+
return true
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// =====================================================================================
|
|
91
|
+
// Circle tools (no allocations)
|
|
92
|
+
// =====================================================================================
|
|
93
|
+
|
|
94
|
+
// scratch for circle center computations (reused everywhere; no runtime object creation)
|
|
95
|
+
let _ccx = 0, _ccy = 0
|
|
96
|
+
|
|
97
|
+
// Writes the world-space center into (_ccx, _ccy).
|
|
98
|
+
function circleCenterScratch(c: CircleCollider, t: WorldTransform): void {
|
|
99
|
+
// No object/array allocation; scalar math only
|
|
100
|
+
const sx = t.scaleX.v, sy = t.scaleY.v
|
|
101
|
+
const cos = t.cos, sin = t.sin
|
|
102
|
+
// local axes
|
|
103
|
+
const ux = cos, uy = sin
|
|
104
|
+
const vx = -sin, vy = cos
|
|
105
|
+
// scaled local offset
|
|
106
|
+
const ox = (c.x || 0) * sx
|
|
107
|
+
const oy = (c.y || 0) * sy
|
|
108
|
+
_ccx = t.x.v + ux * ox + vx * oy
|
|
109
|
+
_ccy = t.y.v + uy * ox + vy * oy
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function circleScaledRadius(c: CircleCollider, t: WorldTransform) {
|
|
113
|
+
const sx = abs(t.scaleX.v), sy = abs(t.scaleY.v)
|
|
114
|
+
return c.radius * (sx > sy ? sx : sy) // conservative
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function checkCircleCircleCollision(
|
|
118
|
+
ca: CircleCollider, ta: WorldTransform, cb: CircleCollider, tb: WorldTransform
|
|
119
|
+
): boolean {
|
|
120
|
+
circleCenterScratch(ca, ta); const ax = _ccx, ay = _ccy
|
|
121
|
+
circleCenterScratch(cb, tb); const bx = _ccx, by = _ccy
|
|
122
|
+
const ra = circleScaledRadius(ca, ta)
|
|
123
|
+
const rb = circleScaledRadius(cb, tb)
|
|
124
|
+
const dx = bx - ax, dy = by - ay
|
|
125
|
+
const r = ra + rb
|
|
126
|
+
return (dx * dx + dy * dy) <= r * r
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// =====================================================================================
|
|
130
|
+
// Rect–Circle (no allocations)
|
|
131
|
+
// =====================================================================================
|
|
132
|
+
|
|
133
|
+
function checkRectCircleCollision(
|
|
134
|
+
r: RectangleCollider, tr: WorldTransform,
|
|
135
|
+
c: CircleCollider, tc: WorldTransform
|
|
136
|
+
): boolean {
|
|
137
|
+
// Rect frame
|
|
138
|
+
const rsx = tr.scaleX.v, rsy = tr.scaleY.v
|
|
139
|
+
const rhx = abs(r.width * rsx) * 0.5
|
|
140
|
+
const rhy = abs(r.height * rsy) * 0.5
|
|
141
|
+
const rc = tr.cos, rs = tr.sin
|
|
142
|
+
const rux = rc, ruy = rs
|
|
143
|
+
const rvx = -rs, rvy = rc
|
|
144
|
+
const rox = (r.x || 0) * rsx
|
|
145
|
+
const roy = (r.y || 0) * rsy
|
|
146
|
+
const rcx = tr.x.v + rux * rox + rvx * roy
|
|
147
|
+
const rcy = tr.y.v + ruy * rox + rvy * roy
|
|
148
|
+
|
|
149
|
+
// Circle center + radius (into scratch scalars)
|
|
150
|
+
circleCenterScratch(c, tc)
|
|
151
|
+
const rr = circleScaledRadius(c, tc)
|
|
152
|
+
|
|
153
|
+
// Project center delta onto rect local axes and clamp
|
|
154
|
+
const dx = _ccx - rcx, dy = _ccy - rcy
|
|
155
|
+
const qx = dx * rux + dy * ruy
|
|
156
|
+
const qy = dx * rvx + dy * rvy
|
|
157
|
+
const clx = qx < -rhx ? -rhx : (qx > rhx ? rhx : qx)
|
|
158
|
+
const cly = qy < -rhy ? -rhy : (qy > rhy ? rhy : qy)
|
|
159
|
+
const ddx = qx - clx
|
|
160
|
+
const ddy = qy - cly
|
|
161
|
+
return (ddx * ddx + ddy * ddy) <= rr * rr
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// =====================================================================================
|
|
165
|
+
// Polygon helpers — SAT (no allocations; polygons are in LOCAL space + Transform)
|
|
166
|
+
// =====================================================================================
|
|
167
|
+
|
|
168
|
+
/*
|
|
169
|
+
Notes:
|
|
170
|
+
- Polygons are stored in LOCAL space. We never allocate world-space copies.
|
|
171
|
+
- For any world axis N = (nx, ny), projection of a local vertex (vx, vy) is:
|
|
172
|
+
dot(N, C) + dot(N, U)*sx*vx + dot(N, V)*sy*vy
|
|
173
|
+
where C is world center, U/V are world unit axes of the polygon frame,
|
|
174
|
+
and sx/sy are scale on those local axes.
|
|
175
|
+
- No objects/arrays are created at runtime. Only scalar computations and loops.
|
|
176
|
+
*/
|
|
177
|
+
|
|
178
|
+
// Poly–Poly (LOCAL + Transform)
|
|
179
|
+
function checkPolyPolyCollision(
|
|
180
|
+
a: PolygonCollider, ta: WorldTransform,
|
|
181
|
+
b: PolygonCollider, tb: WorldTransform
|
|
182
|
+
): boolean {
|
|
183
|
+
const av = a.vertices, bv = b.vertices
|
|
184
|
+
const na = av.length, nb = bv.length
|
|
185
|
+
if (na === 0 || nb === 0) return false
|
|
186
|
+
|
|
187
|
+
// Frame A
|
|
188
|
+
const asx = ta.scaleX.v, asy = ta.scaleY.v
|
|
189
|
+
const acs = ta.cos, asn = ta.sin
|
|
190
|
+
const aux = acs, auy = asn
|
|
191
|
+
const avx = -asn, avy = acs
|
|
192
|
+
const aox = ((a as any).x || 0) * asx
|
|
193
|
+
const aoy = ((a as any).y || 0) * asy
|
|
194
|
+
const acx = ta.x.v + aux * aox + avx * aoy
|
|
195
|
+
const acy = ta.y.v + auy * aox + avy * aoy
|
|
196
|
+
|
|
197
|
+
// Frame B
|
|
198
|
+
const bsx = tb.scaleX.v, bsy = tb.scaleY.v
|
|
199
|
+
const bcs = tb.cos, bsn = tb.sin
|
|
200
|
+
const bux = bcs, buy = bsn
|
|
201
|
+
const bvx = -bsn, bvy = bcs
|
|
202
|
+
const box = ((b as any).x || 0) * bsx
|
|
203
|
+
const boy = ((b as any).y || 0) * bsy
|
|
204
|
+
const bcx = tb.x.v + bux * box + bvx * boy
|
|
205
|
+
const bcy = tb.y.v + buy * box + bvy * boy
|
|
206
|
+
|
|
207
|
+
let i = 0, j = 0, k = 0
|
|
208
|
+
|
|
209
|
+
// A's edge axes
|
|
210
|
+
for (i = 0; i < na; i++) {
|
|
211
|
+
j = (i + 1) % na
|
|
212
|
+
const adx = av[j].x - av[i].x
|
|
213
|
+
const ady = av[j].y - av[i].y
|
|
214
|
+
// edge in world: Ew = U*(sx*dx) + V*(sy*dy)
|
|
215
|
+
const ewx = aux * (asx * adx) + avx * (asy * ady)
|
|
216
|
+
const ewy = auy * (asx * adx) + avy * (asy * ady)
|
|
217
|
+
const nx = -ewy, ny = ewx // world normal (no normalization)
|
|
218
|
+
|
|
219
|
+
// project A on (nx,ny)
|
|
220
|
+
const kUa = (nx * aux + ny * auy) * asx
|
|
221
|
+
const kVa = (nx * avx + ny * avy) * asy
|
|
222
|
+
const baseA = nx * acx + ny * acy
|
|
223
|
+
let minA = Infinity, maxA = -Infinity
|
|
224
|
+
for (k = 0; k < na; k++) {
|
|
225
|
+
const s = baseA + kUa * av[k].x + kVa * av[k].y
|
|
226
|
+
if (s < minA) minA = s
|
|
227
|
+
if (s > maxA) maxA = s
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// project B on (nx,ny)
|
|
231
|
+
const kUb = (nx * bux + ny * buy) * bsx
|
|
232
|
+
const kVb = (nx * bvx + ny * bvy) * bsy
|
|
233
|
+
const baseB = nx * bcx + ny * bcy
|
|
234
|
+
let minB = Infinity, maxB = -Infinity
|
|
235
|
+
for (k = 0; k < nb; k++) {
|
|
236
|
+
const s = baseB + kUb * bv[k].x + kVb * bv[k].y
|
|
237
|
+
if (s < minB) minB = s
|
|
238
|
+
if (s > maxB) maxB = s
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (maxA < minB || maxB < minA) return false
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// B's edge axes
|
|
245
|
+
for (i = 0; i < nb; i++) {
|
|
246
|
+
j = (i + 1) % nb
|
|
247
|
+
const bdx = bv[j].x - bv[i].x
|
|
248
|
+
const bdy = bv[j].y - bv[i].y
|
|
249
|
+
const ewx = bux * (bsx * bdx) + bvx * (bsy * bdy)
|
|
250
|
+
const ewy = buy * (bsx * bdx) + bvy * (bsy * bdy)
|
|
251
|
+
const nx = -ewy, ny = ewx
|
|
252
|
+
|
|
253
|
+
// project A
|
|
254
|
+
const kUa = (nx * aux + ny * auy) * asx
|
|
255
|
+
const kVa = (nx * avx + ny * avy) * asy
|
|
256
|
+
const baseA = nx * acx + ny * acy
|
|
257
|
+
let minA = Infinity, maxA = -Infinity
|
|
258
|
+
for (k = 0; k < na; k++) {
|
|
259
|
+
const s = baseA + kUa * av[k].x + kVa * av[k].y
|
|
260
|
+
if (s < minA) minA = s
|
|
261
|
+
if (s > maxA) maxA = s
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// project B
|
|
265
|
+
const kUb = (nx * bux + ny * buy) * bsx
|
|
266
|
+
const kVb = (nx * bvx + ny * bvy) * bsy
|
|
267
|
+
const baseB = nx * bcx + ny * bcy
|
|
268
|
+
let minB = Infinity, maxB = -Infinity
|
|
269
|
+
for (k = 0; k < nb; k++) {
|
|
270
|
+
const s = baseB + kUb * bv[k].x + kVb * bv[k].y
|
|
271
|
+
if (s < minB) minB = s
|
|
272
|
+
if (s > maxB) maxB = s
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (maxA < minB || maxB < minA) return false
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return true
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Poly–Circle (LOCAL + Transform)
|
|
282
|
+
function checkPolyCircleCollision(poly: PolygonCollider, tp: WorldTransform, c: CircleCollider, tc: WorldTransform): boolean {
|
|
283
|
+
const v = poly.vertices; const n = v.length; if (n === 0) return false
|
|
284
|
+
|
|
285
|
+
// Poly frame
|
|
286
|
+
const psx = tp.scaleX.v, psy = tp.scaleY.v
|
|
287
|
+
const pcs = tp.cos, psn = tp.sin
|
|
288
|
+
const pux = pcs, puy = psn
|
|
289
|
+
const pvx = -psn, pvy = pcs
|
|
290
|
+
const pox = ((poly as any).x || 0) * psx
|
|
291
|
+
const poy = ((poly as any).y || 0) * psy
|
|
292
|
+
const pcx = tp.x.v + pux * pox + pvx * poy
|
|
293
|
+
const pcy = tp.y.v + puy * pox + pvy * poy
|
|
294
|
+
|
|
295
|
+
// Circle center + radius
|
|
296
|
+
circleCenterScratch(c, tc)
|
|
297
|
+
const CCx = _ccx, CCy = _ccy
|
|
298
|
+
const rr = circleScaledRadius(c, tc)
|
|
299
|
+
|
|
300
|
+
let i = 0, j = 0, k = 0
|
|
301
|
+
|
|
302
|
+
// (A) Polygon edge axes
|
|
303
|
+
for (i = 0; i < n; i++) {
|
|
304
|
+
j = (i + 1) % n
|
|
305
|
+
const dx = v[j].x - v[i].x
|
|
306
|
+
const dy = v[j].y - v[i].y
|
|
307
|
+
const ewx = pux * (psx * dx) + pvx * (psy * dy)
|
|
308
|
+
const ewy = puy * (psx * dx) + pvy * (psy * dy)
|
|
309
|
+
const nx = -ewy, ny = ewx
|
|
310
|
+
const kUp = (nx * pux + ny * puy) * psx
|
|
311
|
+
const kVp = (nx * pvx + ny * pvy) * psy
|
|
312
|
+
const baseP = nx * pcx + ny * pcy
|
|
313
|
+
let minP = Infinity, maxP = -Infinity
|
|
314
|
+
for (k = 0; k < n; k++) {
|
|
315
|
+
const s = baseP + kUp * v[k].x + kVp * v[k].y
|
|
316
|
+
if (s < minP) minP = s
|
|
317
|
+
if (s > maxP) maxP = s
|
|
318
|
+
}
|
|
319
|
+
const nlen = Math.hypot(nx, ny)
|
|
320
|
+
const cProj = nx * CCx + ny * CCy
|
|
321
|
+
const minC = cProj - rr * nlen
|
|
322
|
+
const maxC = cProj + rr * nlen
|
|
323
|
+
if (maxP < minC || maxC < minP) return false
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// (B) Closest-vertex axis
|
|
327
|
+
let bestDx = 0, bestDy = 0, bestD2 = Infinity
|
|
328
|
+
for (i = 0; i < n; i++) {
|
|
329
|
+
const wx = pcx + pux * (psx * v[i].x) + pvx * (psy * v[i].y)
|
|
330
|
+
const wy = pcy + puy * (psx * v[i].x) + pvy * (psy * v[i].y)
|
|
331
|
+
const dx = CCx - wx
|
|
332
|
+
const dy = CCy - wy
|
|
333
|
+
const d2 = dx * dx + dy * dy
|
|
334
|
+
if (d2 < bestD2) { bestD2 = d2; bestDx = dx; bestDy = dy }
|
|
335
|
+
}
|
|
336
|
+
if (bestD2 === 0) return true
|
|
337
|
+
{
|
|
338
|
+
const nx = bestDx, ny = bestDy
|
|
339
|
+
const kUp = (nx * pux + ny * puy) * psx
|
|
340
|
+
const kVp = (nx * pvx + ny * pvy) * psy
|
|
341
|
+
const baseP = nx * pcx + ny * pcy
|
|
342
|
+
let minP = Infinity, maxP = -Infinity
|
|
343
|
+
for (i = 0; i < n; i++) {
|
|
344
|
+
const s = baseP + kUp * v[i].x + kVp * v[i].y
|
|
345
|
+
if (s < minP) minP = s
|
|
346
|
+
if (s > maxP) maxP = s
|
|
347
|
+
}
|
|
348
|
+
const nlen = Math.hypot(nx, ny)
|
|
349
|
+
const cProj = nx * CCx + ny * CCy
|
|
350
|
+
const minC = cProj - rr * nlen
|
|
351
|
+
const maxC = cProj + rr * nlen
|
|
352
|
+
if (maxP < minC || maxC < minP) return false
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return true
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Poly–Rect (LOCAL + Transform)
|
|
359
|
+
function checkPolyRectCollision(poly: PolygonCollider, tp: WorldTransform, r: RectangleCollider, tr: WorldTransform): boolean {
|
|
360
|
+
const v = poly.vertices; const n = v.length; if (n === 0) return false
|
|
361
|
+
|
|
362
|
+
// Poly frame
|
|
363
|
+
const psx = tp.scaleX.v, psy = tp.scaleY.v
|
|
364
|
+
const pcs = tp.cos, psn = tp.sin
|
|
365
|
+
const pux = pcs, puy = psn
|
|
366
|
+
const pvx = -psn, pvy = pcs
|
|
367
|
+
const pox = ((poly as any).x || 0) * psx
|
|
368
|
+
const poy = ((poly as any).y || 0) * psy
|
|
369
|
+
const pcx = tp.x.v + pux * pox + pvx * poy
|
|
370
|
+
const pcy = tp.y.v + puy * pox + pvy * poy
|
|
371
|
+
|
|
372
|
+
// Rect frame
|
|
373
|
+
const rsx = tr.scaleX.v, rsy = tr.scaleY.v
|
|
374
|
+
const rhx = abs(r.width * rsx) * 0.5
|
|
375
|
+
const rhy = abs(r.height * rsy) * 0.5
|
|
376
|
+
const rc = tr.cos, rs = tr.sin
|
|
377
|
+
const rux = rc, ruy = rs
|
|
378
|
+
const rvx = -rs, rvy = rc
|
|
379
|
+
const rox = (r.x || 0) * rsx, roy = (r.y || 0) * rsy
|
|
380
|
+
const rcx = tr.x.v + rux * rox + rvx * roy
|
|
381
|
+
const rcy = tr.y.v + ruy * rox + rvy * roy
|
|
382
|
+
|
|
383
|
+
let i = 0, j = 0, k = 0
|
|
384
|
+
|
|
385
|
+
// (A) polygon edge axes
|
|
386
|
+
for (i = 0; i < n; i++) {
|
|
387
|
+
j = (i + 1) % n
|
|
388
|
+
const dx = v[j].x - v[i].x
|
|
389
|
+
const dy = v[j].y - v[i].y
|
|
390
|
+
const ewx = pux * (psx * dx) + pvx * (psy * dy)
|
|
391
|
+
const ewy = puy * (psx * dx) + pvy * (psy * dy)
|
|
392
|
+
const nx = -ewy, ny = ewx
|
|
393
|
+
|
|
394
|
+
// poly projection
|
|
395
|
+
const kUp = (nx * pux + ny * puy) * psx
|
|
396
|
+
const kVp = (nx * pvx + ny * pvy) * psy
|
|
397
|
+
const baseP = nx * pcx + ny * pcy
|
|
398
|
+
let minP = Infinity, maxP = -Infinity
|
|
399
|
+
for (k = 0; k < n; k++) {
|
|
400
|
+
const s = baseP + kUp * v[k].x + kVp * v[k].y
|
|
401
|
+
if (s < minP) minP = s
|
|
402
|
+
if (s > maxP) maxP = s
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// rect projection radius on axis
|
|
406
|
+
const nu = nx * rux + ny * ruy
|
|
407
|
+
const nv = nx * rvx + ny * rvy
|
|
408
|
+
const rRad = rhx * (nu < 0 ? -nu : nu) + rhy * (nv < 0 ? -nv : nv)
|
|
409
|
+
const cProj = nx * rcx + ny * rcy
|
|
410
|
+
const minR = cProj - rRad
|
|
411
|
+
const maxR = cProj + rRad
|
|
412
|
+
if (maxP < minR || maxR < minP) return false
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// (B) rect axis u
|
|
416
|
+
{
|
|
417
|
+
const nx = rux, ny = ruy
|
|
418
|
+
const kUp = (nx * pux + ny * puy) * psx
|
|
419
|
+
const kVp = (nx * pvx + ny * pvy) * psy
|
|
420
|
+
const baseP = nx * pcx + ny * pcy
|
|
421
|
+
let minP = Infinity, maxP = -Infinity
|
|
422
|
+
for (i = 0; i < n; i++) {
|
|
423
|
+
const s = baseP + kUp * v[i].x + kVp * v[i].y
|
|
424
|
+
if (s < minP) minP = s
|
|
425
|
+
if (s > maxP) maxP = s
|
|
426
|
+
}
|
|
427
|
+
const cProj = nx * rcx + ny * rcy
|
|
428
|
+
const minR = cProj - rhx
|
|
429
|
+
const maxR = cProj + rhx
|
|
430
|
+
if (maxP < minR || maxR < minP) return false
|
|
431
|
+
}
|
|
432
|
+
// (C) rect axis v
|
|
433
|
+
{
|
|
434
|
+
const nx = rvx, ny = rvy
|
|
435
|
+
const kUp = (nx * pux + ny * puy) * psx
|
|
436
|
+
const kVp = (nx * pvx + ny * pvy) * psy
|
|
437
|
+
const baseP = nx * pcx + ny * pcy
|
|
438
|
+
let minP = Infinity, maxP = -Infinity
|
|
439
|
+
for (i = 0; i < n; i++) {
|
|
440
|
+
const s = baseP + kUp * v[i].x + kVp * v[i].y
|
|
441
|
+
if (s < minP) minP = s
|
|
442
|
+
if (s > maxP) maxP = s
|
|
443
|
+
}
|
|
444
|
+
const cProj = nx * rcx + ny * rcy
|
|
445
|
+
const minR = cProj - rhy
|
|
446
|
+
const maxR = cProj + rhy
|
|
447
|
+
if (maxP < minR || maxR < minP) return false
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
return true
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// =====================================================================================
|
|
454
|
+
// GJK (no allocations: global scratch + selectable supports) — FIXED/ROBUST
|
|
455
|
+
// =====================================================================================
|
|
456
|
+
|
|
457
|
+
// Global scratch for support result
|
|
458
|
+
let _sx = 0, _sy = 0
|
|
459
|
+
|
|
460
|
+
// Support selectors
|
|
461
|
+
const enum SupportType { None = 0, Ellipse = 1, OBB = 2, Circle = 3, Poly = 4, PolyLocal = 5 }
|
|
462
|
+
let _supportAType = SupportType.None
|
|
463
|
+
let _supportBType = SupportType.None
|
|
464
|
+
|
|
465
|
+
// A-shape params
|
|
466
|
+
let _Acx = 0, _Acy = 0, _Aux = 0, _Auy = 0, _Avx = 0, _Avy = 0, _Arx = 0, _Ary = 0, _Ahx = 0, _Ahy = 0, _Arr = 0
|
|
467
|
+
let _Apoly: { x: number, y: number }[] | null = null
|
|
468
|
+
|
|
469
|
+
// B-shape params
|
|
470
|
+
let _Bcx = 0, _Bcy = 0, _Bux = 0, _Buy = 0, _Bvx = 0, _Bvy = 0, _Brx = 0, _Bry = 0, _Bhx = 0, _Bhy = 0, _Brr = 0
|
|
471
|
+
let _Bpoly: { x: number, y: number }[] | null = null
|
|
472
|
+
|
|
473
|
+
function setSupportCircle(dx: number, dy: number, cx: number, cy: number, r: number) {
|
|
474
|
+
const len = Math.hypot(dx, dy)
|
|
475
|
+
if (len === 0) { _sx = cx; _sy = cy; return }
|
|
476
|
+
const inv = 1 / len
|
|
477
|
+
_sx = cx + dx * inv * r
|
|
478
|
+
_sy = cy + dy * inv * r
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
function setSupportOBB(
|
|
482
|
+
dx: number, dy: number,
|
|
483
|
+
cx: number, cy: number, ux: number, uy: number, vx: number, vy: number, hx: number, hy: number
|
|
484
|
+
) {
|
|
485
|
+
const du = dx * ux + dy * uy
|
|
486
|
+
const dv = dx * vx + dy * vy
|
|
487
|
+
const sx = du >= 0 ? 1 : -1
|
|
488
|
+
const sy = dv >= 0 ? 1 : -1
|
|
489
|
+
_sx = cx + ux * hx * sx + vx * hy * sy
|
|
490
|
+
_sy = cy + uy * hx * sx + vy * hy * sy
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
function dvDy(dy: number, a: number) { return dy * a } // tiny inline helper (prevents temp vars)
|
|
494
|
+
|
|
495
|
+
function setSupportEllipse(
|
|
496
|
+
dx: number, dy: number,
|
|
497
|
+
cx: number, cy: number, ux: number, uy: number, vx: number, vy: number, rx: number, ry: number
|
|
498
|
+
) {
|
|
499
|
+
const du = dx * ux + dvDy(dy, uy)
|
|
500
|
+
const dv = dx * vx + dvDy(dy, vy)
|
|
501
|
+
const denom = Math.hypot(rx * du, ry * dv)
|
|
502
|
+
if (denom === 0) { _sx = cx; _sy = cy; return }
|
|
503
|
+
const kU = (rx * rx * du) / denom
|
|
504
|
+
const kV = (ry * ry * dv) / denom
|
|
505
|
+
_sx = cx + kU * ux + kV * vx
|
|
506
|
+
_sy = cy + kU * uy + kV * vy
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
function setSupportPoly(dx: number, dy: number, verts: { x: number, y: number }[]) {
|
|
510
|
+
let best = 0, bestDot = -Infinity
|
|
511
|
+
for (let i = 0, n = verts.length; i < n; i++) {
|
|
512
|
+
const vx = verts[i].x, vy = verts[i].y
|
|
513
|
+
const d = dx * vx + dy * vy
|
|
514
|
+
if (d > bestDot) { bestDot = d; best = i }
|
|
515
|
+
}
|
|
516
|
+
_sx = verts[best].x
|
|
517
|
+
_sy = verts[best].y
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// PolyLocal support: verts in LOCAL, with frame (cx,cy, U/V, sx/sy)
|
|
521
|
+
function setSupportPolyLocal(
|
|
522
|
+
dx: number, dy: number,
|
|
523
|
+
verts: { x: number, y: number }[],
|
|
524
|
+
cx: number, cy: number, ux: number, uy: number, vx: number, vy: number, sx: number, sy: number
|
|
525
|
+
) {
|
|
526
|
+
const kU = (dx * ux + dy * uy) * sx
|
|
527
|
+
const kV = (dx * vx + dy * vy) * sy
|
|
528
|
+
let best = 0, bestDot = -Infinity
|
|
529
|
+
for (let i = 0, n = verts.length; i < n; i++) {
|
|
530
|
+
const s = kU * verts[i].x + kV * verts[i].y
|
|
531
|
+
if (s > bestDot) { bestDot = s; best = i }
|
|
532
|
+
}
|
|
533
|
+
const lx = verts[best].x, ly = verts[best].y
|
|
534
|
+
_sx = cx + ux * (sx * lx) + vx * (sy * ly)
|
|
535
|
+
_sy = cy + uy * (sx * lx) + vy * (sy * ly)
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
function supportA(dx: number, dy: number) {
|
|
539
|
+
if (_supportAType === SupportType.Ellipse) setSupportEllipse(dx, dy, _Acx, _Acy, _Aux, _Auy, _Avx, _Avy, _Arx, _Ary)
|
|
540
|
+
else if (_supportAType === SupportType.OBB) setSupportOBB(dx, dy, _Acx, _Acy, _Aux, _Auy, _Avx, _Avy, _Ahx, _Ahy)
|
|
541
|
+
else if (_supportAType === SupportType.Circle) setSupportCircle(dx, dy, _Acx, _Acy, _Arr)
|
|
542
|
+
else if (_supportAType === SupportType.Poly) setSupportPoly(dx, dy, _Apoly!)
|
|
543
|
+
else if (_supportAType === SupportType.PolyLocal) setSupportPolyLocal(dx, dy, _Apoly!, _Acx, _Acy, _Aux, _Auy, _Avx, _Avy, _Arx, _Ary)
|
|
544
|
+
else { _sx = 0; _sy = 0 }
|
|
545
|
+
}
|
|
546
|
+
function supportB(dx: number, dy: number) {
|
|
547
|
+
if (_supportBType === SupportType.Ellipse) setSupportEllipse(dx, dy, _Bcx, _Bcy, _Bux, _Buy, _Bvx, _Bvy, _Brx, _Bry)
|
|
548
|
+
else if (_supportBType === SupportType.OBB) setSupportOBB(dx, dy, _Bcx, _Bcy, _Bux, _Buy, _Bvx, _Bvy, _Bhx, _Bhy)
|
|
549
|
+
else if (_supportBType === SupportType.Circle) setSupportCircle(dx, dy, _Bcx, _Bcy, _Brr)
|
|
550
|
+
else if (_supportBType === SupportType.Poly) setSupportPoly(dx, dy, _Bpoly!)
|
|
551
|
+
else if (_supportBType === SupportType.PolyLocal) setSupportPolyLocal(dx, dy, _Bpoly!, _Bcx, _Bcy, _Bux, _Buy, _Bvx, _Bvy, _Brx, _Bry)
|
|
552
|
+
else { _sx = 0; _sy = 0 }
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// GJK core — returns true if intersection (robust; no allocations)
|
|
556
|
+
function gjkIntersectsNoAlloc(): boolean {
|
|
557
|
+
// EPS guards degenerate directions/points
|
|
558
|
+
const EPS = 1e-9
|
|
559
|
+
const EPS2 = EPS * EPS
|
|
560
|
+
|
|
561
|
+
// simplex points (A = most recently added)
|
|
562
|
+
let ax = 0, ay = 0, bx = 0, by = 0, cx = 0, cy = 0
|
|
563
|
+
let n = 0
|
|
564
|
+
|
|
565
|
+
// search direction
|
|
566
|
+
let dx = 1, dy = 0
|
|
567
|
+
|
|
568
|
+
// Adds a new support point as A and shifts previous (C<-B, B<-A)
|
|
569
|
+
function addPointAsA() {
|
|
570
|
+
supportA(dx, dy); const pax = _sx, pay = _sy
|
|
571
|
+
supportB(-dx, -dy); const pbx = _sx, pby = _sy
|
|
572
|
+
const px = pax - pbx, py = pay - pby
|
|
573
|
+
cx = bx; cy = by
|
|
574
|
+
bx = ax; by = ay
|
|
575
|
+
ax = px; ay = py
|
|
576
|
+
if (n < 3) n++
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
addPointAsA()
|
|
580
|
+
if (ax * ax + ay * ay <= EPS2) return true // origin exactly (or ~) hit
|
|
581
|
+
dx = -ax; dy = -ay
|
|
582
|
+
|
|
583
|
+
for (let iter = 0; iter < 32; iter++) {
|
|
584
|
+
const dLen2 = dx * dx + dy * dy
|
|
585
|
+
if (dLen2 <= EPS2) return true // direction collapsed → enclosed
|
|
586
|
+
|
|
587
|
+
addPointAsA()
|
|
588
|
+
|
|
589
|
+
// If new point A does not pass beyond origin along d, shapes are separated
|
|
590
|
+
const Ad = ax * dx + ay * dy
|
|
591
|
+
if (Ad <= 0) return false
|
|
592
|
+
if (ax * ax + ay * ay <= EPS2) return true
|
|
593
|
+
|
|
594
|
+
if (n === 2) {
|
|
595
|
+
// Segment (B-A). Use triple product to get perpendicular toward origin: d = triple(AB, AO, AB)
|
|
596
|
+
const abx = bx - ax, aby = by - ay
|
|
597
|
+
const aox = -ax, aoy = -ay
|
|
598
|
+
const ac = abx * abx + aby * aby // (AB·AB)
|
|
599
|
+
const bc = aox * abx + aoy * aby // (AO·AB)
|
|
600
|
+
dx = aox * ac - abx * bc // AO*(AB·AB) - AB*(AO·AB)
|
|
601
|
+
dy = aoy * ac - aby * bc
|
|
602
|
+
continue
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
// Triangle (C-B-A), A is the latest point
|
|
606
|
+
const abx = bx - ax, aby = by - ay
|
|
607
|
+
const acx = cx - ax, acy = cy - ay
|
|
608
|
+
const aox = -ax, aoy = -ay
|
|
609
|
+
|
|
610
|
+
// abPerp = triple(AC, AO, AB)
|
|
611
|
+
const ac_ab = acx * abx + acy * aby // (AC·AB)
|
|
612
|
+
const ao_ab = aox * abx + aoy * aby // (AO·AB)
|
|
613
|
+
let t1x = aox * ac_ab - acx * ao_ab
|
|
614
|
+
let t1y = aoy * ac_ab - acy * ao_ab
|
|
615
|
+
if (t1x * aox + t1y * aoy > 0) {
|
|
616
|
+
// Origin is in the AB region: drop C -> segment(B-A)
|
|
617
|
+
cx = bx; cy = by; n = 2
|
|
618
|
+
dx = t1x; dy = t1y
|
|
619
|
+
continue
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// acPerp = triple(AB, AO, AC)
|
|
623
|
+
const ab_ac = abx * acx + aby * acy // (AB·AC)
|
|
624
|
+
const ao_ac = aox * acx + aoy * acy // (AO·AC)
|
|
625
|
+
let t2x = aox * ab_ac - abx * ao_ac
|
|
626
|
+
let t2y = aoy * ab_ac - aby * ao_ac
|
|
627
|
+
if (t2x * aox + t2y * aoy > 0) {
|
|
628
|
+
// Origin is in the AC region: drop B -> segment(C-A)
|
|
629
|
+
bx = cx; by = cy; n = 2
|
|
630
|
+
dx = t2x; dy = t2y
|
|
631
|
+
continue
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// Origin is inside triangle
|
|
635
|
+
return true
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// Conservative fallback
|
|
639
|
+
return false
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// =====================================================================================
|
|
643
|
+
// Ellipse interactions via GJK (no allocations)
|
|
644
|
+
// =====================================================================================
|
|
645
|
+
|
|
646
|
+
function checkEllipseRectCollision(
|
|
647
|
+
e: EllipseCollider, te: WorldTransform,
|
|
648
|
+
r: RectangleCollider, tr: WorldTransform
|
|
649
|
+
): boolean {
|
|
650
|
+
// A = Ellipse
|
|
651
|
+
const esx = te.scaleX.v, esy = te.scaleY.v
|
|
652
|
+
_Arx = abs(e.width * esx) * 0.5
|
|
653
|
+
_Ary = abs(e.height * esy) * 0.5
|
|
654
|
+
const ecs = te.cos, esn = te.sin
|
|
655
|
+
_Aux = ecs; _Auy = esn; _Avx = -esn; _Avy = ecs
|
|
656
|
+
const eox = (e.x || 0) * esx, eoy = (e.y || 0) * esy
|
|
657
|
+
_Acx = te.x.v + _Aux * eox + _Avx * eoy
|
|
658
|
+
_Acy = te.y.v + _Auy * eox + _Avy * eoy
|
|
659
|
+
_supportAType = SupportType.Ellipse
|
|
660
|
+
_Apoly = null
|
|
661
|
+
|
|
662
|
+
// B = OBB (rect)
|
|
663
|
+
const rsx = tr.scaleX.v, rsy = tr.scaleY.v
|
|
664
|
+
_Bhx = abs(r.width * rsx) * 0.5
|
|
665
|
+
_Bhy = abs(r.height * rsy) * 0.5
|
|
666
|
+
const rcs = tr.cos, rsn = tr.sin
|
|
667
|
+
_Bux = rcs; _Buy = rsn; _Bvx = -rsn; _Bvy = rcs
|
|
668
|
+
const rox = (r.x || 0) * rsx, roy = (r.y || 0) * rsy
|
|
669
|
+
_Bcx = tr.x.v + _Bux * rox + _Bvx * roy
|
|
670
|
+
_Bcy = tr.y.v + _Buy * rox + _Bvy * roy
|
|
671
|
+
_supportBType = SupportType.OBB
|
|
672
|
+
_Bpoly = null
|
|
673
|
+
|
|
674
|
+
return gjkIntersectsNoAlloc()
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
function checkEllipseCircleCollision(
|
|
678
|
+
e: EllipseCollider, te: WorldTransform,
|
|
679
|
+
c: CircleCollider, tc: WorldTransform
|
|
680
|
+
): boolean {
|
|
681
|
+
// A = Ellipse
|
|
682
|
+
const esx = te.scaleX.v, esy = te.scaleY.v
|
|
683
|
+
_Arx = abs(e.width * esx) * 0.5
|
|
684
|
+
_Ary = abs(e.height * esy) * 0.5
|
|
685
|
+
const ecs = te.cos, esn = te.sin
|
|
686
|
+
_Aux = ecs; _Auy = esn; _Avx = -esn; _Avy = ecs
|
|
687
|
+
const eox = (e.x || 0) * esx, eoy = (e.y || 0) * esy
|
|
688
|
+
_Acx = te.x.v + _Aux * eox + _Avx * eoy
|
|
689
|
+
_Acy = te.y.v + _Auy * eox + _Avy * eoy
|
|
690
|
+
_supportAType = SupportType.Ellipse
|
|
691
|
+
_Apoly = null
|
|
692
|
+
|
|
693
|
+
// B = Circle
|
|
694
|
+
circleCenterScratch(c, tc)
|
|
695
|
+
_Bcx = _ccx; _Bcy = _ccy
|
|
696
|
+
_Brr = circleScaledRadius(c, tc)
|
|
697
|
+
_supportBType = SupportType.Circle
|
|
698
|
+
_Bpoly = null
|
|
699
|
+
|
|
700
|
+
return gjkIntersectsNoAlloc()
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
function checkEllipseEllipseCollision(
|
|
704
|
+
a: EllipseCollider, ta: WorldTransform,
|
|
705
|
+
b: EllipseCollider, tb: WorldTransform
|
|
706
|
+
): boolean {
|
|
707
|
+
// A
|
|
708
|
+
const asx = ta.scaleX.v, asy = ta.scaleY.v
|
|
709
|
+
_Arx = abs(a.width * asx) * 0.5
|
|
710
|
+
_Ary = abs(a.height * asy) * 0.5
|
|
711
|
+
const acs = ta.cos, asn = ta.sin
|
|
712
|
+
_Aux = acs; _Auy = asn; _Avx = -asn; _Avy = acs
|
|
713
|
+
const aox = (a.x || 0) * asx, aoy = (a.y || 0) * asy
|
|
714
|
+
_Acx = ta.x.v + _Aux * aox + _Avx * aoy
|
|
715
|
+
_Acy = ta.y.v + _Auy * aox + _Avy * aoy
|
|
716
|
+
_supportAType = SupportType.Ellipse
|
|
717
|
+
_Apoly = null
|
|
718
|
+
|
|
719
|
+
// B
|
|
720
|
+
const bsx = tb.scaleX.v, bsy = tb.scaleY.v
|
|
721
|
+
_Brx = abs(b.width * bsx) * 0.5
|
|
722
|
+
_Bry = abs(b.height * bsy) * 0.5
|
|
723
|
+
const bcs = tb.cos, bsn = tb.sin
|
|
724
|
+
_Bux = bcs; _Buy = bsn; _Bvx = -bsn; _Bvy = bcs
|
|
725
|
+
const box = (b.x || 0) * bsx, boy = (b.y || 0) * bsy
|
|
726
|
+
_Bcx = tb.x.v + _Bux * box + _Bvx * boy
|
|
727
|
+
_Bcy = tb.y.v + _Buy * box + _Bvy * boy
|
|
728
|
+
_supportBType = SupportType.Ellipse
|
|
729
|
+
_Bpoly = null
|
|
730
|
+
|
|
731
|
+
return gjkIntersectsNoAlloc()
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
// Poly–Ellipse via GJK (Poly in LOCAL + Transform, Ellipse in LOCAL + Transform)
|
|
735
|
+
function checkPolyEllipseCollision(poly: PolygonCollider, tp: WorldTransform, e: EllipseCollider, te: WorldTransform): boolean {
|
|
736
|
+
// A = Poly (LOCAL + Transform) → use PolyLocal support; reuse A scratch slots
|
|
737
|
+
const psx = tp.scaleX.v, psy = tp.scaleY.v
|
|
738
|
+
const pcs = tp.cos, psn = tp.sin
|
|
739
|
+
const pux = pcs, puy = psn
|
|
740
|
+
const pvx = -psn, pvy = pcs
|
|
741
|
+
const pox = ((poly as any).x || 0) * psx
|
|
742
|
+
const poy = ((poly as any).y || 0) * psy
|
|
743
|
+
_Acx = tp.x.v + pux * pox + pvx * poy
|
|
744
|
+
_Acy = tp.y.v + puy * pox + pvy * poy
|
|
745
|
+
_Aux = pux; _Auy = puy; _Avx = pvx; _Avy = pvy
|
|
746
|
+
_Arx = psx; _Ary = psy
|
|
747
|
+
_Apoly = poly.vertices
|
|
748
|
+
_supportAType = SupportType.PolyLocal
|
|
749
|
+
|
|
750
|
+
// B = Ellipse
|
|
751
|
+
const esx = te.scaleX.v, esy = te.scaleY.v
|
|
752
|
+
_Brx = abs(e.width * esx) * 0.5
|
|
753
|
+
_Bry = abs(e.height * esy) * 0.5
|
|
754
|
+
const ecs = te.cos, esn = te.sin
|
|
755
|
+
_Bux = ecs; _Buy = esn; _Bvx = -esn; _Bvy = ecs
|
|
756
|
+
const eox = (e.x || 0) * esx, eoy = (e.y || 0) * esy
|
|
757
|
+
_Bcx = te.x.v + _Bux * eox + _Bvx * eoy
|
|
758
|
+
_Bcy = te.y.v + _Buy * eox + _Bvy * eoy
|
|
759
|
+
_Bpoly = null
|
|
760
|
+
_supportBType = SupportType.Ellipse
|
|
761
|
+
|
|
762
|
+
return gjkIntersectsNoAlloc()
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
// =====================================================================================
|
|
766
|
+
// Dispatcher (no allocations)
|
|
767
|
+
// =====================================================================================
|
|
768
|
+
|
|
769
|
+
export function checkCollision(ca: Collider, ta: WorldTransform, cb: Collider, tb: WorldTransform): boolean {
|
|
770
|
+
// Rectangle–Rectangle
|
|
771
|
+
if (ca.type === ColliderType.Rectangle && cb.type === ColliderType.Rectangle)
|
|
772
|
+
return checkRectRectCollision(ca, ta, cb, tb)
|
|
773
|
+
|
|
774
|
+
// Circle–Circle
|
|
775
|
+
if (ca.type === ColliderType.Circle && cb.type === ColliderType.Circle)
|
|
776
|
+
return checkCircleCircleCollision(ca, ta, cb, tb)
|
|
777
|
+
|
|
778
|
+
// Rect–Circle (both orders)
|
|
779
|
+
if (ca.type === ColliderType.Rectangle && cb.type === ColliderType.Circle)
|
|
780
|
+
return checkRectCircleCollision(ca, ta, cb, tb)
|
|
781
|
+
if (ca.type === ColliderType.Circle && cb.type === ColliderType.Rectangle)
|
|
782
|
+
return checkRectCircleCollision(cb, tb, ca, ta)
|
|
783
|
+
|
|
784
|
+
// Polygon–Polygon (LOCAL + Transform)
|
|
785
|
+
if (ca.type === ColliderType.Polygon && cb.type === ColliderType.Polygon)
|
|
786
|
+
return checkPolyPolyCollision(ca, ta, cb, tb)
|
|
787
|
+
|
|
788
|
+
// Polygon–Circle (both orders; LOCAL + Transform for polygon)
|
|
789
|
+
if (ca.type === ColliderType.Polygon && cb.type === ColliderType.Circle)
|
|
790
|
+
return checkPolyCircleCollision(ca, ta, cb, tb)
|
|
791
|
+
if (ca.type === ColliderType.Circle && cb.type === ColliderType.Polygon)
|
|
792
|
+
return checkPolyCircleCollision(cb, tb, ca, ta)
|
|
793
|
+
|
|
794
|
+
// Polygon–Rect (both orders; LOCAL + Transform for polygon)
|
|
795
|
+
if (ca.type === ColliderType.Polygon && cb.type === ColliderType.Rectangle)
|
|
796
|
+
return checkPolyRectCollision(ca, ta, cb, tb)
|
|
797
|
+
if (ca.type === ColliderType.Rectangle && cb.type === ColliderType.Polygon)
|
|
798
|
+
return checkPolyRectCollision(cb, tb, ca, ta)
|
|
799
|
+
|
|
800
|
+
// Ellipse interactions via GJK
|
|
801
|
+
if (ca.type === ColliderType.Ellipse && cb.type === ColliderType.Rectangle)
|
|
802
|
+
return checkEllipseRectCollision(ca, ta, cb, tb)
|
|
803
|
+
if (ca.type === ColliderType.Rectangle && cb.type === ColliderType.Ellipse)
|
|
804
|
+
return checkEllipseRectCollision(cb, tb, ca, ta)
|
|
805
|
+
|
|
806
|
+
if (ca.type === ColliderType.Ellipse && cb.type === ColliderType.Circle)
|
|
807
|
+
return checkEllipseCircleCollision(ca, ta, cb, tb)
|
|
808
|
+
if (ca.type === ColliderType.Circle && cb.type === ColliderType.Ellipse)
|
|
809
|
+
return checkEllipseCircleCollision(cb, tb, ca, ta)
|
|
810
|
+
|
|
811
|
+
if (ca.type === ColliderType.Ellipse && cb.type === ColliderType.Ellipse)
|
|
812
|
+
return checkEllipseEllipseCollision(ca, ta, cb, tb)
|
|
813
|
+
|
|
814
|
+
// Polygon–Ellipse (both orders; polygon is LOCAL + Transform via PolyLocal support)
|
|
815
|
+
if (ca.type === ColliderType.Polygon && cb.type === ColliderType.Ellipse)
|
|
816
|
+
return checkPolyEllipseCollision(ca, ta, cb, tb)
|
|
817
|
+
if (ca.type === ColliderType.Ellipse && cb.type === ColliderType.Polygon)
|
|
818
|
+
return checkPolyEllipseCollision(cb, tb, ca, ta)
|
|
819
|
+
|
|
820
|
+
return false
|
|
821
|
+
}
|