melonjs 20.2.0 → 20.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -8
- package/build/application/application.d.ts +0 -17
- package/build/application/application.d.ts.map +1 -1
- package/build/application/settings.d.ts +6 -2
- package/build/application/settings.d.ts.map +1 -1
- package/build/audio/audio.d.ts +2 -2
- package/build/audio/audio.d.ts.map +1 -1
- package/build/audio/backend/buffer.d.ts +26 -0
- package/build/audio/backend/buffer.d.ts.map +1 -0
- package/build/audio/backend/cache.d.ts +2 -0
- package/build/audio/backend/cache.d.ts.map +1 -0
- package/build/audio/backend/core.d.ts +24 -0
- package/build/audio/backend/core.d.ts.map +1 -0
- package/build/audio/backend/engine.d.ts +35 -0
- package/build/audio/backend/engine.d.ts.map +1 -0
- package/build/audio/backend/sound.d.ts +29 -0
- package/build/audio/backend/sound.d.ts.map +1 -0
- package/build/audio/backend/spatial.d.ts +191 -0
- package/build/audio/backend/spatial.d.ts.map +1 -0
- package/build/audio/backend/types.d.ts +107 -0
- package/build/audio/backend/types.d.ts.map +1 -0
- package/build/audio/backend/voice.d.ts +8 -0
- package/build/audio/backend/voice.d.ts.map +1 -0
- package/build/audio/playback.d.ts +49 -4
- package/build/audio/playback.d.ts.map +1 -1
- package/build/audio/procedural.d.ts.map +1 -1
- package/build/audio/state.d.ts +69 -0
- package/build/audio/state.d.ts.map +1 -0
- package/build/audio/types.d.ts +93 -1
- package/build/audio/types.d.ts.map +1 -1
- package/build/camera/camera2d.d.ts +0 -68
- package/build/camera/camera2d.d.ts.map +1 -1
- package/build/camera/camera3d.d.ts +91 -84
- package/build/camera/camera3d.d.ts.map +1 -1
- package/build/camera/effects/fade_effect.d.ts +0 -5
- package/build/camera/effects/fade_effect.d.ts.map +1 -1
- package/build/camera/effects/mask_effect.d.ts +0 -5
- package/build/camera/effects/mask_effect.d.ts.map +1 -1
- package/build/camera/fog.d.ts +118 -0
- package/build/camera/fog.d.ts.map +1 -0
- package/build/const.d.ts +2 -2
- package/build/geometries/box3d.d.ts +0 -28
- package/build/geometries/box3d.d.ts.map +1 -1
- package/build/geometries/ellipse.d.ts +0 -20
- package/build/geometries/ellipse.d.ts.map +1 -1
- package/build/geometries/observablePoint.d.ts +0 -3
- package/build/geometries/observablePoint.d.ts.map +1 -1
- package/build/geometries/path2d.d.ts +0 -19
- package/build/geometries/path2d.d.ts.map +1 -1
- package/build/geometries/polygon.d.ts +0 -12
- package/build/geometries/polygon.d.ts.map +1 -1
- package/build/geometries/roundrect.d.ts +0 -18
- package/build/geometries/roundrect.d.ts.map +1 -1
- package/build/geometries/sphere.d.ts +0 -9
- package/build/geometries/sphere.d.ts.map +1 -1
- package/build/geometries/toarccanvas.d.ts.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +12150 -11289
- package/build/index.js.map +4 -4
- package/build/input/gamepad.d.ts.map +1 -1
- package/build/input/input.d.ts +19 -0
- package/build/input/input.d.ts.map +1 -1
- package/build/input/pointer.d.ts +0 -4
- package/build/input/pointer.d.ts.map +1 -1
- package/build/input/pointerevent.d.ts +0 -6
- package/build/input/pointerevent.d.ts.map +1 -1
- package/build/lang/deprecated.d.ts +4 -2
- package/build/lang/deprecated.d.ts.map +1 -1
- package/build/level/gltf/GLTFModel.d.ts +0 -81
- package/build/level/gltf/GLTFModel.d.ts.map +1 -1
- package/build/level/gltf/GLTFScene.d.ts +13 -44
- package/build/level/gltf/GLTFScene.d.ts.map +1 -1
- package/build/level/gltf/gltf_sampler.d.ts +1 -48
- package/build/level/gltf/gltf_sampler.d.ts.map +1 -1
- package/build/level/level.d.ts +195 -113
- package/build/level/level.d.ts.map +1 -1
- package/build/level/tiled/TMXGroup.d.ts +1 -65
- package/build/level/tiled/TMXGroup.d.ts.map +1 -1
- package/build/level/tiled/TMXLayer.d.ts +0 -44
- package/build/level/tiled/TMXLayer.d.ts.map +1 -1
- package/build/level/tiled/TMXObject.d.ts +1 -136
- package/build/level/tiled/TMXObject.d.ts.map +1 -1
- package/build/level/tiled/TMXObjectFactory.d.ts +1 -40
- package/build/level/tiled/TMXObjectFactory.d.ts.map +1 -1
- package/build/level/tiled/TMXTile.d.ts +1 -30
- package/build/level/tiled/TMXTile.d.ts.map +1 -1
- package/build/level/tiled/TMXTileMap.d.ts +0 -10
- package/build/level/tiled/TMXTileMap.d.ts.map +1 -1
- package/build/level/tiled/TMXTileset.d.ts +0 -113
- package/build/level/tiled/TMXTileset.d.ts.map +1 -1
- package/build/level/tiled/TMXTilesetGroup.d.ts +0 -1
- package/build/level/tiled/TMXTilesetGroup.d.ts.map +1 -1
- package/build/level/tiled/TMXUtils.d.ts +1 -43
- package/build/level/tiled/TMXUtils.d.ts.map +1 -1
- package/build/level/tiled/factories/shape.d.ts +1 -7
- package/build/level/tiled/factories/shape.d.ts.map +1 -1
- package/build/level/tiled/factories/text.d.ts +1 -7
- package/build/level/tiled/factories/text.d.ts.map +1 -1
- package/build/level/tiled/factories/tile.d.ts +1 -7
- package/build/level/tiled/factories/tile.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXHexagonalRenderer.d.ts +0 -60
- package/build/level/tiled/renderer/TMXHexagonalRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXIsometricRenderer.d.ts +0 -42
- package/build/level/tiled/renderer/TMXIsometricRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXObliqueRenderer.d.ts +0 -5
- package/build/level/tiled/renderer/TMXObliqueRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXOrthogonalRenderer.d.ts +0 -31
- package/build/level/tiled/renderer/TMXOrthogonalRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXRenderer.d.ts +2 -2
- package/build/level/tiled/renderer/TMXRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/TMXStaggeredRenderer.d.ts.map +1 -1
- package/build/level/tiled/renderer/autodetect.d.ts +1 -6
- package/build/level/tiled/renderer/autodetect.d.ts.map +1 -1
- package/build/lighting/light2d.d.ts +0 -25
- package/build/lighting/light2d.d.ts.map +1 -1
- package/build/lighting/light3d.d.ts +0 -16
- package/build/lighting/light3d.d.ts.map +1 -1
- package/build/loader/loader.d.ts +46 -73
- package/build/loader/loader.d.ts.map +1 -1
- package/build/loader/loadingscreen.d.ts +0 -33
- package/build/loader/loadingscreen.d.ts.map +1 -1
- package/build/loader/parsers/aseprite.d.ts +0 -13
- package/build/loader/parsers/aseprite.d.ts.map +1 -1
- package/build/loader/parsers/audio.d.ts +2 -0
- package/build/loader/parsers/audio.d.ts.map +1 -0
- package/build/loader/parsers/binary.d.ts +1 -10
- package/build/loader/parsers/binary.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/compressed_image.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/parseDDS.d.ts +1 -7
- package/build/loader/parsers/compressed_textures/parseDDS.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/parseKTX.d.ts +1 -7
- package/build/loader/parsers/compressed_textures/parseKTX.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/parseKTX2.d.ts +1 -7
- package/build/loader/parsers/compressed_textures/parseKTX2.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/parsePKM.d.ts +1 -7
- package/build/loader/parsers/compressed_textures/parsePKM.d.ts.map +1 -1
- package/build/loader/parsers/compressed_textures/parsePVR.d.ts +1 -7
- package/build/loader/parsers/compressed_textures/parsePVR.d.ts.map +1 -1
- package/build/loader/parsers/fontface.d.ts +1 -13
- package/build/loader/parsers/fontface.d.ts.map +1 -1
- package/build/loader/parsers/gltf.d.ts +1 -70
- package/build/loader/parsers/gltf.d.ts.map +1 -1
- package/build/loader/parsers/image.d.ts +1 -22
- package/build/loader/parsers/image.d.ts.map +1 -1
- package/build/loader/parsers/json.d.ts +1 -10
- package/build/loader/parsers/json.d.ts.map +1 -1
- package/build/loader/parsers/mtl.d.ts +1 -28
- package/build/loader/parsers/mtl.d.ts.map +1 -1
- package/build/loader/parsers/obj.d.ts +1 -59
- package/build/loader/parsers/obj.d.ts.map +1 -1
- package/build/loader/parsers/pbr.d.ts +1 -62
- package/build/loader/parsers/pbr.d.ts.map +1 -1
- package/build/loader/parsers/script.d.ts +1 -10
- package/build/loader/parsers/script.d.ts.map +1 -1
- package/build/loader/parsers/shader.d.ts +1 -52
- package/build/loader/parsers/shader.d.ts.map +1 -1
- package/build/loader/parsers/tmx.d.ts +1 -10
- package/build/loader/parsers/tmx.d.ts.map +1 -1
- package/build/loader/parsers/video.d.ts +1 -10
- package/build/loader/parsers/video.d.ts.map +1 -1
- package/build/math/color.d.ts.map +1 -1
- package/build/math/noise.d.ts +0 -40
- package/build/math/noise.d.ts.map +1 -1
- package/build/math/observableVector2d.d.ts +0 -3
- package/build/math/observableVector2d.d.ts.map +1 -1
- package/build/math/observableVector3d.d.ts +0 -3
- package/build/math/observableVector3d.d.ts.map +1 -1
- package/build/math/vector2d.d.ts +0 -6
- package/build/math/vector2d.d.ts.map +1 -1
- package/build/math/vertex.d.ts +25 -0
- package/build/math/vertex.d.ts.map +1 -1
- package/build/particles/emitter.d.ts +0 -65
- package/build/particles/emitter.d.ts.map +1 -1
- package/build/particles/particle.d.ts +0 -81
- package/build/particles/particle.d.ts.map +1 -1
- package/build/physics/adapter.d.ts +3 -3
- package/build/physics/bounds.d.ts +0 -1
- package/build/physics/bounds.d.ts.map +1 -1
- package/build/physics/broadphase/broadphase.d.ts +0 -7
- package/build/physics/broadphase/broadphase.d.ts.map +1 -1
- package/build/physics/broadphase/octree.d.ts +0 -91
- package/build/physics/broadphase/octree.d.ts.map +1 -1
- package/build/physics/broadphase/quadtree.d.ts +0 -47
- package/build/physics/broadphase/quadtree.d.ts.map +1 -1
- package/build/physics/builtin/body.d.ts +5 -69
- package/build/physics/builtin/body.d.ts.map +1 -1
- package/build/physics/builtin/detector.d.ts +0 -312
- package/build/physics/builtin/detector.d.ts.map +1 -1
- package/build/physics/builtin/sat.d.ts +1 -48
- package/build/physics/builtin/sat.d.ts.map +1 -1
- package/build/physics/builtin/sat3d.d.ts +1 -56
- package/build/physics/builtin/sat3d.d.ts.map +1 -1
- package/build/physics/collision.d.ts +0 -2
- package/build/physics/collision.d.ts.map +1 -1
- package/build/physics/response.d.ts +0 -1
- package/build/physics/response.d.ts.map +1 -1
- package/build/physics/world.d.ts.map +1 -1
- package/build/plugin/plugin.d.ts +9 -1
- package/build/plugin/plugin.d.ts.map +1 -1
- package/build/polyfill/index.d.ts +1 -4
- package/build/polyfill/index.d.ts.map +1 -1
- package/build/renderable/anchorPoint.d.ts +1 -73
- package/build/renderable/anchorPoint.d.ts.map +1 -1
- package/build/renderable/animation.d.ts +0 -7
- package/build/renderable/animation.d.ts.map +1 -1
- package/build/renderable/colorlayer.d.ts +0 -5
- package/build/renderable/colorlayer.d.ts.map +1 -1
- package/build/renderable/container.d.ts +0 -55
- package/build/renderable/container.d.ts.map +1 -1
- package/build/renderable/draggable.d.ts +0 -5
- package/build/renderable/draggable.d.ts.map +1 -1
- package/build/renderable/dragndrop.d.ts +1 -12
- package/build/renderable/dragndrop.d.ts.map +1 -1
- package/build/renderable/entity/entity.d.ts +0 -8
- package/build/renderable/entity/entity.d.ts.map +1 -1
- package/build/renderable/frameAnimation.d.ts +0 -41
- package/build/renderable/frameAnimation.d.ts.map +1 -1
- package/build/renderable/groundshadow.d.ts +1 -91
- package/build/renderable/groundshadow.d.ts.map +1 -1
- package/build/renderable/imagelayer.d.ts +0 -29
- package/build/renderable/imagelayer.d.ts.map +1 -1
- package/build/renderable/instanced_mesh.d.ts +26 -104
- package/build/renderable/instanced_mesh.d.ts.map +1 -1
- package/build/renderable/mesh.d.ts +145 -140
- package/build/renderable/mesh.d.ts.map +1 -1
- package/build/renderable/nineslicesprite.d.ts +0 -4
- package/build/renderable/nineslicesprite.d.ts.map +1 -1
- package/build/renderable/renderable.d.ts +17 -54
- package/build/renderable/renderable.d.ts.map +1 -1
- package/build/renderable/sprite.d.ts +7 -52
- package/build/renderable/sprite.d.ts.map +1 -1
- package/build/renderable/sprite3d.d.ts +0 -95
- package/build/renderable/sprite3d.d.ts.map +1 -1
- package/build/renderable/text/bitmaptext.d.ts +0 -14
- package/build/renderable/text/bitmaptext.d.ts.map +1 -1
- package/build/renderable/text/bitmaptextdata.d.ts +0 -22
- package/build/renderable/text/bitmaptextdata.d.ts.map +1 -1
- package/build/renderable/text/glyph.d.ts +1 -39
- package/build/renderable/text/glyph.d.ts.map +1 -1
- package/build/renderable/text/text.d.ts +0 -20
- package/build/renderable/text/text.d.ts.map +1 -1
- package/build/renderable/text/textstyle.d.ts +1 -5
- package/build/renderable/text/textstyle.d.ts.map +1 -1
- package/build/renderable/trail.d.ts +0 -29
- package/build/renderable/trail.d.ts.map +1 -1
- package/build/renderable/trigger.d.ts +0 -6
- package/build/renderable/trigger.d.ts.map +1 -1
- package/build/renderable/ui/uibaseelement.d.ts +0 -40
- package/build/renderable/ui/uibaseelement.d.ts.map +1 -1
- package/build/renderable/ui/uispriteelement.d.ts +0 -35
- package/build/renderable/ui/uispriteelement.d.ts.map +1 -1
- package/build/state/stage.d.ts +4 -68
- package/build/state/stage.d.ts.map +1 -1
- package/build/state/state.d.ts.map +1 -1
- package/build/system/device.d.ts +0 -12
- package/build/system/device.d.ts.map +1 -1
- package/build/system/dom.d.ts +1 -8
- package/build/system/dom.d.ts.map +1 -1
- package/build/system/event.d.ts +1 -1
- package/build/system/legacy_pool.d.ts +1 -6
- package/build/system/legacy_pool.d.ts.map +1 -1
- package/build/system/platform.d.ts +21 -2
- package/build/system/platform.d.ts.map +1 -1
- package/build/system/pool.d.ts +0 -9
- package/build/system/pool.d.ts.map +1 -1
- package/build/system/save.d.ts.map +1 -1
- package/build/system/timer.d.ts +0 -20
- package/build/system/timer.d.ts.map +1 -1
- package/build/tweens/tween.d.ts +0 -62
- package/build/tweens/tween.d.ts.map +1 -1
- package/build/utils/array-multimap.d.ts +1 -13
- package/build/utils/array-multimap.d.ts.map +1 -1
- package/build/utils/decode.d.ts.map +1 -1
- package/build/utils/fetchdata.d.ts +2 -0
- package/build/utils/fetchdata.d.ts.map +1 -0
- package/build/utils/utils.d.ts +0 -13
- package/build/utils/utils.d.ts.map +1 -1
- package/build/video/blendmodes.d.ts +1 -106
- package/build/video/blendmodes.d.ts.map +1 -1
- package/build/video/buffer/index.d.ts +1 -39
- package/build/video/buffer/index.d.ts.map +1 -1
- package/build/video/buffer/vertex.d.ts +1 -82
- package/build/video/buffer/vertex.d.ts.map +1 -1
- package/build/video/canvas/canvas_renderer.d.ts +7 -25
- package/build/video/canvas/canvas_renderer.d.ts.map +1 -1
- package/build/video/canvas_factory.d.ts +1 -24
- package/build/video/canvas_factory.d.ts.map +1 -1
- package/build/video/effects/blendEffect.d.ts +0 -54
- package/build/video/effects/blendEffect.d.ts.map +1 -1
- package/build/video/effects/blur.d.ts +4 -4
- package/build/video/effects/blur.d.ts.map +1 -1
- package/build/video/effects/chromaticAberration.d.ts +5 -5
- package/build/video/effects/chromaticAberration.d.ts.map +1 -1
- package/build/video/effects/colorMatrix.d.ts +5 -15
- package/build/video/effects/colorMatrix.d.ts.map +1 -1
- package/build/video/effects/desaturate.d.ts +5 -5
- package/build/video/effects/desaturate.d.ts.map +1 -1
- package/build/video/effects/dissolve.d.ts +4 -4
- package/build/video/effects/dissolve.d.ts.map +1 -1
- package/build/video/effects/dropShadow.d.ts +5 -5
- package/build/video/effects/dropShadow.d.ts.map +1 -1
- package/build/video/effects/flash.d.ts +4 -4
- package/build/video/effects/flash.d.ts.map +1 -1
- package/build/video/effects/glow.d.ts +5 -5
- package/build/video/effects/glow.d.ts.map +1 -1
- package/build/video/effects/glsl_realization.d.ts +1 -17
- package/build/video/effects/glsl_realization.d.ts.map +1 -1
- package/build/video/effects/hologram.d.ts +4 -4
- package/build/video/effects/hologram.d.ts.map +1 -1
- package/build/video/effects/invert.d.ts +5 -5
- package/build/video/effects/invert.d.ts.map +1 -1
- package/build/video/effects/outline.d.ts +6 -6
- package/build/video/effects/outline.d.ts.map +1 -1
- package/build/video/effects/pixelate.d.ts +4 -4
- package/build/video/effects/pixelate.d.ts.map +1 -1
- package/build/video/effects/radialGradient.d.ts +2 -3
- package/build/video/effects/radialGradient.d.ts.map +1 -1
- package/build/video/effects/scanline.d.ts +6 -6
- package/build/video/effects/scanline.d.ts.map +1 -1
- package/build/video/effects/sepia.d.ts +5 -5
- package/build/video/effects/sepia.d.ts.map +1 -1
- package/build/video/effects/shadereffect.d.ts +12 -123
- package/build/video/effects/shadereffect.d.ts.map +1 -1
- package/build/video/effects/shine.d.ts +3 -3
- package/build/video/effects/shine.d.ts.map +1 -1
- package/build/video/effects/tintPulse.d.ts +4 -4
- package/build/video/effects/tintPulse.d.ts.map +1 -1
- package/build/video/effects/vignette.d.ts +6 -6
- package/build/video/effects/vignette.d.ts.map +1 -1
- package/build/video/effects/wave.d.ts +4 -4
- package/build/video/effects/wave.d.ts.map +1 -1
- package/build/video/effects/wgsl/layout.d.ts +1 -27
- package/build/video/effects/wgsl/layout.d.ts.map +1 -1
- package/build/video/effects/wgsl/parse.d.ts +1 -8
- package/build/video/effects/wgsl/parse.d.ts.map +1 -1
- package/build/video/effects/wgsl/scaffold.d.ts +1 -42
- package/build/video/effects/wgsl/scaffold.d.ts.map +1 -1
- package/build/video/effects/wgsl_realization.d.ts +1 -82
- package/build/video/effects/wgsl_realization.d.ts.map +1 -1
- package/build/video/gpu/batcher.d.ts +1 -13
- package/build/video/gpu/batcher.d.ts.map +1 -1
- package/build/video/gpu/instancerecord.d.ts +1 -163
- package/build/video/gpu/instancerecord.d.ts.map +1 -1
- package/build/video/gpu/meshchunk.d.ts +1 -48
- package/build/video/gpu/meshchunk.d.ts.map +1 -1
- package/build/video/gpu/meshvertex.d.ts +1 -53
- package/build/video/gpu/meshvertex.d.ts.map +1 -1
- package/build/video/gpu/primitives.d.ts +1 -59
- package/build/video/gpu/primitives.d.ts.map +1 -1
- package/build/video/gpu/quadcorners.d.ts +1 -10
- package/build/video/gpu/quadcorners.d.ts.map +1 -1
- package/build/video/gpu/textureslots.d.ts +1 -121
- package/build/video/gpu/textureslots.d.ts.map +1 -1
- package/build/video/gpu/texturestore.d.ts +1 -138
- package/build/video/gpu/texturestore.d.ts.map +1 -1
- package/build/video/gpu/topology.d.ts.map +1 -1
- package/build/video/gpu/vertexformat.d.ts +0 -28
- package/build/video/gpu/vertexformat.d.ts.map +1 -1
- package/build/video/gradient.d.ts +0 -81
- package/build/video/gradient.d.ts.map +1 -1
- package/build/video/renderer.d.ts +21 -102
- package/build/video/renderer.d.ts.map +1 -1
- package/build/video/renderstate.d.ts +0 -51
- package/build/video/renderstate.d.ts.map +1 -1
- package/build/video/rendertarget/canvasrendertarget.d.ts +0 -10
- package/build/video/rendertarget/canvasrendertarget.d.ts.map +1 -1
- package/build/video/rendertarget/render_target_pool.d.ts +1 -82
- package/build/video/rendertarget/render_target_pool.d.ts.map +1 -1
- package/build/video/rendertarget/webglrendertarget.d.ts +1 -64
- package/build/video/rendertarget/webglrendertarget.d.ts.map +1 -1
- package/build/video/rendertarget/webgpurendertarget.d.ts +0 -8
- package/build/video/rendertarget/webgpurendertarget.d.ts.map +1 -1
- package/build/video/texture/atlas.d.ts +2 -76
- package/build/video/texture/atlas.d.ts.map +1 -1
- package/build/video/texture/cache.d.ts +0 -136
- package/build/video/texture/cache.d.ts.map +1 -1
- package/build/video/texture/frametexture.d.ts +1 -71
- package/build/video/texture/frametexture.d.ts.map +1 -1
- package/build/video/texture/noise_texture2d.d.ts +0 -43
- package/build/video/texture/noise_texture2d.d.ts.map +1 -1
- package/build/video/texture/parser/aseprite.d.ts +1 -8
- package/build/video/texture/parser/aseprite.d.ts.map +1 -1
- package/build/video/texture/parser/spritesheet.d.ts +1 -8
- package/build/video/texture/parser/spritesheet.d.ts.map +1 -1
- package/build/video/texture/parser/texturepacker.d.ts +1 -8
- package/build/video/texture/parser/texturepacker.d.ts.map +1 -1
- package/build/video/texture/resource.d.ts +0 -9
- package/build/video/texture/resource.d.ts.map +1 -1
- package/build/video/texture/texture2d.d.ts +0 -11
- package/build/video/texture/texture2d.d.ts.map +1 -1
- package/build/video/utils/autodetect.d.ts +1 -5
- package/build/video/utils/autodetect.d.ts.map +1 -1
- package/build/video/webgl/batchers/batcher.d.ts +0 -55
- package/build/video/webgl/batchers/batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/lit_mesh_batcher.d.ts +0 -14
- package/build/video/webgl/batchers/lit_mesh_batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/lit_quad_batcher.d.ts +0 -72
- package/build/video/webgl/batchers/lit_quad_batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/material_batcher.d.ts +0 -89
- package/build/video/webgl/batchers/material_batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/mesh_batcher.d.ts +14 -343
- package/build/video/webgl/batchers/mesh_batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/primitive_batcher.d.ts +0 -10
- package/build/video/webgl/batchers/primitive_batcher.d.ts.map +1 -1
- package/build/video/webgl/batchers/quad_batcher.d.ts +0 -30
- package/build/video/webgl/batchers/quad_batcher.d.ts.map +1 -1
- package/build/video/webgl/buffer/index.d.ts +1 -36
- package/build/video/webgl/buffer/index.d.ts.map +1 -1
- package/build/video/webgl/buffer/instance_buffer.d.ts +1 -53
- package/build/video/webgl/buffer/instance_buffer.d.ts.map +1 -1
- package/build/video/webgl/buffer/retained_geometry.d.ts +1 -81
- package/build/video/webgl/buffer/retained_geometry.d.ts.map +1 -1
- package/build/video/webgl/buffer/uniformblock.d.ts +1 -80
- package/build/video/webgl/buffer/uniformblock.d.ts.map +1 -1
- package/build/video/webgl/buffer/vertexstate.d.ts +1 -100
- package/build/video/webgl/buffer/vertexstate.d.ts.map +1 -1
- package/build/video/webgl/glshader.d.ts +2 -51
- package/build/video/webgl/glshader.d.ts.map +1 -1
- package/build/video/webgl/lighting/pack3d.d.ts +1 -47
- package/build/video/webgl/lighting/pack3d.d.ts.map +1 -1
- package/build/video/webgl/lighting/std140.d.ts +1 -109
- package/build/video/webgl/lighting/std140.d.ts.map +1 -1
- package/build/video/webgl/renderers/tmxlayer/orthogonal.d.ts +1 -103
- package/build/video/webgl/renderers/tmxlayer/orthogonal.d.ts.map +1 -1
- package/build/video/webgl/shaders/multitexture-lit.d.ts +1 -26
- package/build/video/webgl/shaders/multitexture-lit.d.ts.map +1 -1
- package/build/video/webgl/shaders/multitexture.d.ts +1 -9
- package/build/video/webgl/shaders/multitexture.d.ts.map +1 -1
- package/build/video/webgl/texture/store.d.ts +1 -50
- package/build/video/webgl/texture/store.d.ts.map +1 -1
- package/build/video/webgl/utils/attributes.d.ts +1 -11
- package/build/video/webgl/utils/attributes.d.ts.map +1 -1
- package/build/video/webgl/utils/maxtextures.d.ts +1 -36
- package/build/video/webgl/utils/maxtextures.d.ts.map +1 -1
- package/build/video/webgl/utils/precision.d.ts +1 -14
- package/build/video/webgl/utils/precision.d.ts.map +1 -1
- package/build/video/webgl/utils/program.d.ts +1 -5
- package/build/video/webgl/utils/program.d.ts.map +1 -1
- package/build/video/webgl/utils/samplercache.d.ts +1 -68
- package/build/video/webgl/utils/samplercache.d.ts.map +1 -1
- package/build/video/webgl/utils/string.d.ts +1 -21
- package/build/video/webgl/utils/string.d.ts.map +1 -1
- package/build/video/webgl/utils/topology.d.ts +1 -23
- package/build/video/webgl/utils/topology.d.ts.map +1 -1
- package/build/video/webgl/utils/uniforms.d.ts +1 -25
- package/build/video/webgl/utils/uniforms.d.ts.map +1 -1
- package/build/video/webgl/utils/vertexformat.d.ts +1 -26
- package/build/video/webgl/utils/vertexformat.d.ts.map +1 -1
- package/build/video/webgl/webgl_renderer.d.ts +24 -286
- package/build/video/webgl/webgl_renderer.d.ts.map +1 -1
- package/build/video/webgpu/batchers/lit_mesh_batcher.d.ts +0 -6
- package/build/video/webgpu/batchers/lit_mesh_batcher.d.ts.map +1 -1
- package/build/video/webgpu/batchers/lit_quad_batcher.d.ts +0 -8
- package/build/video/webgpu/batchers/lit_quad_batcher.d.ts.map +1 -1
- package/build/video/webgpu/batchers/mesh_batcher.d.ts +1 -230
- package/build/video/webgpu/batchers/mesh_batcher.d.ts.map +1 -1
- package/build/video/webgpu/batchers/primitive_batcher.d.ts.map +1 -1
- package/build/video/webgpu/batchers/quad_batcher.d.ts +0 -82
- package/build/video/webgpu/batchers/quad_batcher.d.ts.map +1 -1
- package/build/video/webgpu/buffer/arena.d.ts +1 -63
- package/build/video/webgpu/buffer/arena.d.ts.map +1 -1
- package/build/video/webgpu/buffer/instance_buffer.d.ts +1 -64
- package/build/video/webgpu/buffer/instance_buffer.d.ts.map +1 -1
- package/build/video/webgpu/buffer/retained_geometry.d.ts +1 -54
- package/build/video/webgpu/buffer/retained_geometry.d.ts.map +1 -1
- package/build/video/webgpu/buffer/uniformring.d.ts +1 -67
- package/build/video/webgpu/buffer/uniformring.d.ts.map +1 -1
- package/build/video/webgpu/effect_binding.d.ts +1 -16
- package/build/video/webgpu/effect_binding.d.ts.map +1 -1
- package/build/video/webgpu/pipeline/bindgroups.d.ts +1 -32
- package/build/video/webgpu/pipeline/bindgroups.d.ts.map +1 -1
- package/build/video/webgpu/pipeline/cache.d.ts +1 -163
- package/build/video/webgpu/pipeline/cache.d.ts.map +1 -1
- package/build/video/webgpu/renderers/tmxlayer/orthogonal.d.ts +1 -87
- package/build/video/webgpu/renderers/tmxlayer/orthogonal.d.ts.map +1 -1
- package/build/video/webgpu/shaders/mesh-instanced.d.ts +1 -43
- package/build/video/webgpu/shaders/mesh-instanced.d.ts.map +1 -1
- package/build/video/webgpu/texture/compressed.d.ts +1 -32
- package/build/video/webgpu/texture/compressed.d.ts.map +1 -1
- package/build/video/webgpu/texture/frametexture.d.ts +1 -62
- package/build/video/webgpu/texture/frametexture.d.ts.map +1 -1
- package/build/video/webgpu/texture/store.d.ts +1 -147
- package/build/video/webgpu/texture/store.d.ts.map +1 -1
- package/build/video/webgpu/webgpu_renderer.d.ts +2 -89
- package/build/video/webgpu/webgpu_renderer.d.ts.map +1 -1
- package/package.json +8 -11
- package/skills/AGENTS.md +67 -0
- package/skills/melonjs/SKILL.md +156 -0
- package/skills/melonjs-20-migration/SKILL.md +160 -0
- package/skills/melonjs-3d/SKILL.md +525 -0
- package/skills/melonjs-3d-assets/SKILL.md +258 -0
- package/skills/melonjs-audio/SKILL.md +236 -0
- package/skills/melonjs-camera-and-drawing/SKILL.md +175 -0
- package/skills/melonjs-deployment/SKILL.md +113 -0
- package/skills/melonjs-effects-and-shaders/SKILL.md +178 -0
- package/skills/melonjs-events/SKILL.md +159 -0
- package/skills/melonjs-getting-started/SKILL.md +183 -0
- package/skills/melonjs-input/SKILL.md +166 -0
- package/skills/melonjs-lighting/SKILL.md +139 -0
- package/skills/melonjs-loading-assets/SKILL.md +186 -0
- package/skills/melonjs-particles-and-trails/SKILL.md +136 -0
- package/skills/melonjs-performance/SKILL.md +183 -0
- package/skills/melonjs-physics/SKILL.md +321 -0
- package/skills/melonjs-plugins/SKILL.md +191 -0
- package/skills/melonjs-renderables/SKILL.md +214 -0
- package/skills/melonjs-renderer-backends/SKILL.md +173 -0
- package/skills/melonjs-scenes-and-state/SKILL.md +180 -0
- package/skills/melonjs-sprites-and-animation/SKILL.md +173 -0
- package/skills/melonjs-tilemaps/SKILL.md +213 -0
- package/skills/melonjs-ui-and-text/SKILL.md +65 -0
- package/build/audio/backend.d.ts +0 -140
- package/build/audio/backend.d.ts.map +0 -1
- package/build/loader/parsers/fetchdata.d.ts +0 -32
- package/build/loader/parsers/fetchdata.d.ts.map +0 -1
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: melonjs-input
|
|
3
|
+
description: "Use this skill for keyboard, pointer, mouse, touch and gamepad input in melonJS. Covers the bindKey action indirection, registerPointerEvent on regions, the isKinematic requirement that silently blocks pointer events, world vs screen pointer coordinates, and gamepad mapping onto the same actions. Triggers on: input, bindKey, isKeyPressed, KEY, registerPointerEvent, releasePointerEvent, pointerdown, pointerup, POINTERMOVE, gamepad, bindGamepad, triggerKeyEvent, click, touch, drag."
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Input: keyboard, pointer and gamepad
|
|
8
|
+
|
|
9
|
+
## Keyboard goes through named actions
|
|
10
|
+
|
|
11
|
+
Do not poll key codes. Bind a key to an **action string**, then poll the action —
|
|
12
|
+
this is what lets gamepad and virtual controls map onto the same handling.
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
import { input } from "melonjs";
|
|
16
|
+
|
|
17
|
+
input.bindKey(input.KEY.LEFT, "left");
|
|
18
|
+
input.bindKey(input.KEY.RIGHT, "right");
|
|
19
|
+
input.bindKey(input.KEY.X, "jump", true); // true = locked: one press per keydown
|
|
20
|
+
|
|
21
|
+
// in update()
|
|
22
|
+
if (input.isKeyPressed("left")) { /* … */ }
|
|
23
|
+
if (input.isKeyPressed("jump")) { /* fires once per press, not per frame */ }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The third argument to `bindKey` is `lock` (default `false`). Without it,
|
|
27
|
+
`isKeyPressed` stays true for as long as the key is held — correct for movement,
|
|
28
|
+
wrong for jump or fire. A locked action stays consumed until the key is released
|
|
29
|
+
or you call `input.unlockKey("jump")`. Use `input.keyStatus(action)` when you
|
|
30
|
+
want the raw held/not-held state regardless of locking.
|
|
31
|
+
|
|
32
|
+
The full signature is `bindKey(keyCode, action, lock?, preventDefault?)`;
|
|
33
|
+
`preventDefault` defaults to `input.preventDefault` (itself `true`). Pass the
|
|
34
|
+
fourth argument per binding, or change the global default with
|
|
35
|
+
`input.setPreventDefault(false)` — **assigning `input.preventDefault = false`
|
|
36
|
+
does not work**, it is a read-only module binding.
|
|
37
|
+
|
|
38
|
+
## Pointer events need `isKinematic = false`
|
|
39
|
+
|
|
40
|
+
**This is the trap.** `Renderable.isKinematic` defaults to `true`, and both the
|
|
41
|
+
broadphase and the pointer dispatcher skip any candidate whose `isKinematic` is
|
|
42
|
+
still `true`. The handler registers successfully and simply never fires.
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
class Button extends Renderable {
|
|
46
|
+
constructor(x, y, w, h) {
|
|
47
|
+
super(x, y, w, h);
|
|
48
|
+
this.isKinematic = false; // ← required
|
|
49
|
+
}
|
|
50
|
+
onActivateEvent() {
|
|
51
|
+
input.registerPointerEvent("pointerdown", this, this.onDown.bind(this));
|
|
52
|
+
}
|
|
53
|
+
onDeactivateEvent() {
|
|
54
|
+
input.releasePointerEvent("pointerdown", this);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`Container`, `Camera2d`, `Draggable`, `DropTarget` and the `UI*` elements set it
|
|
60
|
+
to `false` for you, and so does attaching a physics body (`Body`'s constructor
|
|
61
|
+
sets `ancestor.isKinematic = false`) — so plain `Renderable` and `Sprite`
|
|
62
|
+
subclasses with no body are the ones that catch people.
|
|
63
|
+
|
|
64
|
+
Register in `onActivateEvent` and release in `onDeactivateEvent`, not in the
|
|
65
|
+
constructor — pooled objects are reused and would otherwise accumulate handlers.
|
|
66
|
+
|
|
67
|
+
`app.viewport` works as a whole-screen region when you want global clicks: the
|
|
68
|
+
dispatcher appends it to the candidate list on every event, so it is reachable
|
|
69
|
+
even when nothing else is under the pointer.
|
|
70
|
+
|
|
71
|
+
The accepted event names are exactly `"pointerdown"`, `"pointerup"`,
|
|
72
|
+
`"pointermove"`, `"pointercancel"`, `"pointerenter"`, `"pointerover"`,
|
|
73
|
+
`"pointerleave"` and `"wheel"`. Anything else — `"click"`, `"mousedown"`,
|
|
74
|
+
`"touchstart"` — makes both `registerPointerEvent` and `releasePointerEvent`
|
|
75
|
+
throw `invalid event type`. melonJS maps the canonical name onto whichever
|
|
76
|
+
mouse/touch events the device actually supports, so you always register the
|
|
77
|
+
pointer name.
|
|
78
|
+
|
|
79
|
+
## World coordinates versus screen coordinates
|
|
80
|
+
|
|
81
|
+
The pointer carries several, and picking the wrong one produces a feedback loop:
|
|
82
|
+
|
|
83
|
+
| property | meaning | use for |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| `pointer.gameScreenX` / `gameScreenY` | canvas-relative position | anything that **moves the camera** |
|
|
86
|
+
| `pointer.gameWorldX` / `gameWorldY` | projected into world space | picking and spawning objects |
|
|
87
|
+
| `pointer.gameLocalX` / `gameLocalY` | relative to the region's ancestor container | hit-testing inside a container |
|
|
88
|
+
| `pointer.gameX` / `gameY` | **context-dependent** — see below | region handlers on non-floating regions |
|
|
89
|
+
|
|
90
|
+
`gameX`/`gameY` is not a fixed coordinate space. The dispatcher rewrites it per
|
|
91
|
+
candidate just before calling your handler: world coordinates for a normal
|
|
92
|
+
region, screen coordinates for a `isFloating === true` region. On the global
|
|
93
|
+
`event.POINTERMOVE` broadcast it is set to the **screen** coordinates. When you
|
|
94
|
+
need one specific space, read `gameWorldX`/`gameWorldY` or
|
|
95
|
+
`gameScreenX`/`gameScreenY` by name rather than relying on `gameX`.
|
|
96
|
+
|
|
97
|
+
Using world coordinates for a camera-orbit drag means the same pixel maps to a
|
|
98
|
+
different world point every frame as the camera moves — the drag jumps wildly.
|
|
99
|
+
|
|
100
|
+
## Pointer move and release outside a region
|
|
101
|
+
|
|
102
|
+
Region handlers only fire while the pointer is over the region. For drag
|
|
103
|
+
tracking, listen globally:
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
import { event } from "melonjs";
|
|
107
|
+
event.on(event.POINTERMOVE, (pointer) => { /* … */ });
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
There is **no global pointer-up system event** — `event.ts` publishes only
|
|
111
|
+
`POINTERMOVE`, `POINTERLOCKCHANGE`, `DRAGSTART` and `DRAGEND`. For "released
|
|
112
|
+
anywhere" you need a raw listener:
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
globalThis.addEventListener("pointerup", onRelease);
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
For plain drag-and-drop, `Draggable` / `DropTarget` already wire all of this up
|
|
119
|
+
(`pointerdown` / `pointerup` / `pointercancel` regions plus a global
|
|
120
|
+
`POINTERMOVE` listener) and emit `event.DRAGSTART` / `event.DRAGEND`. `DRAGEND`
|
|
121
|
+
still originates from a region handler, so it only fires when the release lands
|
|
122
|
+
on the draggable itself.
|
|
123
|
+
|
|
124
|
+
## Gamepad
|
|
125
|
+
|
|
126
|
+
Gamepad input maps onto the same action strings, so game code does not branch:
|
|
127
|
+
|
|
128
|
+
```js
|
|
129
|
+
input.bindGamepad(0,
|
|
130
|
+
{ type: "buttons", code: input.GAMEPAD.BUTTONS.FACE_1 },
|
|
131
|
+
input.KEY.X); // → the "jump" action bound above
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**Order matters:** `bindGamepad` throws `no action defined for keycode N` if the
|
|
135
|
+
keycode has not already been passed to `bindKey`. Axes use the same call with a
|
|
136
|
+
threshold: `{ type: "axes", code: input.GAMEPAD.AXES.LX, threshold: -0.5 }`.
|
|
137
|
+
`unbindGamepad(index, button)`, `setGamepadDeadzone(value)` and
|
|
138
|
+
`setGamepadMapping(id, mapping)` complete the surface.
|
|
139
|
+
|
|
140
|
+
## Virtual controls
|
|
141
|
+
|
|
142
|
+
On-screen buttons synthesise key events, again reaching the same actions:
|
|
143
|
+
|
|
144
|
+
```js
|
|
145
|
+
input.triggerKeyEvent(input.KEY.LEFT, true); // press
|
|
146
|
+
input.triggerKeyEvent(input.KEY.LEFT, false); // release
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Symptom → cause
|
|
150
|
+
|
|
151
|
+
| symptom | cause |
|
|
152
|
+
|---|---|
|
|
153
|
+
| pointer handler never fires | `isKinematic` left at its `true` default |
|
|
154
|
+
| handlers fire twice, or on dead objects | registered in the constructor instead of `onActivateEvent` |
|
|
155
|
+
| camera drag jumps around | using world coordinates instead of `gameScreenX`/`gameScreenY` |
|
|
156
|
+
| `gameX` holds screen coords where world coords were expected | read on `event.POINTERMOVE`, or on a floating region — use `gameWorldX`/`gameWorldY` |
|
|
157
|
+
| drag stops when leaving the object | region events end at the region — use `event.POINTERMOVE` |
|
|
158
|
+
| release never detected outside the region | no global pointer-up event — add a raw listener |
|
|
159
|
+
| jump fires every frame while held | `bindKey` without its third `lock` argument |
|
|
160
|
+
| `invalid event type` thrown at registration | non-pointer name (`"click"`, `"mousedown"`, …) passed to `registerPointerEvent` |
|
|
161
|
+
| `no action defined for keycode N` | `bindGamepad` called before `bindKey` for that keycode |
|
|
162
|
+
|
|
163
|
+
## Related skills
|
|
164
|
+
|
|
165
|
+
- `melonjs-renderables` — `isKinematic` also gates the physics broadphase
|
|
166
|
+
- `melonjs-ui-and-text` — `UISpriteElement` and `UITextButton` handle this for you
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: melonjs-lighting
|
|
3
|
+
description: "Use this skill for 2D dynamic lighting in melonJS — Light2d, ambient light on a Stage, multiple lights, and per-pixel normal-mapped sprites authored in SpriteIlluminator. Covers the ambient-cutout model, which parts need a GPU backend, and why Light2d does not survive a Camera3d. Triggers on: Light2d, lighting, ambientLight, ambientLightingColor, normalMap, SpriteIlluminator, per-pixel lighting, drawLight, torch, glow, darkness."
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# 2D dynamic lighting
|
|
8
|
+
|
|
9
|
+
> `Light2d` is a world renderable that cuts through a stage's ambient darkness.
|
|
10
|
+
> The glow and the cutout work on every backend; only per-pixel normal-map
|
|
11
|
+
> shading needs a GPU one. It is 2D-only.
|
|
12
|
+
|
|
13
|
+
## The model: ambient darkness plus cutouts
|
|
14
|
+
|
|
15
|
+
The `Stage` holds an ambient colour — a dark sheet painted over the scene after
|
|
16
|
+
the world is drawn — and each active `Light2d` punches a hole in it at its
|
|
17
|
+
visible area. The lights themselves are drawn additively on top.
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
class PlayScreen extends Stage {
|
|
21
|
+
onResetEvent(app) {
|
|
22
|
+
this.ambientLight.parseCSS("#1a1a2e"); // the darkness
|
|
23
|
+
|
|
24
|
+
app.world.addChild(new Light2d(x, y, radiusX, radiusY, "#ffddaa", 0.9));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The constructor is `Light2d(x, y, radiusX, radiusY = radiusX, color = "#FFF",
|
|
30
|
+
intensity = 0.7)`, and `pos` is the light's **centre** — its `anchorPoint` is
|
|
31
|
+
`(0.5, 0.5)`, and `centerX` / `centerY` are overridden to return `pos` directly.
|
|
32
|
+
Give `radiusY` a different value for a stretched, elliptical light.
|
|
33
|
+
|
|
34
|
+
A `Light2d` added to the world **registers itself with the stage's ambient
|
|
35
|
+
overlay on activate**, so you add it like any other renderable and it takes part
|
|
36
|
+
in the lighting pass. It draws additively (`blendMode = "lighter"`); set
|
|
37
|
+
`light.illuminationOnly = true` to suppress the visible glow while still lighting
|
|
38
|
+
normal-mapped sprites.
|
|
39
|
+
|
|
40
|
+
`Stage.ambientLight` defaults to fully transparent black, and `drawLighting()`
|
|
41
|
+
returns immediately while its alpha is 0 — so with no ambient colour set there
|
|
42
|
+
is nothing to cut through and the lights just look like soft additive blobs.
|
|
43
|
+
|
|
44
|
+
## Multiple lights
|
|
45
|
+
|
|
46
|
+
Add as many as you need — the glow quads and the ambient cutouts accumulate with
|
|
47
|
+
no fixed cap.
|
|
48
|
+
|
|
49
|
+
The **normal-map** pipeline is capped: lights are packed into a std140 uniform
|
|
50
|
+
block sized for `MAX_LIGHTS = 32`, and anything past the 32nd is silently dropped
|
|
51
|
+
from the per-pixel shading (it still draws its glow and punches its cutout). The
|
|
52
|
+
cap is an allocation, not a budget — the fragment loop still runs once per pixel
|
|
53
|
+
per live light.
|
|
54
|
+
|
|
55
|
+
Lights are positioned like any renderable, so they can follow an entity by
|
|
56
|
+
updating `pos`, or be added as children of one.
|
|
57
|
+
|
|
58
|
+
## Per-pixel lighting with normal maps
|
|
59
|
+
|
|
60
|
+
For sprites that respond to light direction rather than just brightness, supply a
|
|
61
|
+
normal map alongside the diffuse texture:
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
await loader.preload([
|
|
65
|
+
{ name: "hero", type: "image", src: "data/img/hero.png" },
|
|
66
|
+
{ name: "hero_n", type: "image", src: "data/img/hero_n.png" },
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
const hero = new Sprite(x, y, {
|
|
70
|
+
image: "hero",
|
|
71
|
+
normalMap: "hero_n", // ← enables per-pixel lighting on this sprite
|
|
72
|
+
framewidth: 32, frameheight: 32,
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`normalMap` takes a loader key, or any image-like source (`HTMLImageElement`,
|
|
77
|
+
canvas, `ImageBitmap`, a `Texture2d`). Assigning anything else — including an
|
|
78
|
+
`HTMLVideoElement`, which would freeze on frame 0 — throws a `TypeError`.
|
|
79
|
+
|
|
80
|
+
Normal maps are typically authored in **SpriteIlluminator**. The sidecar pattern
|
|
81
|
+
above — one `_n` image beside each diffuse image — is the simplest setup, but an
|
|
82
|
+
atlas can carry one too: `new TextureAtlas(json, image, { normalMap })` pairs a
|
|
83
|
+
normal texture sharing the colour texture's UVs, and a `Sprite` built from that
|
|
84
|
+
atlas picks it up in preference to its own `settings.normalMap`.
|
|
85
|
+
|
|
86
|
+
Unlit areas of a normal-mapped sprite render pure black unless you raise
|
|
87
|
+
`Stage.ambientLightingColor` (default black) — that is the base level added to
|
|
88
|
+
every lit pixel, and it is a different knob from `Stage.ambientLight`.
|
|
89
|
+
|
|
90
|
+
Without a normal map a sprite is still lit, but flatly: brightness varies with
|
|
91
|
+
distance from the light, not with surface direction.
|
|
92
|
+
|
|
93
|
+
## What needs a GPU backend, and what does not
|
|
94
|
+
|
|
95
|
+
Less than you would expect. `Light2d` is renderer-agnostic: it just calls
|
|
96
|
+
`renderer.drawLight(this)`, and every backend implements it — the GPU backends
|
|
97
|
+
through a shared procedural radial-falloff shader, the Canvas renderer by
|
|
98
|
+
rasterising a cached `Gradient` into one shared render target and compositing it
|
|
99
|
+
with `drawImage`. The ambient cutout pass is plain `setMask` + `fillRect`. So the
|
|
100
|
+
lit-spot look works everywhere, Canvas included.
|
|
101
|
+
|
|
102
|
+
What Canvas cannot do is **per-pixel normal-map lighting**:
|
|
103
|
+
`renderer.setLightUniforms()` is a no-op there, and the first frame that passes a
|
|
104
|
+
non-empty light list logs a one-shot warning. Normal-mapped sprites simply render
|
|
105
|
+
unlit — no error.
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
if (app.renderer.shaderLanguage === null) {
|
|
109
|
+
// Canvas fallback: lights and ambient still work, but `normalMap` is ignored
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Do not combine with `Camera3d`
|
|
114
|
+
|
|
115
|
+
`Camera3d` extends `Camera2d` and therefore still runs the 2D lighting pass, but
|
|
116
|
+
nothing in that pass is projection-aware: the ambient fill is a screen-space
|
|
117
|
+
`fillRect`, the cutout is a 2D `Ellipse` mask, and light positions are packed as
|
|
118
|
+
2D world coordinates minus the camera translate. Under a perspective projection
|
|
119
|
+
none of that lines up with what the camera actually draws.
|
|
120
|
+
|
|
121
|
+
For 3D scenes use `Light3d` instead — it is the counterpart for the mesh
|
|
122
|
+
lighting path, with `"directional"`, `"ambient"`, `"point"` and `"spot"` types.
|
|
123
|
+
See the `melonjs-3d` skill.
|
|
124
|
+
|
|
125
|
+
## Symptom → cause
|
|
126
|
+
|
|
127
|
+
| symptom | cause |
|
|
128
|
+
|---|---|
|
|
129
|
+
| lights added but the scene never darkens | no ambient colour set — `ambientLight` alpha is 0, so the pass returns early |
|
|
130
|
+
| sprite lit flatly, ignoring light direction | no `normalMap` on the sprite, or the Canvas backend is active |
|
|
131
|
+
| normal-mapped sprite is pure black where unlit | `Stage.ambientLightingColor` left at black |
|
|
132
|
+
| the 33rd light shades nothing | `MAX_LIGHTS = 32` for the normal-map pipeline |
|
|
133
|
+
| `TypeError` assigning `normalMap` | not an image-like value (a video element is rejected outright) |
|
|
134
|
+
| lighting misaligned under a 3D camera | the 2D light pass is not projection-aware — use `Light3d` |
|
|
135
|
+
|
|
136
|
+
## Related skills
|
|
137
|
+
|
|
138
|
+
- `melonjs-3d` — `Light3d` for perspective scenes
|
|
139
|
+
- `melonjs-sprites-and-animation` — sprite settings and atlases
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: melonjs-loading-assets
|
|
3
|
+
description: "Use this skill for loading and managing game assets in melonJS — the resource descriptor format, the full asset type list, preload versus load, retrieving loaded assets, base URLs and cross-origin settings, and the loading screen. Triggers on: loader, loader.preload, loader.load, resources, getImage, getJSON, getTMX, getGLTF, getVideo, getFont, setBaseURL, setOptions, crossOrigin, withCredentials, credentials, cookies, authenticated assets, CORS, asset, preload, LOADER_COMPLETE, loading screen, unload."
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Loading assets
|
|
8
|
+
|
|
9
|
+
## The resource descriptor
|
|
10
|
+
|
|
11
|
+
Every asset is `{ name, type, src }` plus type-specific extras:
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import { loader } from "melonjs";
|
|
15
|
+
|
|
16
|
+
loader.setOptions({ crossOrigin: "anonymous" }); // needed for remote assets
|
|
17
|
+
|
|
18
|
+
await loader.preload([
|
|
19
|
+
{ name: "tiles", type: "image", src: "data/img/tiles.png" },
|
|
20
|
+
{ name: "map1", type: "tmx", src: "data/map/map1.tmx" },
|
|
21
|
+
{ name: "tileset", type: "tsx", src: "data/map/tileset.tsx" },
|
|
22
|
+
{ name: "sfx", type: "audio", src: "data/sfx/" },
|
|
23
|
+
{ name: "font", type: "fontface", src: "data/font/PressStart2P.ttf" },
|
|
24
|
+
{ name: "atlas", type: "json", src: "data/img/atlas.json" },
|
|
25
|
+
]);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`preload()` has been awaitable since 19.8. The callback form still works and
|
|
29
|
+
takes a third argument to suppress the built-in loading screen:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
loader.preload(resources, onLoaded, /* switchToLoadState */ false);
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## The type list
|
|
36
|
+
|
|
37
|
+
The type strings are melonJS-specific — this is not a generic loader:
|
|
38
|
+
|
|
39
|
+
| type | for |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `"image"` | textures, sprite sheets, normal maps |
|
|
42
|
+
| `"json"` | data, texture-atlas descriptors |
|
|
43
|
+
| `"tmx"` / `"tsx"` | Tiled maps and external tilesets |
|
|
44
|
+
| `"audio"` | sound — **`src` is a directory**, see below |
|
|
45
|
+
| `"video"` | video textures |
|
|
46
|
+
| `"binary"` | raw data, bitmap font `.fnt` descriptors |
|
|
47
|
+
| `"fontface"` | web fonts (`.ttf`, `.woff`) |
|
|
48
|
+
| `"aseprite"` | Aseprite JSON + image |
|
|
49
|
+
| `"shader"` | GLSL/WGSL shader sources |
|
|
50
|
+
| `"obj"` / `"mtl"` | Wavefront models and materials |
|
|
51
|
+
| `"gltf"` / `"glb"` | glTF scenes |
|
|
52
|
+
| `"js"` | scripts |
|
|
53
|
+
|
|
54
|
+
## Two conventions that produce 404s
|
|
55
|
+
|
|
56
|
+
**Audio `src` is a directory.** The loader appends the asset name plus each
|
|
57
|
+
format from `audio.init()`, and picks the first that decodes:
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
audio.init("mp3,ogg"); // before preloading audio
|
|
61
|
+
{ name: "cling", type: "audio", src: "data/sfx/" } // → data/sfx/cling.mp3
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
A full filename here gives you a 404. And `audio.init()` must run **before** any
|
|
65
|
+
audio asset is preloaded.
|
|
66
|
+
|
|
67
|
+
**A Tiled map needs its dependencies listed too** — the `.tmx`, any external
|
|
68
|
+
`.tsx`, and the tileset images. Listing only the map produces a blank level.
|
|
69
|
+
|
|
70
|
+
## Retrieving loaded assets
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
loader.getImage("tiles");
|
|
74
|
+
loader.getJSON("atlas");
|
|
75
|
+
loader.getTMX("map1");
|
|
76
|
+
loader.getGLTF("diorama");
|
|
77
|
+
loader.getVideo("intro");
|
|
78
|
+
loader.getFont("font");
|
|
79
|
+
loader.getBinary("font-fnt");
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Most engine classes take the asset **name** directly, so you often do not need
|
|
83
|
+
these — `new Sprite(x, y, { image: "tiles" })` resolves it for you.
|
|
84
|
+
|
|
85
|
+
## Base URLs
|
|
86
|
+
|
|
87
|
+
Set a prefix per asset type rather than repeating it:
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
loader.setBaseURL("image", "data/img/");
|
|
91
|
+
loader.setBaseURL("audio", "data/sfx/");
|
|
92
|
+
loader.setBaseURL("*", "https://cdn.example.com/"); // every 2D type at once
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The `"*"` wildcard deliberately **skips `obj`, `mtl`, `gltf` and `glb`**: those
|
|
96
|
+
resolve their own internal references (a `map_Kd` texture, a glTF `.bin`)
|
|
97
|
+
relative to their file, so a global prefix would double-prefix them. Set those
|
|
98
|
+
types individually.
|
|
99
|
+
|
|
100
|
+
## Progress and completion
|
|
101
|
+
|
|
102
|
+
Use the events. The old callback properties (`loader.onload`, `onProgress`,
|
|
103
|
+
`onError`) were deprecated in 18.2 and **removed in 20.3** — being `let`
|
|
104
|
+
bindings on an ES module namespace they could never be assigned from outside in
|
|
105
|
+
the first place, so `loader.onProgress = fn` always threw a `TypeError`:
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
import { event } from "melonjs";
|
|
109
|
+
|
|
110
|
+
event.on(event.LOADER_PROGRESS, (progress) => { /* 0..1 */ });
|
|
111
|
+
event.on(event.LOADER_COMPLETE, () => { /* … */ });
|
|
112
|
+
event.on(event.LOADER_ERROR, (res) => { /* … */ });
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Unloading
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
loader.unload({ name: "map1", type: "tmx" });
|
|
119
|
+
loader.unloadAll();
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`unloadAll()` also releases audio and GPU resources such as shader programs, so
|
|
123
|
+
it is the right teardown for switching between large levels.
|
|
124
|
+
|
|
125
|
+
## Loading between scenes
|
|
126
|
+
|
|
127
|
+
The default loading screen appears automatically when `preload` switches state.
|
|
128
|
+
For a custom one, register a `Stage` against `state.LOADING`:
|
|
129
|
+
|
|
130
|
+
```js
|
|
131
|
+
state.set(state.LOADING, new MyLoadingScreen());
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
If you preload without a loading stage and then change state immediately, pass
|
|
135
|
+
`forceChange`:
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
state.change(state.PLAY, true);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Cross-origin and authenticated assets
|
|
142
|
+
|
|
143
|
+
Two settings, both global and both applying to **every** asset type — there is
|
|
144
|
+
no per-asset or per-type spelling to remember:
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
loader.setOptions({
|
|
148
|
+
crossOrigin: "anonymous", // CORS mode for remote assets
|
|
149
|
+
withCredentials: true, // send cookies / auth with the request
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`withCredentials` is what an asset behind a session cookie or an
|
|
154
|
+
`Authorization`-style login needs. Every fetched asset — image, json, binary,
|
|
155
|
+
tmx, tsx, shader, gltf/glb, obj, mtl, aseprite, video — carries it, and so does
|
|
156
|
+
buffered audio.
|
|
157
|
+
|
|
158
|
+
**Set them through `setOptions`.** `loader.crossOrigin` and
|
|
159
|
+
`loader.withCredentials` are read-only module bindings; assigning to them
|
|
160
|
+
throws, the same trap as the removed `loader.onload` / `onProgress`.
|
|
161
|
+
|
|
162
|
+
| | |
|
|
163
|
+
| --- | --- |
|
|
164
|
+
| one streamed clip (`stream: true` / `html5: true`) ignores `withCredentials` | it plays through an `<audio>` element, which needs a `crossorigin` attribute rather than fetch credentials. Preload it buffered if it is behind auth |
|
|
165
|
+
| credentials silently dropped for audio before 20.4 | the loader forwarded them under a pre-20.3 name the backend never read — a hung preload rather than an error |
|
|
166
|
+
|
|
167
|
+
## Symptom → cause
|
|
168
|
+
|
|
169
|
+
| symptom | cause |
|
|
170
|
+
|---|---|
|
|
171
|
+
| audio 404s | `src` given as a file instead of a directory |
|
|
172
|
+
| audio fails, `preload()` rejects with "Failed loading resource" | `audio.init()` not called before preloading — the real message is replaced by the loader's |
|
|
173
|
+
| blank level, missing tiles | `.tsx` or tileset image not listed in the resources |
|
|
174
|
+
| cross-origin textures fail | missing `loader.setOptions({ crossOrigin: "anonymous" })` |
|
|
175
|
+
| assets behind a login 401 / audio preload hangs | missing `loader.setOptions({ withCredentials: true })` — one switch, all asset types |
|
|
176
|
+
| `TypeError` assigning `loader.withCredentials` / `crossOrigin` | read-only module bindings; use `loader.setOptions({ … })` |
|
|
177
|
+
| preload never finishes, blank screen, no error | a failing sound with `audio.setStopOnAudioError(false)` before 20.4 — it disabled audio *and* failed the preload |
|
|
178
|
+
| text renders in a fallback font | web font not preloaded as `"fontface"` |
|
|
179
|
+
| `BitmapText` renders nothing | the `.fnt` (as `"binary"`) or its image is missing |
|
|
180
|
+
| `TypeError` assigning `loader.onProgress` / `onload` | removed in 20.3; they were never writable — use the `LOADER_*` events |
|
|
181
|
+
|
|
182
|
+
## Related skills
|
|
183
|
+
|
|
184
|
+
- `melonjs-getting-started` — where preloading sits in the bootstrap
|
|
185
|
+
- `melonjs-tilemaps` — the full Tiled asset set
|
|
186
|
+
- `melonjs-audio` — formats and the directory convention
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: melonjs-particles-and-trails
|
|
3
|
+
description: "Use this skill for particle effects and motion trails in melonJS — ParticleEmitter configuration, burst versus stream emission, the referenceSpace frame of reference introduced in 20.2, and the Trail renderable. Covers the emitter that silently does nothing until you call an emit method. Triggers on: ParticleEmitter, particles, burstParticles, streamParticles, referenceSpace, ParticleEmitterSettings, Trail, explosion, smoke, sparks, exhaust, emitter."
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Particles and trails
|
|
8
|
+
|
|
9
|
+
## An emitter does nothing until you tell it to emit
|
|
10
|
+
|
|
11
|
+
Adding a `ParticleEmitter` to the world is not enough. Nothing appears, and
|
|
12
|
+
nothing warns you.
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
const emitter = new ParticleEmitter(x, y, {
|
|
16
|
+
image: loader.getImage("spark"),
|
|
17
|
+
totalParticles: 60,
|
|
18
|
+
speed: 4,
|
|
19
|
+
minLife: 200, maxLife: 800,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
world.addChild(emitter);
|
|
23
|
+
emitter.streamParticles(); // continuous — or:
|
|
24
|
+
emitter.burstParticles(); // one shot
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`streamParticles(ms)` takes an optional run time; without one it uses the
|
|
28
|
+
`duration` setting, which defaults to `Infinity` — a stream runs until
|
|
29
|
+
`stopStream()`. `burstParticles(n)` launches `n`, or `totalParticles`.
|
|
30
|
+
|
|
31
|
+
For one-shot effects, `autoDestroyOnComplete: true` removes the emitter once its
|
|
32
|
+
particles have finished. The `onComplete` callback fires at that same moment
|
|
33
|
+
either way.
|
|
34
|
+
|
|
35
|
+
For repeated effects (muzzle flashes, impacts) keep **one** long-lived emitter
|
|
36
|
+
and re-aim it per shot, rather than allocating an emitter per event.
|
|
37
|
+
|
|
38
|
+
## `referenceSpace` — which frame particles live in
|
|
39
|
+
|
|
40
|
+
Added in 20.2. This decides what a particle's position is measured *from*, and
|
|
41
|
+
it is the difference between an effect that trails behind a moving object and
|
|
42
|
+
one that drags along with it.
|
|
43
|
+
|
|
44
|
+
| value | particles are measured from | use for |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `"local"` (default) | the emitter | flames, auras, anything welded to the object |
|
|
47
|
+
| `"world"` | the container the emitter sits in | **trails, smoke, exhaust, dust** |
|
|
48
|
+
| a `Container` | that container | a moving frame — snow inside a moving carriage |
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
// exhaust that stays where it was emitted, so the ship flies away from it
|
|
52
|
+
const exhaust = new ParticleEmitter(x, y, { referenceSpace: "world", /* … */ });
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
With the default `"local"`, a moving emitter carries its whole cloud along —
|
|
56
|
+
which is right for a torch flame and wrong for a smoke trail. Changing it at
|
|
57
|
+
runtime re-bases live particles, so nothing jumps.
|
|
58
|
+
|
|
59
|
+
## Particle tuning changed in 20.2
|
|
60
|
+
|
|
61
|
+
The 20.2 particle transform fix corrected a drift where drawn positions ran past
|
|
62
|
+
simulated ones. Particles now travel roughly **half as far** over their life as
|
|
63
|
+
they did before.
|
|
64
|
+
|
|
65
|
+
Consequence: **speed values tuned on 19.x or earlier look wrong on 20.2+.** If
|
|
66
|
+
you are copying emitter settings from older code or older tutorials, expect to
|
|
67
|
+
raise `speed` or `maxLife`.
|
|
68
|
+
|
|
69
|
+
## Trails
|
|
70
|
+
|
|
71
|
+
`Trail` is a ribbon that follows a target — use it rather than hand-rolling a
|
|
72
|
+
position history. **Its constructor takes one argument, the options object** —
|
|
73
|
+
no `x, y` pair like every other renderable:
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
const trail = new Trail({
|
|
77
|
+
target: sprite, // a renderable or a plain Vector2d
|
|
78
|
+
length: 24, // max points kept (default 20)
|
|
79
|
+
width: 20, // max ribbon width in px (default 10)
|
|
80
|
+
lifetime: 500, // per-point lifetime in ms (default 500)
|
|
81
|
+
widthCurve: [1, 0], // 0 = head, 1 = tail
|
|
82
|
+
gradient: ["#fff", "#f80", "#f000"],
|
|
83
|
+
});
|
|
84
|
+
trail.blendMode = "additive";
|
|
85
|
+
world.addChild(trail, 5);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Omit `target` and feed it yourself with `trail.addPoint(x, y)` — the mode for a
|
|
89
|
+
sword slash, where the ribbon follows a weapon tip rather than an object. Points
|
|
90
|
+
closer together than `minDistance` (default 4 px) are dropped.
|
|
91
|
+
|
|
92
|
+
**`Trail` is 2D.** `addPoint` takes `(x, y)`, points are stored without a `z`,
|
|
93
|
+
and the ribbon is drawn as connected screen-space quads. Under a `Camera3d` it
|
|
94
|
+
draws a flat ribbon that does not recede with perspective — so it is the wrong
|
|
95
|
+
tool for a trail behind an object moving *into* the scene. For that:
|
|
96
|
+
|
|
97
|
+
- **`ParticleEmitter` with `referenceSpace: "world"`** — particles stay where
|
|
98
|
+
they were dropped while the emitter moves on, and the emitter propagates its
|
|
99
|
+
depth to each particle so `Camera3d` projects them correctly. This is the
|
|
100
|
+
built-in answer for exhaust, ski tracks and speed trails in 3D.
|
|
101
|
+
- **A procedural `Mesh`** built from the object's recent path, with
|
|
102
|
+
`mesh.vertexColors` for a per-vertex gradient — more work, but a continuous
|
|
103
|
+
ribbon rather than discrete puffs.
|
|
104
|
+
|
|
105
|
+
## Performance
|
|
106
|
+
|
|
107
|
+
- Particles come from a shared pool, so a steady-state emitter allocates
|
|
108
|
+
nothing. Each emitter is still a `Container` that updates and draws every
|
|
109
|
+
frame, so one busy emitter beats many idle ones.
|
|
110
|
+
- `totalParticles` (default 50) is a cap on how many are alive at once in stream
|
|
111
|
+
mode; `burstParticles()` launches that many in one go, or the count you pass.
|
|
112
|
+
- `framesToSkip` (default 0) skips n updates between simulation steps — the
|
|
113
|
+
cheapest lever on an emitter with many particles.
|
|
114
|
+
- Blending is per particle, set through the `blendMode` setting or by assigning
|
|
115
|
+
`emitter.blendMode` (which reaches the particles already alive as well as
|
|
116
|
+
later ones). Additive is cheap everywhere: fixed-function on both GPU
|
|
117
|
+
backends, native `lighter` on Canvas. The expensive modes are the advanced CSS
|
|
118
|
+
ones (`overlay`, `soft-light`, `color-dodge`, `darken`, …), which on WebGL 2
|
|
119
|
+
and WebGPU cost a destination capture plus a shader composite *per blended
|
|
120
|
+
draw*.
|
|
121
|
+
|
|
122
|
+
## Symptom → cause
|
|
123
|
+
|
|
124
|
+
| symptom | cause |
|
|
125
|
+
|---|---|
|
|
126
|
+
| trail looks flat under a `Camera3d` | `Trail` is 2D — use a world-space emitter or a ribbon mesh |
|
|
127
|
+
| emitter added but nothing appears | `streamParticles()` / `burstParticles()` never called |
|
|
128
|
+
| the cloud follows a moving emitter | default `referenceSpace: "local"` — use `"world"` for trails |
|
|
129
|
+
| particles do not travel far enough | settings tuned pre-20.2, when drawn travel was doubled |
|
|
130
|
+
| one-shot emitters accumulate | missing `autoDestroyOnComplete: true` |
|
|
131
|
+
| frame rate drops with many effects | an emitter per event instead of one re-aimed emitter |
|
|
132
|
+
|
|
133
|
+
## Related skills
|
|
134
|
+
|
|
135
|
+
- `melonjs-renderables` — draw order and blend modes
|
|
136
|
+
- `melonjs-effects-and-shaders` — blend mode cost on each backend
|