littlejsengine 1.24.1 → 1.24.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +78 -1
  2. package/EDITOR.md +2 -0
  3. package/FAQ.md +13 -2
  4. package/README.md +1 -1
  5. package/REFERENCE.md +22 -7
  6. package/dist/littlejs.d.ts +204 -118
  7. package/dist/littlejs.esm.js +2479 -1983
  8. package/dist/littlejs.esm.min.js +3 -3
  9. package/dist/littlejs.js +2476 -1983
  10. package/dist/littlejs.min.js +2 -2
  11. package/dist/littlejs.release.js +2434 -1990
  12. package/package.json +1 -1
  13. package/plugins/box2d.js +9 -5
  14. package/plugins/gltf.js +67 -9
  15. package/plugins/lightSystem.js +1 -1
  16. package/plugins/math3d.js +1014 -1013
  17. package/plugins/medalSystem.js +7 -11
  18. package/plugins/particleEffects.js +2 -2
  19. package/plugins/pathFinder.js +2 -2
  20. package/plugins/pluginExport.js +1 -0
  21. package/plugins/render3d.js +131 -55
  22. package/plugins/render3dEditor.js +24 -10
  23. package/plugins/render3dExtras.js +41 -25
  24. package/plugins/render3dLevel.js +21 -12
  25. package/plugins/render3dVoxels.js +2 -2
  26. package/plugins/textureSheet.js +109 -7
  27. package/plugins/tweakables.js +1 -1
  28. package/plugins/tweenSystem.js +2 -2
  29. package/plugins/uiSystem.js +6 -2
  30. package/src/engine.js +60 -23
  31. package/src/engineAudio.js +16 -6
  32. package/src/engineBuild.mjs +49 -2
  33. package/src/engineDebug.js +4 -1
  34. package/src/engineDraw.js +40 -25
  35. package/src/engineEditor.js +82 -50
  36. package/src/engineExport.js +2 -0
  37. package/src/engineInput.js +21 -4
  38. package/src/engineMath.js +6 -2
  39. package/src/engineObject.js +675 -675
  40. package/src/engineParticles.js +1 -1
  41. package/src/engineSettings.js +16 -0
  42. package/src/engineTileLayer.js +85 -22
  43. package/src/engineUtilities.js +20 -8
  44. package/src/engineWebGL.js +15 -11
package/CHANGELOG.md CHANGED
@@ -7,6 +7,79 @@ What changed in each release, newest first. Releases before 1.20.0 are on the
7
7
 
8
8
  Nothing yet.
9
9
 
