littlejsengine 1.18.12 → 1.18.17

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.
@@ -291,7 +291,7 @@ declare module "littlejsengine" {
291
291
  * @param {boolean} [screenSpace]
292
292
  * @memberof Debug */
293
293
  export function debugOverlap(posA: Vector2, sizeA: Vector2, posB: Vector2, sizeB: Vector2, color?: Color | string, time?: number, screenSpace?: boolean): void;
294
- /** Draw a debug axis aligned bounding box in world space
294
+ /** Draw debug text in world space
295
295
  * @param {string|number} text
296
296
  * @param {Vector2} pos
297
297
  * @param {number} [size]
@@ -358,7 +358,7 @@ declare module "littlejsengine" {
358
358
  export let canvasColorTiles: boolean;
359
359
  /** Color to clear the canvas to before render, does not clear if alpha is 0
360
360
  * @type {Color}
361
- * @memberof Draw */
361
+ * @memberof Settings */
362
362
  export let canvasClearColor: Color;
363
363
  /** The max size of the canvas, centered if window is larger
364
364
  * @type {Vector2}
@@ -510,30 +510,69 @@ declare module "littlejsengine" {
510
510
  * - Supports left analog stick, 4 face buttons and start button (button 9)
511
511
  * - setTouchGamepadButtonCount(1) to use face buttons as right analog stick
512
512
  * - Analog stick buttons 10 and 11 are also activated when virtual sticks are touched
513
-
513
+ * - Rendered as a full-viewport HTML/SVG overlay, so controls may sit outside the game canvas
514
514
  * @type {boolean}
515
515
  * @default
516
516
  * @memberof Settings */
517
517
  export let touchGamepadEnable: boolean;
518
- /** True if touch gamepad should have start button in the center
519
- * - Prevents activating if overlappng with virtual stick or buttons if they are enabled
518
+ /** True if touches outside the gamepad controls should still drive mouse/touch input
519
+ * - When false (the default), enabling the touch gamepad suppresses touch-to-mouse input entirely
520
+ * - Set true to also pass touches outside the controls through to the game as mouse/touch input
521
+ * - Touches on the gamepad controls never drive the mouse regardless of this setting
522
+ * @type {boolean}
523
+ * @default
524
+ * @memberof Settings */
525
+ export let touchGamepadPassthrough: boolean;
526
+ /** Size of center button if touch gamepad should have start button in the center
527
+ * - Prevents activating when pressed near virtual stick or face buttons
520
528
  * - When the game is paused, any touch will press the button
521
- * - Set size to enable the center button
529
+ * - Measured in viewport CSS pixels
522
530
  * @type {number}
523
531
  * @default
524
532
  * @memberof Settings */
525
533
  export let touchGamepadCenterButtonSize: number;
526
- /** Number of buttons on touch gamepad (0-4), if 1 also acts as right analog stick
534
+ /** Number of buttons on the right side of the touch gamepad (0-4), using gamepad buttons 0-3
535
+ * - A count of 1 is a single large button (the size of a stick)
536
+ * - Ignored when touchGamepadRightStick is set (the right side is a stick instead)
527
537
  * @type {number}
528
538
  * @default
529
539
  * @memberof Settings */
530
540
  export let touchGamepadButtonCount: number;
541
+ /** True if the touch gamepad should have a left analog stick (or dpad)
542
+ * - When false, the left side is face buttons (touchGamepadLeftButtonCount) or nothing
543
+ * @type {boolean}
544
+ * @default
545
+ * @memberof Settings */
546
+ export let touchGamepadLeftStick: boolean;
547
+ /** Number of buttons on the left side of the touch gamepad (0-4), using gamepad buttons 4-7
548
+ * - Only used when touchGamepadLeftStick is false (otherwise the left side is a stick)
549
+ * - A count of 1 is a single large button (the size of a stick)
550
+ * @type {number}
551
+ * @default
552
+ * @memberof Settings */
553
+ export let touchGamepadLeftButtonCount: number;
554
+ /** True if the touch gamepad right side should be an analog stick (or dpad) instead of face buttons
555
+ * - When set, touchGamepadButtonCount is ignored and the right side is a stick
556
+ * - Uses an analog stick when touchGamepadAnalog is true, otherwise an 8 way dpad
557
+ * @type {boolean}
558
+ * @default
559
+ * @memberof Settings */
560
+ export let touchGamepadRightStick: boolean;
531
561
  /** True if touch gamepad should be analog stick or false to use if 8 way dpad
532
562
  * @type {boolean}
533
563
  * @default
534
564
  * @memberof Settings */
535
565
  export let touchGamepadAnalog: boolean;
536
- /** Size of virtual gamepad for touch devices in pixels
566
+ /** True if touch gamepad directional controls should float to where you press
567
+ * - Only affects analog sticks and dpads, not face buttons
568
+ * - Directional controls re-anchor to where you press within the bottom ~60% of their screen half; the top ~40% passes through to the game
569
+ * - The right side floats only when it acts as the right analog stick (touchGamepadRightStick is set)
570
+ * - A center button (touchGamepadCenterButtonSize) still works since it ignores touches near the sticks
571
+ * @type {boolean}
572
+ * @default
573
+ * @memberof Settings */
574
+ export let touchGamepadFloating: boolean;
575
+ /** Size of virtual gamepad for touch devices in viewport CSS pixels
537
576
  * @type {number}
538
577
  * @default
539
578
  * @memberof Settings */
@@ -548,6 +587,12 @@ declare module "littlejsengine" {
548
587
  * @default
549
588
  * @memberof Settings */
550
589
  export let touchGamepadDisplayTime: number;
590
+ /** Duration in ms to vibrate when a touch gamepad face button or start button is pressed
591
+ * - Set to 0 to disable, also requires vibrateEnable and hardware support (ignored on iOS)
592
+ * @type {number}
593
+ * @default
594
+ * @memberof Settings */
595
+ export let touchGamepadVibration: number;
551
596
  /** Allow vibration hardware if it exists
552
597
  * @type {boolean}
553
598
  * @default
@@ -717,20 +762,41 @@ declare module "littlejsengine" {
717
762
  * @param {boolean} enable
718
763
  * @memberof Settings */
719
764
  export function setTouchGamepadEnable(enable: boolean): void;
765
+ /** Set if touches outside the gamepad controls should still drive mouse/touch input
766
+ * @param {boolean} passthrough
767
+ * @memberof Settings */
768
+ export function setTouchGamepadPassthrough(passthrough: boolean): void;
720
769
  /** Set if touch gamepad should have start button in the center
721
770
  * - Set size to enable the center button
722
771
  * - When the game is paused, any touch will press the button
723
772
  * @param {number} size
724
773
  * @memberof Settings */
725
774
  export function setTouchGamepadCenterButtonSize(size: number): void;
726
- /** Set number of buttons on touch gamepad (0-4), if 1 also acts as right analog stick
775
+ /** Set number of buttons on the right side of the touch gamepad (0-4, gamepad buttons 0-3)
727
776
  * @param {number} count
728
777
  * @memberof Settings */
729
778
  export function setTouchGamepadButtonCount(count: number): void;
779
+ /** Set if the touch gamepad should have a left analog stick (or dpad)
780
+ * @param {boolean} enable
781
+ * @memberof Settings */
782
+ export function setTouchGamepadLeftStick(enable: boolean): void;
783
+ /** Set number of buttons on the left side of the touch gamepad (0-4, gamepad buttons 4-7)
784
+ * - Only used when touchGamepadLeftStick is false
785
+ * @param {number} count
786
+ * @memberof Settings */
787
+ export function setTouchGamepadLeftButtonCount(count: number): void;
788
+ /** Set if the touch gamepad right side is an analog stick (or dpad) instead of face buttons
789
+ * @param {boolean} rightStick
790
+ * @memberof Settings */
791
+ export function setTouchGamepadRightStick(rightStick: boolean): void;
730
792
  /** Set if touch gamepad should be analog stick or 8 way dpad
731
793
  * @param {boolean} analog
732
794
  * @memberof Settings */
733
795
  export function setTouchGamepadAnalog(analog: boolean): void;
796
+ /** Set if touch gamepad directional controls should float to where you press
797
+ * @param {boolean} floating
798
+ * @memberof Settings */
799
+ export function setTouchGamepadFloating(floating: boolean): void;
734
800
  /** Set size of virtual gamepad for touch devices in pixels
735
801
  * @param {number} size
736
802
  * @memberof Settings */
@@ -739,6 +805,14 @@ declare module "littlejsengine" {
739
805
  * @param {number} alpha
740
806
  * @memberof Settings */
741
807
  export function setTouchGamepadAlpha(alpha: number): void;
808
+ /** Set how long to display the touch gamepad on screen in seconds, set to 0 to always display
809
+ * @param {number} time
810
+ * @memberof Settings */
811
+ export function setTouchGamepadDisplayTime(time: number): void;
812
+ /** Set duration in ms to vibrate when a touch gamepad face or start button is pressed (0 disables)
813
+ * @param {number} ms
814
+ * @memberof Settings */
815
+ export function setTouchGamepadVibration(ms: number): void;
742
816
  /** Set to allow vibration hardware if it exists
743
817
  * @param {boolean} enable
744
818
  * @memberof Settings */
@@ -821,17 +895,17 @@ declare module "littlejsengine" {
821
895
  * @param {number} x
822
896
  * @return {number}
823
897
  * @memberof Math */
824
- export const sign: any;
898
+ export function sign(x: number): number;
825
899
  /** Returns hypotenuse of values passed in
826
900
  * @param {...number} values
827
901
  * @return {number}
828
902
  * @memberof Math */
829
- export const hypot: any;
903
+ export function hypot(...values: number[]): number;
830
904
  /** Returns log2 of value passed in
831
905
  * @param {number} x
832
906
  * @return {number}
833
907
  * @memberof Math */
834
- export const log2: any;
908
+ export function log2(x: number): number;
835
909
  /** Returns sin of value passed in
836
910
  * @param {number} x
837
911
  * @return {number}
@@ -1422,7 +1496,8 @@ declare module "littlejsengine" {
1422
1496
  /** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
1423
1497
  * @return {number} */
1424
1498
  get(): number;
1425
- /** Get percentage elapsed based on time it was set to, returns 0 if not set
1499
+ /** Get percentage elapsed based on time it was set to, returns 0 if not set.
1500
+ * Zero-duration timers report 1 (already elapsed).
1426
1501
  * @return {number} */
1427
1502
  getPercent(): number;
1428
1503
  /** Get the time this timer was set to, returns 0 if not set
@@ -1499,9 +1574,9 @@ declare module "littlejsengine" {
1499
1574
  /**
1500
1575
  * Check if object is an array
1501
1576
  * @param {any} a
1502
- * @return {boolean}
1577
+ * @return {a is Array<any>}
1503
1578
  * @memberof Math */
1504
- export function isArray(a: any): boolean;
1579
+ export function isArray(a: any): a is any[];
1505
1580
  /** Color - White #ffffff
1506
1581
  * @type {Color}
1507
1582
  * @memberof Math */
@@ -1580,8 +1655,8 @@ declare module "littlejsengine" {
1580
1655
  * @param {Vector2} [pos=vec2()] - Top left corner of tile in pixels
1581
1656
  * @param {Vector2} [size] - Size of tile in pixels
1582
1657
  * @param {TextureInfo} [textureInfo] - Texture info to use
1583
- * @param {number} [padding] - How many pixels padding around tiles
1584
- * @param {number} [bleed] - How many pixels smaller to draw tiles
1658
+ * @param {number} [padding] - How many pixels padding around all sides of each tile (increases grid size, does not affect tile size)
1659
+ * @param {number} [bleed] - How many pixels smaller to shrink UVS of tiles (does not affect grid size, only UVs)
1585
1660
  */
1586
1661
  constructor(pos?: Vector2, size?: Vector2, textureInfo?: TextureInfo, padding?: number, bleed?: number);
1587
1662
  /** @property {Vector2} - Top left corner of tile in pixels */
@@ -1656,7 +1731,7 @@ declare module "littlejsengine" {
1656
1731
  * - Optimized tile sheet sprite rendering using WebGL batching
1657
1732
  * - Primitive drawing for polygons, ellipses, and lines
1658
1733
  * - Tile-based rendering with TileInfo and TextureInfo classes
1659
- * - Text rendering with custom fonts and FontImage support
1734
+ * - Text rendering with custom fonts and ImageFont support
1660
1735
  * - Color and additive color blending for effects
1661
1736
  * - Rotation, mirroring, and scaling transformations
1662
1737
  * - Camera system with position, scale, and rotation
@@ -1833,9 +1908,9 @@ declare module "littlejsengine" {
1833
1908
  * @param {Vector2} [size=vec2(1)]
1834
1909
  * @param {number} [sides]
1835
1910
  * @param {Color} [color=WHITE]
1836
- * @param {number} [angle]
1837
1911
  * @param {number} [lineWidth]
1838
1912
  * @param {Color} [lineColor=BLACK]
1913
+ * @param {number} [angle]
1839
1914
  * @param {boolean} [useWebGL=glEnable]
1840
1915
  * @param {boolean} [screenSpace]
1841
1916
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
@@ -1864,13 +1939,29 @@ declare module "littlejsengine" {
1864
1939
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
1865
1940
  * @memberof Draw */
1866
1941
  export function drawCircle(pos: Vector2, size?: number, color?: Color, lineWidth?: number, lineColor?: Color, useWebGL?: boolean, screenSpace?: boolean, context?: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D): void;
1867
- export function drawCircleGradient(pos: any, size: number, colorInner: Color, colorOuter: Color, useWebGL: boolean, screenSpace: boolean, context: any): void;
1942
+ export function drawEllipseGradient(pos: any, size: Vector2, colorInner: Color, colorOuter: Color, angle: number, useWebGL: boolean, screenSpace: boolean, context: any): void;
1943
+ /** Draw a circle filled with a radial gradient from the center to the rim
1944
+ * - Best when batched with other untextured polys
1945
+ * - If drawing mostly textured sprites, bake the gradient into a texture and use drawTile instead
1946
+ * - Stacking gradients at the exact same position may show a faint vertical artifact
1947
+ * @param {Vector2} pos
1948
+ * @param {number} [size=1] - Diameter
1949
+ * @param {Color} [colorInner=WHITE]
1950
+ * @param {Color} [colorOuter=CLEAR_WHITE]
1951
+ * @param {boolean} [useWebGL=glEnable]
1952
+ * @param {boolean} [screenSpace]
1953
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
1954
+ * @memberof Draw */
1955
+ export function drawCircleGradient(pos: Vector2, size?: number, colorInner?: Color, colorOuter?: Color, useWebGL?: boolean, screenSpace?: boolean, context?: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D): void;
1868
1956
  /**
1869
1957
  * @callback Canvas2DDrawFunction - A function that draws to a 2D canvas context
1870
1958
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} context
1871
1959
  * @memberof Draw
1872
1960
  */
1873
- /** Draw directly to a 2d canvas context in world space
1961
+ /** Draw directly to a 2d canvas context in world space.
1962
+ * The Y axis is flipped so world-Y-up coordinates render right-side up
1963
+ * (matches the WebGL path). Callers whose drawing depends on Y direction
1964
+ * (e.g. linear gradients) should flip their own Y endpoints accordingly.
1874
1965
  * @param {Vector2} pos
1875
1966
  * @param {Vector2} size
1876
1967
  * @param {number} angle
@@ -1922,11 +2013,11 @@ declare module "littlejsengine" {
1922
2013
  * @memberof Draw */
1923
2014
  export function combineCanvases(): void;
1924
2015
  /** Engine font image, 8x8 font provided by the engine
1925
- * @type {FontImage}
2016
+ * @type {ImageFont}
1926
2017
  * @memberof Draw */
1927
- export let engineFontImage: FontImage;
2018
+ export let engineImageFont: ImageFont;
1928
2019
  /**
1929
- * Font Image Object - Draw text by using tiles in an image
2020
+ * Image Font Object - Draw text by using tiles in an image
1930
2021
  * - 96 characters (from space to tilde) are stored in an image
1931
2022
  * - A 8x8 default engine font is supplied for general use
1932
2023
  * - This system is WebGL enabled for fast text rendering
@@ -1935,12 +2026,12 @@ declare module "littlejsengine" {
1935
2026
  * @memberof Draw
1936
2027
  * @example
1937
2028
  * // use built in font
1938
- * const font = engineFontImage;
2029
+ * const font = engineImageFont;
1939
2030
  *
1940
2031
  * // draw text
1941
2032
  * font.drawTextScreen('LittleJS\nHello World!', vec2(200, 50));
1942
2033
  */
1943
- export class FontImage {
2034
+ export class ImageFont {
1944
2035
  /** Create an image font
1945
2036
  * @param {TileInfo} tileInfo - Tile info of first character in font
1946
2037
  */
@@ -2087,9 +2178,9 @@ declare module "littlejsengine" {
2087
2178
  * @memberof WebGL */
2088
2179
  export function glDraw(x: number, y: number, sizeX: number, sizeY: number, angle?: number, uv0X?: number, uv0Y?: number, uv1X?: number, uv1Y?: number, rgba?: number, rgbaAdditive?: number): void;
2089
2180
  /** Add an untextured rect to the gl draw list
2090
- * Picks the optimal path: if already in poly mode, emits a tristrip rect
2091
- * so it batches with surrounding polys; otherwise uses the instanced path
2092
- * with uvs and rgba zeroed so the color falls through the additive slot.
2181
+ * Zeroes the uvs and rgba so the texture contribution multiplies to 0,
2182
+ * then carries the real color in the additive slot. Works regardless of
2183
+ * which texture is currently bound.
2093
2184
  * @param {number} x
2094
2185
  * @param {number} y
2095
2186
  * @param {number} sizeX
@@ -2405,7 +2496,7 @@ declare module "littlejsengine" {
2405
2496
  * @param {number} [randomnessScale] - How much to scale pitch randomness
2406
2497
  * @param {boolean} [loop] - Should the sound loop?
2407
2498
  * @param {boolean} [paused] - Should the sound start paused
2408
- * @return {SoundInstance} - The audio source node
2499
+ * @return {SoundInstance} - The sound instance, or undefined if sound is disabled, not loaded, or running in headless mode
2409
2500
  */
2410
2501
  play(pos?: Vector2, volume?: number, pitch?: number, randomnessScale?: number, loop?: boolean, paused?: boolean): SoundInstance;
2411
2502
  /** Play a music track that loops by default
@@ -2424,7 +2515,7 @@ declare module "littlejsengine" {
2424
2515
  */
2425
2516
  playNote(semitoneOffset?: number, pos?: Vector2, volume?: number): SoundInstance;
2426
2517
  /** Get how long this sound is in seconds
2427
- * @return {number} - How long the sound is in seconds (undefined if loading)
2518
+ * @return {number} - How long the sound is in seconds (0 if loading)
2428
2519
  */
2429
2520
  getDuration(): number;
2430
2521
  /** Check if sound is loaded, for sounds fetched from a url
@@ -2505,7 +2596,7 @@ declare module "littlejsengine" {
2505
2596
  */
2506
2597
  getCurrentTime(): number;
2507
2598
  /** Get the total duration of this sound
2508
- * @return {number} - Total duration in seconds
2599
+ * @return {number} - Total duration in seconds (0 if loading)
2509
2600
  */
2510
2601
  getDuration(): number;
2511
2602
  /** Get source of this sound instance
@@ -2641,7 +2732,7 @@ declare module "littlejsengine" {
2641
2732
  color: Color;
2642
2733
  /** @property {Color} - Additive color to apply when rendered */
2643
2734
  additiveColor: any;
2644
- /** @property {boolean} - Should it flip along y axis when rendered */
2735
+ /** @property {boolean} - Should the rendered tile flip along the y axis. Affects rendering and the local→world transform of attached children (a mirrored parent flips its children's localPos.x and localAngle). Does not affect this object's own physics, collision, or localToWorld/worldToLocal. */
2645
2736
  mirror: boolean;
2646
2737
  /** @property {boolean} - Has object been destroyed? */
2647
2738
  destroyed: boolean;
@@ -2693,6 +2784,8 @@ declare module "littlejsengine" {
2693
2784
  update(): void;
2694
2785
  /** Render the object, draws a tile by default, automatically called each frame, sorted by renderOrder */
2695
2786
  render(): void;
2787
+ /** Optional hook called during the light system plugin's lightmap pass to draw this object's lightmap contribution. Does nothing by default. */
2788
+ renderLight(): void;
2696
2789
  /** Destroy this object, destroy its children, detach its parent, and mark it for removal
2697
2790
  * @param {boolean} [immediate] - should attached effects be allowed to die off? */
2698
2791
  destroy(immediate?: boolean): void;
@@ -2898,20 +2991,6 @@ declare module "littlejsengine" {
2898
2991
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context] - Canvas 2D context to draw to
2899
2992
  * @memberof Draw */
2900
2993
  draw(pos: Vector2, size?: Vector2, color?: Color, angle?: number, mirror?: boolean, additiveColor?: Color, screenSpace?: boolean, context?: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D): void;
2901
- /** Draw a tile onto the layer canvas in world space
2902
- * @param {Vector2} pos
2903
- * @param {Vector2} [size=vec2(1)]
2904
- * @param {TileInfo} [tileInfo]
2905
- * @param {Color} [color=WHITE]
2906
- * @param {number} [angle]
2907
- * @param {boolean} [mirror] */
2908
- drawTile(pos: Vector2, size?: Vector2, tileInfo?: TileInfo, color?: Color, angle?: number, mirror?: boolean): void;
2909
- /** Draw a rectangle onto the layer canvas in world space
2910
- * @param {Vector2} pos
2911
- * @param {Vector2} [size=vec2(1)]
2912
- * @param {Color} [color=WHITE]
2913
- * @param {number} [angle] */
2914
- drawRect(pos: Vector2, size?: Vector2, color?: Color, angle?: number): void;
2915
2994
  /** Create WebGL texture if necessary and copy layer canvas to it */
2916
2995
  updateWebGL(): void;
2917
2996
  /** Check if this layer is using WebGL
@@ -2982,6 +3061,20 @@ declare module "littlejsengine" {
2982
3061
  * @param {number} [angle] - Angle to rotate by
2983
3062
  */
2984
3063
  drawLayerRect(pos: Vector2, size: Vector2, color?: Color, angle?: number): void;
3064
+ /** Draw a tile onto the layer canvas in world space
3065
+ * @param {Vector2} pos
3066
+ * @param {Vector2} [size=vec2(1)]
3067
+ * @param {TileInfo} [tileInfo]
3068
+ * @param {Color} [color=WHITE]
3069
+ * @param {number} [angle]
3070
+ * @param {boolean} [mirror] */
3071
+ drawTile(pos: Vector2, size?: Vector2, tileInfo?: TileInfo, color?: Color, angle?: number, mirror?: boolean): void;
3072
+ /** Draw a rectangle onto the layer canvas in world space
3073
+ * @param {Vector2} pos
3074
+ * @param {Vector2} [size=vec2(1)]
3075
+ * @param {Color} [color=WHITE]
3076
+ * @param {number} [angle] */
3077
+ drawRect(pos: Vector2, size?: Vector2, color?: Color, angle?: number): void;
2985
3078
  /** Clear a rectangle in layer space
2986
3079
  * @param {Vector2} pos - position in pixel coordinates
2987
3080
  * @param {Vector2} size
@@ -2998,8 +3091,8 @@ declare module "littlejsengine" {
2998
3091
  clearData(layerPos: Vector2, redraw?: boolean): void;
2999
3092
  /** Get data at a given position in the array
3000
3093
  * @param {Vector2} layerPos - Local position in array
3001
- * @return {TileLayerData} */
3002
- getData(layerPos: Vector2): TileLayerData;
3094
+ * @return {TileLayerData|undefined} */
3095
+ getData(layerPos: Vector2): TileLayerData | undefined;
3003
3096
  /** Called after this layer is redrawn, does nothing by default */
3004
3097
  onRedraw(): void;
3005
3098
  /** @type {[CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D, Vector2, Vector2, number, Color]} */
@@ -3102,13 +3195,13 @@ declare module "littlejsengine" {
3102
3195
  * @param {number} [particleTime] - How long particles live
3103
3196
  * @param {number} [sizeStart] - How big are particles at start
3104
3197
  * @param {number} [sizeEnd] - How big are particles at end
3105
- * @param {number} [speed] - How fast are particles when spawned
3106
- * @param {number} [angleSpeed] - How fast are particles rotating
3107
- * @param {number} [damping] - How much to dampen particle speed
3108
- * @param {number} [angleDamping] - How much to dampen particle angular speed
3198
+ * @param {number} [speed] - How fast are particles when spawned, in world units per frame (at 60fps, so multiply units/sec by 1/60)
3199
+ * @param {number} [angleSpeed] - How fast are particles rotating, in radians per frame (at 60fps)
3200
+ * @param {number} [damping] - How much to dampen particle speed, per-frame velocity multiplier (1 = no damping, .9 = lose 10% speed each frame)
3201
+ * @param {number} [angleDamping] - How much to dampen particle angular speed, per-frame multiplier (1 = no damping)
3109
3202
  * @param {number} [gravityScale] - How much gravity effect particles
3110
3203
  * @param {number} [particleConeAngle] - Cone for start particle angle
3111
- * @param {number} [fadeRate] - How quick to fade particles at start/end in percent of life
3204
+ * @param {number} [fadeRate] - Fraction of life spent fading: half at fade-in (start), half at fade-out (end). e.g. .2 = 10% fade-in, 80% full opacity, 10% fade-out
3112
3205
  * @param {number} [randomness] - Apply extra randomness percent
3113
3206
  * @param {boolean} [collideTiles] - Do particles collide against tiles
3114
3207
  * @param {boolean} [additive] - Should particles use additive blend
@@ -3143,13 +3236,13 @@ declare module "littlejsengine" {
3143
3236
  sizeStart: number;
3144
3237
  /** @property {number} - How big are particles at end */
3145
3238
  sizeEnd: number;
3146
- /** @property {number} - How fast are particles when spawned */
3239
+ /** @property {number} - Particle speed when spawned, in world units per frame (at 60fps) */
3147
3240
  speed: number;
3148
- /** @property {number} - How fast are particles rotating */
3241
+ /** @property {number} - Particle angular speed when spawned, in radians per frame (at 60fps) */
3149
3242
  angleSpeed: number;
3150
3243
  /** @property {number} - Cone for start particle angle */
3151
3244
  particleConeAngle: number;
3152
- /** @property {number} - How quick to fade in particles at start/end in percent of life */
3245
+ /** @property {number} - Fraction of life spent fading, split half at start and half at end (e.g. .2 = 10% fade-in + 10% fade-out) */
3153
3246
  fadeRate: number;
3154
3247
  /** @property {number} - Apply extra randomness percent */
3155
3248
  randomness: number;
@@ -3249,6 +3342,21 @@ declare module "littlejsengine" {
3249
3342
  * @default
3250
3343
  * @memberof Settings */
3251
3344
  export let medalsPreventUnlock: boolean;
3345
+ /** How long to show medals for in seconds
3346
+ * @type {number}
3347
+ * @default
3348
+ * @memberof Settings */
3349
+ export let medalDisplayTime: number;
3350
+ /** How quickly to slide on/off medals in seconds
3351
+ * @type {number}
3352
+ * @default
3353
+ * @memberof Settings */
3354
+ export let medalDisplaySlideTime: number;
3355
+ /** Size of medal display
3356
+ * @type {Vector2}
3357
+ * @default Vector2(640,80)
3358
+ * @memberof Settings */
3359
+ export let medalDisplaySize: Vector2;
3252
3360
  /** Initialize medals with a save name used for storage
3253
3361
  * - Call this after creating all medals
3254
3362
  * - Checks if medals are unlocked
@@ -3264,6 +3372,25 @@ declare module "littlejsengine" {
3264
3372
  * @param {MedalCallbackFunction} callback
3265
3373
  * @memberof Medals */
3266
3374
  export function medalsForEach(callback: MedalCallbackFunction): void;
3375
+ /** Reset all medals to locked and persist the cleared catalog
3376
+ * @memberof Medals */
3377
+ export function medalsReset(): void;
3378
+ /** Set how long to show medals for in seconds
3379
+ * @param {number} time
3380
+ * @memberof Settings */
3381
+ export function setMedalDisplayTime(time: number): void;
3382
+ /** Set how quickly to slide on/off medals in seconds
3383
+ * @param {number} time
3384
+ * @memberof Settings */
3385
+ export function setMedalDisplaySlideTime(time: number): void;
3386
+ /** Set size of medal display
3387
+ * @param {Vector2} size
3388
+ * @memberof Settings */
3389
+ export function setMedalDisplaySize(size: Vector2): void;
3390
+ /** Set to stop medals from being unlockable
3391
+ * @param {boolean} preventUnlock
3392
+ * @memberof Settings */
3393
+ export function setMedalsPreventUnlock(preventUnlock: boolean): void;
3267
3394
  /**
3268
3395
  * Medal - Tracks an unlockable medal
3269
3396
  * @memberof Medals
@@ -3309,39 +3436,7 @@ declare module "littlejsengine" {
3309
3436
  * @param {number} size - Screen space size
3310
3437
  */
3311
3438
  renderIcon(pos: Vector2, size: number): void;
3312
- storageKey(): string;
3313
3439
  }
3314
- /** How long to show medals for in seconds
3315
- * @type {number}
3316
- * @default
3317
- * @memberof Settings */
3318
- export let medalDisplayTime: number;
3319
- /** How quickly to slide on/off medals in seconds
3320
- * @type {number}
3321
- * @default
3322
- * @memberof Settings */
3323
- export let medalDisplaySlideTime: number;
3324
- /** Size of medal display
3325
- * @type {Vector2}
3326
- * @default Vector2(640,80)
3327
- * @memberof Settings */
3328
- export let medalDisplaySize: Vector2;
3329
- /** Set how long to show medals for in seconds
3330
- * @param {number} time
3331
- * @memberof Settings */
3332
- export function setMedalDisplayTime(time: number): void;
3333
- /** Set how quickly to slide on/off medals in seconds
3334
- * @param {number} time
3335
- * @memberof Settings */
3336
- export function setMedalDisplaySlideTime(time: number): void;
3337
- /** Set size of medal display
3338
- * @param {Vector2} size
3339
- * @memberof Settings */
3340
- export function setMedalDisplaySize(size: Vector2): void;
3341
- /** Set to stop medals from being unlockable
3342
- * @param {boolean} preventUnlock
3343
- * @memberof Settings */
3344
- export function setMedalsPreventUnlock(preventUnlock: boolean): void;
3345
3440
  /**
3346
3441
  * LittleJS Newgrounds Plugin
3347
3442
  * - NewgroundsMedal extends Medal with Newgrounds API functionality
@@ -3380,9 +3475,7 @@ declare module "littlejsengine" {
3380
3475
  host: string;
3381
3476
  /** @property {string|null} - Newgrounds session id from the URL (null when not logged in) */
3382
3477
  session_id: string;
3383
- /** @property {Array} - Medals fetched from Newgrounds (empty until session is active) */
3384
3478
  medals: any;
3385
- /** @property {Array} - Scoreboards fetched from Newgrounds */
3386
3479
  scoreboards: any;
3387
3480
  /** Send message to unlock a medal by id
3388
3481
  * @param {number} id - The medal id */
@@ -3449,6 +3542,85 @@ declare module "littlejsengine" {
3449
3542
  /** @property {WebGLVertexArrayObject} - Vertex array object */
3450
3543
  vao: any;
3451
3544
  }
3545
+ /**
3546
+ * LittleJS Light System Plugin
3547
+ * - Adds 2D dynamic lighting to the scene
3548
+ * - Lights are first-class EngineObjects (the Light class)
3549
+ * - Each Light draws a soft falloff blob of its color into a shared lightmap
3550
+ * - Lights accumulate ADDITIVELY in the lightmap (red + blue = magenta)
3551
+ * - The lightmap is then MULTIPLIED with the scene during composite, so unlit
3552
+ * areas go to the ambient color and lit areas show the scene tinted by the
3553
+ * accumulated light color
3554
+ * - Draw the world at full brightness — the lightmap does the darkening
3555
+ * - Any EngineObject may override renderLight() to additively contribute to the
3556
+ * lightmap (e.g. emissive lava tiles, weapon flashes, glowing crystals)
3557
+ * - Must be constructed BEFORE PostProcessPlugin so post-process sees lit pixels
3558
+ * @namespace LightSystem
3559
+ */
3560
+ /** Global Light System plugin object
3561
+ * @type {LightSystemPlugin}
3562
+ * @memberof LightSystem */
3563
+ export let lightSystem: LightSystemPlugin;
3564
+ /**
3565
+ * LightSystemPlugin
3566
+ * - Owns the offscreen lightmap texture, falloff/composite shaders, and the
3567
+ * per-frame render pass that multiplies the lightmap onto the WebGL scene
3568
+ * - The composite is MULTIPLICATIVE: unlit areas get the ambient color, lit
3569
+ * areas show the scene tinted by the accumulated light color. So you should
3570
+ * draw your world at full brightness — the lightmap handles the darkening.
3571
+ * @memberof LightSystem
3572
+ */
3573
+ export class LightSystemPlugin {
3574
+ /** Create the global light system plugin.
3575
+ * @param {Vector2} [textureSize] - Size of the lightmap texture (defaults to mainCanvasSize)
3576
+ * @param {Color} [ambientColor] - Color applied to unlit areas of the scene (defaults to BLACK = pitch dark). Set a small RGB like rgb(0.1,0.1,0.15) for a faint "moonlight" baseline so unlit areas aren't fully black.
3577
+ * @example
3578
+ * // simplest usage
3579
+ * new LightSystemPlugin();
3580
+ */
3581
+ constructor(textureSize?: Vector2, ambientColor?: Color);
3582
+ /** @property {boolean} - When false, the render pass is skipped entirely */
3583
+ enabled: boolean;
3584
+ /** @property {Color} - Baseline color applied to unlit areas of the scene. Defaults to BLACK (pitch dark). Set to a small RGB for a faint ambient. The lightmap is cleared to this color each frame, then lights add on top, then the result multiplies the scene. */
3585
+ ambientColor: Color;
3586
+ /** @property {Vector2} - Size of the lightmap texture (set at construction; falls back to mainCanvasSize at init time) */
3587
+ textureSize: Vector2;
3588
+ /** @property {WebGLTexture} - The lightmap texture */
3589
+ texture: any;
3590
+ /** @property {WebGLProgram} - Shader for drawing per-Light falloff blobs into the lightmap */
3591
+ lightShader: any;
3592
+ /** @property {WebGLProgram} - Shader for compositing the lightmap over the main scene */
3593
+ compositeShader: any;
3594
+ /** @property {WebGLVertexArrayObject} - Vertex array object for the light shader */
3595
+ lightVAO: any;
3596
+ /** @property {WebGLVertexArrayObject} - Vertex array object for the composite shader */
3597
+ compositeVAO: any;
3598
+ /** Draw a single Light's falloff blob into the currently bound lightmap.
3599
+ * Called by Light.renderLight() during the plugin's render pass.
3600
+ * @param {Light} light */
3601
+ drawLight(light: Light): void;
3602
+ }
3603
+ /**
3604
+ * A Light is an EngineObject that contributes a soft additive blob of color
3605
+ * to the LightSystem plugin's lightmap.
3606
+ * @extends EngineObject
3607
+ * @memberof LightSystem
3608
+ * @example
3609
+ * new Light(vec2(5, 5), 4, rgb(1, 0.5, 0)); // orange light, full soft blob
3610
+ * new Light(vec2(0, 0), 8, rgb(1, 1, 1), 2); // white core with 2-unit soft halo
3611
+ */
3612
+ export class Light extends EngineObject {
3613
+ /** Create a light object and add it to the engine object list
3614
+ * @param {Vector2} pos - World space position
3615
+ * @param {number} radius - Total extent of the light in world units
3616
+ * @param {Color} [color] - Color of the light; alpha modulates intensity
3617
+ * @param {number} [fadeRange] - Width of the soft edge in world units (defaults to radius) */
3618
+ constructor(pos: Vector2, radius: number, color?: Color, fadeRange?: number);
3619
+ /** @property {number} - Total extent of the light in world units */
3620
+ radius: number;
3621
+ /** @property {number} - Width of the soft edge in world units */
3622
+ fadeRange: number;
3623
+ }
3452
3624
  /**
3453
3625
  * LittleJS ZzFXM Plugin
3454
3626
  * @namespace ZzFXM
@@ -3498,6 +3670,14 @@ declare module "littlejsengine" {
3498
3670
  */
3499
3671
  playMusic(volume?: number, loop?: boolean): SoundInstance;
3500
3672
  }
3673
+ /** Generate samples for a ZzFM song with given parameters
3674
+ * @param {Array} instruments - Array of ZzFX sound parameters
3675
+ * @param {Array} patterns - Array of pattern data
3676
+ * @param {Array} sequence - Array of pattern indexes
3677
+ * @param {number} [BPM] - Playback speed of the song in BPM
3678
+ * @return {Array} - Left and right channel sample data
3679
+ * @memberof ZzFXM */
3680
+ export function zzfxM(instruments: any[], patterns: any[], sequence: any[], BPM?: number): any[];
3501
3681
  /**
3502
3682
  * LittleJS User Interface Plugin
3503
3683
  * - call new UISystemPlugin() to setup the UI system
@@ -3659,6 +3839,7 @@ declare module "littlejsengine" {
3659
3839
  * @param {DragAndDropCallback} [onDragLeave] - when a file is dragged off the window
3660
3840
  * @param {DragAndDropCallback} [onDragOver] - continuously when dragging over */
3661
3841
  setupDragAndDrop(onDrop?: (event: DragEvent) => any, onDragEnter?: (event: DragEvent) => any, onDragLeave?: (event: DragEvent) => any, onDragOver?: (event: DragEvent) => any): void;
3842
+ _dragListeners: any[];
3662
3843
  /** Convert a screen space position to native UI position
3663
3844
  * @param {Vector2} pos
3664
3845
  * @return {Vector2} */
@@ -4225,7 +4406,9 @@ declare module "littlejsengine" {
4225
4406
  /** Add a box shape to the body
4226
4407
  * @param {Vector2} [size]
4227
4408
  * @param {Vector2} [offset]
4228
- * @param {number} [angle]
4409
+ * @param {number} [angle] - LittleJS convention (clockwise positive).
4410
+ * Negated internally to match Box2D's CCW-positive convention so the
4411
+ * fixture aligns with the same angle passed to drawRect/drawTile.
4229
4412
  * @param {number} [density]
4230
4413
  * @param {number} [friction]
4231
4414
  * @param {number} [restitution]
@@ -5086,6 +5269,32 @@ declare module "littlejsengine" {
5086
5269
  * @param {number} [angle] - Angle to rotate by
5087
5270
  * @memberof DrawUtilities */
5088
5271
  export function drawThreeSliceScreen(pos: Vector2, size: Vector2, startTile: TileInfo, borderSize?: number, extraSpace?: number, angle?: number): void;
5272
+ /** Draw a crescent / moon-phase shape built from a polygon
5273
+ * Routes through drawPoly, so it supports WebGL, screen space, color, and outlines
5274
+ * @param {Vector2} pos - Center position
5275
+ * @param {number} [size] - Diameter
5276
+ * @param {number} [percent] - Moon phase over a full cycle (0=new, .25=first quarter, .5=full, .75=last quarter), wraps
5277
+ * @param {Color} [color] - Fill color
5278
+ * @param {number} [angle] - Angle to rotate by
5279
+ * @param {boolean} [invert] - Flip which side is illuminated
5280
+ * @param {number} [lineWidth] - Outline width, 0 for no outline
5281
+ * @param {Color} [lineColor] - Outline color
5282
+ * @param {boolean} [useWebGL=glEnable] - Use WebGL for rendering
5283
+ * @param {boolean} [screenSpace] - Use screen space coordinates
5284
+ * @param {CanvasRenderingContext2D} [context] - Canvas context to use
5285
+ * @memberof DrawUtilities */
5286
+ export function drawCrescent(pos: Vector2, size?: number, percent?: number, color?: Color, angle?: number, invert?: boolean, lineWidth?: number, lineColor?: Color, useWebGL?: boolean, screenSpace?: boolean, context?: CanvasRenderingContext2D): void;
5287
+ /** Get the list of points that make up a crescent / moon-phase shape
5288
+ * Returns world-space points with pos and angle baked in, ready for drawPoly or other use
5289
+ * @param {Vector2} pos - Center position
5290
+ * @param {number} [size] - Diameter
5291
+ * @param {number} [percent] - Moon phase over a full cycle (0=new, .25=first quarter, .5=full, .75=last quarter), wraps
5292
+ * @param {number} [angle] - Angle to rotate by
5293
+ * @param {boolean} [invert] - Flip which side is illuminated
5294
+ * @param {number} [sides=glCircleSides] - Number of sides for a full circle (halved per arc)
5295
+ * @return {Array<Vector2>} - List of points making up the crescent
5296
+ * @memberof DrawUtilities */
5297
+ export function getCrescentPoints(pos: Vector2, size?: number, percent?: number, angle?: number, invert?: boolean, sides?: number): Array<Vector2>;
5089
5298
  /** A numeric tween: drives a callback with a value interpolated between
5090
5299
  * `start` and `end` over `duration` seconds. Pauses with the game by default.
5091
5300
  * @memberof TweenSystem