10
+ ## 1.24.3 - 2026-10-03
11
+
12
+ ### Fixes
13
+
14
+ - TypeScript: the d.ts keeps `undefined` where a value may be missing, so a game in strict mode can write `render3D.shader = undefined` and is told `light.flare`, `levelEditor.edit3D` or `uiSystem.keyInputObject` may be undefined; a game not in strict mode reads the same types as before
15
+ - `box2d.boxCast` and `boxCastAll` say that they test each shape's bounding box, which can find an object near the corner of a turned box or a circle that the box does not touch
16
+ - An image that failed to load gives tiles of no size, which draw nothing, where `tile()` gave NaN places in release builds and stopped debug builds at an assert; a texture slot never given an image still asserts in debug
17
+ - A release build says when a sound, a `loadSprite` or a `loadAtlas` fails to load, as it did for textures and tile sets
18
+ - A `Box2dObject` keeps one `pos` for life, moved in place each step as an EngineObject's is, so a camera holding it follows the body
19
+ - `drawRectGradient` takes no size, as its docs say
20
+ - A release build going on past an error logs each new error, not only the first, and an error every tick no longer runs the game at the screen's refresh rate
21
+ - Under pointer lock a click is a press wherever the locked mouse was left, a letterbox bar too
22
+ - A gamepad with no sticks keeps the one its d-pad stands in for, where its stick count flickered
23
+ - A zzfx `Sound` made in a browser with no audio counts as loaded and plays nothing, where it threw
24
+ - `glCompileShader`, `glCreateProgram` and `glCreateTexture` are typed as giving undefined with no WebGL
25
+ - A release build going on past an error clears that frame's input, where a key press whose action threw was pressed again every frame
26
+ - `loadSprite`, `loadTiles` and `loadAtlas` forget a load whose file failed, so loading it again tries again, where a failure once was kept for the session
27
+ - glTF: a file the model names in subfolders is found when what is in its folder was dropped, not the folder, and a file found by its name alone may have capitals in it, where both said the file was not among those given; the 3D Mesh short keeps a dropped folder's name when other files come with it
28
+
29
+ ## 1.24.2 - 2026-10-03
30
+
31
+ ### New Changes
32
+
33
+ - Tile sets from separate images: `loadTiles(['grass.png', 'brick.png', 'props.png'], 16)` packs tile images, or several tile sheets, into the texture sheets as one tile set, numbered in the order given, for `tileLayersLoad`, tile layers and the level editor's palette; an image that is not whole tiles gives the whole tiles in it, and a map's tileset margin or spacing does not replace the set
34
+ - Spotlight gels: `light.gel` is a picture the shadow casting spotlight shines through, cast along its beam in its colors, like a slide or stained glass; with none a scene draws exactly as before. The 3D First Person flashlight has one on G
35
+ - Less garbage each frame: objects are sorted only when one is out of render order and the destroyed taken out only when there are some, an object with mass that collides with nothing copies no position, and outlines and regular polygons are made into kept vectors, about 98 fewer for each outlined circle; a 3D pick makes no vectors for an object it misses
36
+ - `Mesh.computeNormals(true)` is 5 to 7 times faster, the same normals to the last bit: a 960 point flag in 0.24 ms where it took 1.8, so a mesh can be bent every frame
37
+ - `loadSprite`, `loadTiles` and `loadAtlas` give back what the first load did when the same image is loaded again with the same settings, packed once
38
+ - A release build goes on past an error in a frame, logging the first, where one error froze the game for good; a debug build stops and shows it as before
39
+
40
+ ### Fixes
41
+
42
+ - A Tiled property named as a method of the object it is for, like `update`, is left out, where it replaced the method; a debug build says so
43
+ - `noise2D` stays noise however far out y is, where past about 24 million every row was one value; it gives the same values as before everywhere else
44
+ - Medals: the save keeps the unlock of a medal the game has not made this time, and a medal made after `medalsInit` reads its unlock, so a medal made late or behind a flag is never lost; `medalsReset` locks those too
45
+ - Older browsers: the engine starts with no `OffscreenCanvas` (Safari before 16.4), drawing into a canvas element in its place, and so do the textures it makes itself (normal maps from heights, particle shapes, light glows, lens flares, glTF's white texture), and uses neither `Array.prototype.at` nor `Object.hasOwn` (Safari before 15.4); the example browser's markdown has no lookbehind, which Safari before 16.4 could not read
46
+ - On an iPhone the silent switch mutes the game, as it does a ringtone, and the player's music plays on beside it; `setSoundIgnoreSilentSwitch(true)` has the game play through the switch as media does (Safari 16.4 and up)
47
+ - Level editor: the brush, its ghost and the palette read a tile past the end of a sheet as nothing, as the layer draws it, where a collision value picked up with the right button asserted every frame; the palette of a tile set filled in after it was first shown shows its tiles
48
+ - A light's flare looks past four lamps around it to what is behind them, where the fourth counted as hidden
49
+ - A click or tap in the bars around a letterboxed canvas presses nothing, where it pressed whatever was at the canvas edge
50
+ - `showConfirmDialog` while one is open gives the one open, where a second broke UI navigation in release builds
51
+ - The level editor's cut, copy and stamps keep an object's name, size, turn and visibility, where a paste made a bare point; objects moved with a selection or stamped land on their place to the digit, not a hair off
52
+ - The 3D editor's terrain paint rounds no heights, and a sculpt stroke rounds only those it changed
53
+ - A `UISlider` let go in the frame it moves takes that last place
54
+ - A gamepad of fewer buttons put in the slot of another holds none of the other's buttons; a gamepad axis that reads NaN is centered, where it failed an assert in debug builds
55
+ - `UITextInput` takes a keydown with no key, as autofill sends, where it threw
56
+ - `parseOBJ` reads a comment after a face, carriage return line ends and a line carried on with a backslash, and a release build leaves out a face of a vertex the file does not have
57
+ - `tileLayersFromLDtk` keeps a tile layer with no tiles as an empty layer, so a level of one loads and the editor can paint it
58
+ - Level editor: a property set in the box keeps its place and a `file` or `object` property its type; a save leaves out the object layer made for a first object that was undone; a new object layer's id is past every layer's
59
+ - 3D editor: taking a prefab out of the level takes its instances out of the game; a level's parts are saved in one order, so a level reloaded from its autosave saves the same
60
+ - `writeSaveData` asserts its data is an object, which `readSaveData` reads back, and returns whether it was written, false when storage is full or unavailable
61
+ - `parseAtlas` warns of two sprites with one name; `nearestPowerOfTwo` is never less than its value and is 1 for a value of 1 or less; a particle effect's name cut to 60 characters ends with no space
62
+ - A tile layer's raycast toward a point far beyond the layer walks only across the layer, where a ray to a far constant took seconds
63
+ - `debugShowErrors` shows a message as text, so a file name with markup in it can not add elements to the page
64
+ - Canvas2D tints clamp the color to 0 to 1, as WebGL does
65
+ - glTF: the keys of the files given may start with ./ or / or use backslashes, a uri above them is refused, and an accessor that reaches past its buffer is refused before its floats are made
66
+ - A level whose prefab holds itself, several times over, loads at once with that prefab left out where it holds itself, in place of making thousands of objects
67
+ - Small malformed files no longer make a loader run on: an Aseprite tag past its frames keeps to them, a glTF node reached twice and an accessor of millions with no buffer are refused, an LDtk level of millions of cells is refused and a tile or entity with no place is passed by
68
+ - LDtk: an IntGrid layer whose rule tiles are on another tileset keeps its values for collision, its tiles left out with a warning
69
+ - A collision layer named that no layer has says so in release builds too
70
+ - A light's lens flare: its lamp is a mesh around the light that the ray meets near the light and that is thin, so a globe or a lamp post is its own fixture, while a room or a level mesh hides the light, even one close behind its wall
71
+ - VoxelMap: the inside of a doubleSided face is split along the same diagonal as its outside, so it shows no seam
72
+ - glTF: `parseGLTF(data, baseUrl, files)` finds the `.bin` and image files a `.gltf` names among files given, like a drop's, from the model's own folder, or by the file name alone when only one file has it; a file it can not find is named in the error, and an image that can not be read in a warning; the 3D Mesh example takes a `.gltf` dropped with its files or in its folder, and frees the model it replaces
73
+ - Example browser: after the arrow keys move through the list, Enter keeps the example they went to, and Escape in the search clears it without also closing the list
74
+ - 3D levels: a color that is not a string, and a number that is NaN or Infinity (1e999 in JSON), are read as the default, in place of an assert or a NaN
75
+ - `tileLayersLoad` says so when a map is not a whole number of cells across and down, has no layers, or a layer's tiles do not fill it, in release builds too, in place of running on; every layer is checked before any is made. A game that relied on a release build loading such a map anyway now gets the error
76
+ - A tile past the end of a sheet read by its columns draws nothing, as an LDtk IntGrid layer's values past the art did in the level editor, which asserted
77
+ - A tween that loops or ping pongs with a duration of 0 or less, possible in release builds, ends its loops
78
+
79
+ ### New Demos
80
+
81
+ - [Custom Editor](https://killedbyapixel.github.io/LittleJS/examples/?example=Custom%20Editor) - A level editor made for one game: a class of its own with a tool that lays out rooms by a drag, a button, a key and an overlay
82
+
10
83
  ## 1.24.1 - 2026-10-02
11
84
 
12
85
  ### New Changes
@@ -16,7 +89,11 @@ Nothing yet.
16
89
  - `tileLayersLoad`'s `collisionLayer` may be a layer's name
17
90
  - `light.addFlare` takes the flare's color too
18
91
  - LDtk: an IntGrid layer is always a hidden layer of its values under its own name, its rule tiles in layers over it named with tiles, so `tileLayersLoad(map, tileInfo, 0, 'Collisions')` is solid where the values say, whatever the tiles stack or fade; a project of several worlds loads; a project with no tileset entry keeps its tiles
19
- - The example browser has a new look, in the dark colors of the docs site: a slim top bar in place of the title, the demo at 16:9, and the example list as rows under their headings. A handle between the code and its write-up drags to give one the other's space, by touch and the arrow keys too, and is remembered; a double click puts the quarter back. On a phone the example's name, between Prev and Next, opens a full screen picker with the search. The Screenshot button is gone
92
+ - The example browser has a new look, in the dark colors of the docs site: a slim top bar in place of the title, the demo at 16:9, and the example list as rows under their headings. A handle between the code and its write-up drags to give one the other's space, by touch and the arrow keys too, and is remembered; a double click puts the quarter back. On a phone the example's name, between Prev and Next, opens a full screen picker with the search. The Screenshot button is gone. A button in the top bar switches between dark and light, the choice shared with the docs site
93
+
94
+ ### Breaking Changes
95
+
96
+ - LDtk: an IntGrid layer with tiles is now a hidden layer of its values under its own name, its tiles in layers named with tiles over it, so the layer indices and names of such a level move; name the collision layer, `tileLayersLoad(map, tileInfo, 0, 'Collisions')`, in place of an index
20
97
 
21
98
  ### Fixes
22
99
 
package/EDITOR.md CHANGED
@@ -341,6 +341,8 @@ after a reload.
341
341
 
342
342
  ## Where the working examples are
343
343
 
344
+ - `examples/shorts/customEditor.js`: a 2D editor class of a game's own, with a tool that lays out rooms by a
345
+ drag, a button, a key and an overlay drawn in `onDraw`.
344
346
  - `examples/shorts/render3dLevelEditor.js`: a 3D level with its own Coin and PlayerStart types and both hooks.
345
347
  - `examples/shorts/render3dPrefab.js`: the 3D editor used as a prefab maker.
346
348
  - `examples/shorts/levelEditor.js` and `examples/platformer/`: the 2D editor with a game's own types, palette
package/FAQ.md CHANGED
@@ -206,6 +206,10 @@ If you are using [Visual Studio Code](https://code.visualstudio.com/) there is a
206
206
 
207
207
  Another option is to setup a simple local web server like [http-server](https://www.npmjs.com/package/http-server) via npm.
208
208
 
209
+ ### Which browsers does LittleJS run in?
210
+
211
+ Current Chrome, Edge, Firefox and Safari, on desktop and on phones. The oldest it aims to support is Safari 15 (iOS 15) and the other browsers from 2021 on. Where WebGL2 is missing, 2D games fall back to Canvas2D rendering on their own; the 3D plugin needs WebGL2.
212
+
209
213
  ### How does the camera and world coordinate systems work?
210
214
 
211
215
  LittleJS drawing functions are all handled in world coordinates by default.
@@ -263,6 +267,13 @@ Plugins are self-contained features that live alongside the engine but aren't pa
263
267
  | `newgrounds.js` | Newgrounds.io integration (medals held on the server, scoreboards) |
264
268
  | `audioEffects.js` | Web Audio effects like filter, reverb, delay, distortion and compressor, for a group of sounds or everything |
265
269
  | `drawUtilities.js` | Higher-level drawing helpers like nine-slice and three-slice |
270
+ | `render3dVoxels.js` | `VoxelMap`, a 3D grid of blocks that draws itself and that objects collide with |
271
+ | `render3dLevel.js` | 3D levels as JSON: object types, prefabs, a scene block, block maps and terrain, loaded with `level3DLoad` |
272
+ | `render3dDebug.js` | 3D debug draws (`debugBox3D`, `debugSphere3D`, `debugLine3D`), in debug builds only |
273
+ | `render3dEditor.js` | The free camera and the 3D level editor, in debug builds only |
274
+ | `sceneSystem.js` | Scenes as plain objects, switched with `setScene` |
275
+ | `parallax.js` | `ParallaxLayer`, a background that follows the camera at its own depth and repeats |
276
+ | `particleEffects.js` | A library of ready made particle effects, and their designer's file format |
266
277
 
267
278
  This self-contained design means the community can also ship plugins independently of the main repo — you can write your own plugin as just a JavaScript file that uses the engine's public API.
268
279
 
@@ -367,7 +378,7 @@ LittleJS has a dedicated [js13k branch](https://github.com/KilledByAPixel/Little
367
378
  - **Lean on built-ins to avoid asset files**: `Sound` with ZzFX parameters generates sound effects from a tiny array, and built-in shape drawing avoids shipping image assets.
368
379
  - **Use a packer**: the js13k branch is set up to compress the final bundle with Roadroller or a similar packer. Check the branch's build script for the current toolchain.
369
380
 
370
- For normal production (non-13KB) builds, the engine ships `dist/littlejs.release.js` (asserts stripped) and `dist/littlejs.min.js` (minified) — both well under 100KB.
381
+ For normal production (non-13KB) builds, the engine ships `dist/littlejs.release.js` (asserts stripped, about 1.5 MB with every plugin and its comments) and `dist/littlejs.min.js` (minified, about 420 KB, about 125 KB gzipped). A bundler like Vite leaves out the plugins a game does not use, which makes a small game far smaller.
371
382
 
372
383
  ---
373
384
 
@@ -387,7 +398,7 @@ LittleJS works best when your tile sheet is broken up into grids of tiles becaus
387
398
  drawTile(vec2(21,5), vec2(4.5), tile(3,128));
388
399
  ```
389
400
 
390
- Once loaded, the underlying images are available via `textureInfos[0].image`, `textureInfos[1].image`, etc. This is useful for tasks like reading pixel data to generate a level — see [examples/module/game.js](examples/module/game.js) for an example that reads tile data directly from an image.
401
+ Once loaded, the underlying images are available via `textureInfos[0].image`, `textureInfos[1].image`, etc. This is useful for tasks like reading pixel data to generate a level — the [Level Editor short](https://killedbyapixel.github.io/LittleJS/examples/?example=Level%20Editor) loads a level from data instead, and [examples/module/game.js](examples/module/game.js) builds one from a string.
391
402
 
392
403
  ### What is the tile function and how do tile indexes work?
393
404
 
package/README.md CHANGED
@@ -172,7 +172,7 @@ LittleJS comes with several demos both for learning and using as starter project
172
172
  | [littlejs.esm.js](https://github.com/KilledByAPixel/LittleJS/blob/main/dist/littlejs.esm.js) | Debug | ESM | Debug mode with asserts |
173
173
  | [littlejs.esm.min.js](https://github.com/KilledByAPixel/LittleJS/blob/main/dist/littlejs.esm.min.js) | Release | ESM | Optimized for release and minified |
174
174
 
175
- Every build includes the plugins. littlejs.min.js is about 100 KB gzipped: the core engine is about 36 KB of that and the 3D plugins about 40 KB. A bundler like Vite leaves out the plugins a game does not use, so a small 2D game comes to about 26 KB gzipped, and a lit 3D scene to about 47 KB.
175
+ Every build includes the plugins. littlejs.min.js is about 125 KB gzipped, and the 3D plugins are a large part of that. A bundler like Vite leaves out the plugins a game does not use, so a small 2D game comes to about 26 KB gzipped, and a lit 3D scene to about 47 KB.
176
176
 
177
177
  ## Games Made With LittleJS
178
178
 
package/REFERENCE.md CHANGED
@@ -144,7 +144,7 @@ fetchJSON(url) // Fetch and parse a JSON file (async)
144
144
  shareURL(title, url, callback) // Share a URL via the navigator share API
145
145
  readSaveData(saveName, defaultSaveData) // Read game save data from localStorage, default must be an object
146
146
  // the result has the default's type in TypeScript
147
- writeSaveData(saveName, saveData) // Write game save data to localStorage; give medalsInit a different name
147
+ writeSaveData(saveName, saveData) // Write a save data object to localStorage, false if it could not; give medalsInit a different name
148
148
 
149
149
  // Random functions
150
150
  rand(valueA=1, valueB=0) // Random float between values
@@ -441,6 +441,8 @@ getNoteFrequency(semitoneOffset, rootFrequency=220) // Get frequency for musica
441
441
 
442
442
  // Audio settings
443
443
  soundEnable = true // Should sound be enabled?
444
+ soundIgnoreSilentSwitch = false // play with an iPhone's silent switch on, as media, pausing the player's music;
445
+ // off, the switch mutes the game; setSoundIgnoreSilentSwitch(true)
444
446
  soundVolume = .3 // Volume scale to apply to all sound
445
447
  soundDefaultRange = 40 // Default range where sound no longer plays
446
448
  soundDefaultTaper = .7 // Default range percent to taper off sound (0-1)
@@ -1301,6 +1303,9 @@ light.coneAngle = .5 // a spotlight: the angle in radians from its
1301
1303
  // cone, 0 by default for a light that shines every way; it shines along its
1302
1304
  // own forward, so rotation3D or what it is attached to aims it
1303
1305
  light.coneSoftness = .2 // how much of the cone is its fading edge: 0 a hard edge, 1 fading from the middle
1306
+ light.gel = textureInfo // or a TileInfo's whole texture: a picture the light shines through, cast along its cone in its colors, upright
1307
+ // as the light looks out, like a slide or stained glass; only the spotlight that
1308
+ // casts the shadows has one, render3D.shadows on and it as render3D.shadowLight
1304
1309
  light.glow = 1 // a soft hazy glow over the light this big, like a lamp at night; 0 by default,
1305
1310
  // added onto what is behind it, hidden by what is in front
1306
1311
  light.glowFalloff = 1 // how fast the glow fades from its middle, .5 a wide haze, 2 a tight bright core
@@ -1667,8 +1672,9 @@ const map = new VoxelMap(pos3D=vec3(), mapSize=vec3(16), tileInfo=tile()) // a g
1667
1672
  // that objects with collideLevel collide with; pos3D is its corner and a cell is 1 unit, it stays upright
1668
1673
  map.setVoxel(cell, type) / map.getVoxel(cell) // type 1-255 shows that tile on every face, 0 is empty, a cell outside
1669
1674
  // the map is ignored and reads 0
1670
- map.setBlockType(type, faces, {seeThrough, transparent}) // faces: a tile, six (+x, -x, +y, -y, +z, -z), or
1671
- // {top, side, bottom}; seeThrough for holes like leaves, transparent to blend like water, drawn after the rest
1675
+ map.setBlockType(type, faces, {seeThrough, transparent, doubleSided}) // faces: a tile, six (+x, -x, +y, -y, +z,
1676
+ // -z), or {top, side, bottom}; seeThrough for holes like leaves, transparent to blend like water, drawn after
1677
+ // the rest; doubleSided for faces seen from inside too, so the surface of water shows from under it
1672
1678
  map.raycast(ray, maxDistance, test) // {distance, cell, normal, type} of the first block a ray hits, or
1673
1679
  // undefined; test(type, cell) says which blocks count
1674
1680
  map.data / map.rebuild() // the Uint8Array of types, x + mapSize.x*(y + mapSize.y*z); rebuild
@@ -1683,8 +1689,10 @@ await loadOBJ(url, smooth) // fetch then parse, in an async gameInit; chain .cen
1683
1689
  // glTF models - the glTF plugin, .gltf with its files beside it or .glb in one file; meshes with their node placement,
1684
1690
  // vertex colors, material colors and base color textures, and node animations; no skins or morph targets, and no
1685
1691
  // Draco or meshopt compressed geometry, which throws saying so
1686
- const model = await loadGLTF(url) // a GLTFModel, in an async gameInit; or await parseGLTF(data, baseUrl) on bytes or
1687
- // JSON you already have
1692
+ const model = await loadGLTF(url) // a GLTFModel, in an async gameInit; or await parseGLTF(data, baseUrl, files) on
1693
+ // bytes or JSON you already have; files, a Map of the .bin and image files a
1694
+ // .gltf names by their paths, like the files of a drop, in place of fetching,
1695
+ // baseUrl then the .gltf's folder among them
1688
1696
  model.parts // one GLTFPart per primitive of every node: name, mesh in model space, color,
1689
1697
  // textureInfo when the material has one and WebGL is on, transparent for a
1690
1698
  // blending material or glass (KHR_materials_transmission), which comes in
@@ -2040,7 +2048,8 @@ box2d.raycast(start, end, includeSensors=false) // Returns the closest Box2dR
2040
2048
  // are passed through unless includeSensors
2041
2049
  box2d.raycastAll(start, end, includeSensors=false) // Every Box2dRaycastResult along the ray, nearest first
2042
2050
  box2d.boxCast(pos, size, includeSensors=false) / boxCastAll(pos, size, includeSensors=false) // An object, or all
2043
- // of them, whose shapes overlap the box; sensors are passed through unless included
2051
+ // of them, whose shapes' bounding boxes overlap the box, so near the corner of a turned
2052
+ // box or a circle it can find one the box misses; sensors are passed through unless included
2044
2053
  box2d.circleCast(pos, diameter, includeSensors=false) / circleCastAll(pos, diameter, includeSensors=false) // The
2045
2054
  // nearest object, or all of them, whose position is in the circle, wherever its shapes
2046
2055
  // are; objects of only sensors are passed over unless included
@@ -2172,6 +2181,11 @@ getCrescentPoints(pos, size=1, percent=0, angle=0, invert=false, sides=glCircleS
2172
2181
  - See `examples/shorts/textureSheet.js`
2173
2182
 
2174
2183
  ```javascript
2184
+ loadTiles(sources, tileSize, padding=1) // Pack tile images, or several tile sheets, into one tile set: each image cut
2185
+ // into tiles, numbered from 0 in the order given; give the TileInfo it
2186
+ // returns to tileLayersLoad or a TileLayer, and await spritesReady first
2187
+ tileInfo.tiles // a tile set's tiles, each where it was packed: a tile layer draws tile n
2188
+ // from tiles[n], and the level editor's palette offers each
2175
2189
  loadSprite(src, frameSize, padding=1, sourcePadding=0) // Load an image and pack it, returns a TileInfo
2176
2190
  loadAtlas(imageSrc, jsonSrc, padding=1) // Load a TexturePacker or Aseprite atlas, returns name->TileInfo object
2177
2191
  parseAtlas(data) // Parse atlas json into named frame groups, used by loadAtlas
@@ -2288,7 +2302,8 @@ debugLine(posA, posB, color, width=.1, time) // Draw debug line
2288
2302
  debugPoly(pos, points, color=WHITE, time=0, angle=0, fill) // Draw debug polygon
2289
2303
  debugText(text, pos, size=1, color=WHITE, time=0, angle=0) // Draw debug text
2290
2304
  debugOverlap(pA, sA, pB, sB, color) // Draw a debug overlap between two boxes
2291
- // each debug draw also takes screenSpace after the params above, defaulting to drawScreenSpace
2305
+ // each debug draw also takes screenSpace as its last parameter, defaulting to drawScreenSpace; debugText takes a
2306
+ // font before it
2292
2307
  debugClear() // Clear all debug primitives
2293
2308
  debugScreenshot() // Save a screenshot at the end of this frame
2294
2309
  debugShowErrors() // Show full page error message when an error occurs