littlejsengine 1.10.2 → 1.10.4

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 (42) hide show
  1. package/README.md +7 -15
  2. package/dist/littlejs.d.ts +49 -1
  3. package/dist/littlejs.esm.js +60 -37
  4. package/dist/littlejs.esm.min.js +1 -1
  5. package/dist/littlejs.js +46 -37
  6. package/dist/littlejs.min.js +1 -1
  7. package/dist/littlejs.release.js +46 -37
  8. package/examples/box2d/game.js +3 -0
  9. package/examples/breakoutTutorial/README.md +9 -7
  10. package/examples/breakoutTutorial/game.js +6 -6
  11. package/examples/js13k/build/index.html +1 -0
  12. package/examples/js13k/build/index.js +1 -0
  13. package/examples/js13k/build/tiles.png +0 -0
  14. package/examples/js13k/game - Copy.zip +0 -0
  15. package/examples/js13k/game.zip +0 -0
  16. package/examples/platformer/game.js +6 -4
  17. package/examples/platformer/gameCharacter.js +12 -11
  18. package/examples/platformer/gameEffects.js +3 -4
  19. package/examples/platformer/gameLevel.js +17 -33
  20. package/examples/platformer/gameObjects.js +9 -14
  21. package/examples/starter/build/index.html +2 -0
  22. package/examples/starter/build/index.js +1 -0
  23. package/examples/starter/build/tiles.png +0 -0
  24. package/examples/starter/game.zip +0 -0
  25. package/examples/typescript/build/build/littlejs.esm.js +4327 -0
  26. package/examples/typescript/build/dist/littlejs.esm.js +4425 -0
  27. package/examples/typescript/build/examples/typescript/build.js +24 -0
  28. package/examples/typescript/build/examples/typescript/game.js +100 -0
  29. package/examples/typescript/build/examples/typescript/test/build/littlejs.esm.js +3934 -0
  30. package/examples/typescript/build/examples/typescript/test/examples/typescript/build.js +86 -0
  31. package/examples/typescript/build/examples/typescript/test/examples/typescript/game.js +92 -0
  32. package/examples/typescript/game.ts +1 -1
  33. package/package.json +1 -1
  34. package/plugins/postProcess.js +8 -1
  35. package/src/engine.js +5 -13
  36. package/src/engineDraw.js +19 -18
  37. package/src/engineExport.js +14 -0
  38. package/src/engineInput.js +1 -3
  39. package/src/engineObject.js +1 -0
  40. package/src/engineTileLayer.js +2 -1
  41. package/src/engineUtilities.js +1 -0
  42. package/src/engineWebGL.js +17 -2
package/README.md CHANGED
@@ -24,7 +24,7 @@ The code is very clean and well documented with some fun examples to get you sta
24
24
 
25
25
  <div align="center">
26
26
 
27
- ## [Demo](https://killedbyapixel.github.io/LittleJS/examples/starter/) | [Docs](https://killedbyapixel.github.io/LittleJS/docs) | [Trailer](https://youtu.be/chuBzGjv7Ms) | [Discord](https://discord.gg/zb7hcGkyZe) | [Tutorial](https://github.com/KilledByAPixel/LittleJS/blob/main/examples/breakoutTutorial/README.md) | [Quick Reference](https://github.com/KilledByAPixel/LittleJS/blob/main/reference.md)
27
+ ## [Demo](https://killedbyapixel.github.io/LittleJS/examples/starter/) | [Docs](https://killedbyapixel.github.io/LittleJS/docs) | [Trailer](https://youtu.be/chuBzGjv7Ms) | [Discord](https://discord.gg/zb7hcGkyZe) | [Tutorial](https://github.com/KilledByAPixel/LittleJS/blob/main/examples/breakoutTutorial/README.md) | [FAQ](https://github.com/KilledByAPixel/LittleJS/blob/main/FAQ.md)
28
28
 
29
29
  </div>
30
30
 
@@ -83,13 +83,11 @@ To get started download the latest LittleJS package from GitHub or install via n
83
83
 
84
84
  This is because web browsers just have protection from loading local files. You may see a console error like "The image element contains cross-origin data." Don't panic, it's easy to fix! If you are using [Visual Studio Code](https://code.visualstudio.com/) there is a [Live Preview Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.live-server) that will handle this for you automatically. Another option is to setup a simple local web server like [http-server](https://www.npmjs.com/package/http-server) via npm.
85
85
 
86
- Learn how to make a simple game from scratch with [The Breakout Tutorial.](https://github.com/KilledByAPixel/LittleJS/tree/main/examples/breakoutTutorial)
87
-
88
- [LittleJS Engine Quick Reference Sheet](https://github.com/KilledByAPixel/LittleJS/blob/main/reference.md) - This cheat sheet can help you get started.
89
-
90
- [Watch this GitNation talk](https://youtu.be/_dXKU0WgAj8?si=ZDXLYAFDWp54hrGT) to hear more about LittleJS works and get some tips on how to use it.
91
-
92
- Join our vibrant community on [Discord](https://discord.gg/zb7hcGkyZe) to get help, share your projects, and collaborate with others!
86
+ - Learn how to make a simple game from scratch with [The Breakout Tutorial.](https://github.com/KilledByAPixel/LittleJS/tree/main/examples/breakoutTutorial)
87
+ - [LittleJS Engine Quick Reference Sheet](https://github.com/KilledByAPixel/LittleJS/blob/main/reference.md) - This cheat sheet can help you get started.
88
+ - [Watch this GitNation talk](https://youtu.be/_dXKU0WgAj8?si=ZDXLYAFDWp54hrGT) to hear more about LittleJS works and get some tips on how to use it.
89
+ - Join our vibrant community on [Discord](https://discord.gg/zb7hcGkyZe) to get help, share your projects, and collaborate with others!
90
+ - [Check out The Little JS FAQ for more help getting started](https://github.com/KilledByAPixel/LittleJS/blob/main/FAQ.md), and let us know if there's anything you'd like to see added.
93
91
 
94
92
  ## Examples
95
93
 
@@ -102,6 +100,7 @@ These demos are for both learning and using as starter projects to create your o
102
100
  - [Box2D Demo](https://killedbyapixel.github.io/LittleJS/examples/box2d/) - Box2D plugin demonstration and testbed
103
101
  - [Stress Test](https://killedbyapixel.github.io/LittleJS/examples/stress/) - Max sprite/object test and music system demo
104
102
  - [Particle System Designer](https://killedbyapixel.github.io/LittleJS/examples/particles/) - Particle system editor and visualizer
103
+ - [All Examples](https://killedbyapixel.github.io/LittleJS/examples/) - Links to all the example projects on one page
105
104
 
106
105
  ## Builds
107
106
 
@@ -189,13 +188,6 @@ class MyObject extends EngineObject
189
188
 
190
189
  Debug builds of LittleJS have a special menu that can be opened by pressing the Esc key.
191
190
 
192
- - Esc: Debug Overlay
193
- - 1: Debug Physics
194
- - 2: Debug Particles
195
- - 3: Debug Gamepads
196
- - 4: Debug Raycasts
197
- - 5: Save Screenshot
198
-
199
191
  ## Games Made With LittleJS
200
192
 
201
193
  Here are a few of the amazing games people made using LittleJS...
@@ -69,7 +69,7 @@ declare module "littlejsengine" {
69
69
  * @param {Function} gameUpdatePost - Called after physics and objects are updated, setup camera and prepare for render
70
70
  * @param {Function} gameRender - Called before objects are rendered, draw any background effects that appear behind objects
71
71
  * @param {Function} gameRenderPost - Called after objects are rendered, draw effects or hud that appear above all objects
72
- * @param {Array} [imageSources=['tiles.png']] - Image to load
72
+ * @param {Array} [imageSources=[]] - Image to load
73
73
  * @param {HTMLElement} [rootElement] - Root element to attach to, the document body by default
74
74
  * @memberof Engine */
75
75
  export function engineInit(gameInit: Function, gameUpdate: Function, gameUpdatePost: Function, gameRender: Function, gameRenderPost: Function, imageSources?: any[], rootElement?: HTMLElement): void;
@@ -1245,6 +1245,37 @@ declare module "littlejsengine" {
1245
1245
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
1246
1246
  * @memberof Draw */
1247
1247
  export function drawLine(posA: Vector2, posB: Vector2, thickness?: number, color?: Color, useWebGL?: boolean, screenSpace?: boolean, context?: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D): void;
1248
+ /** Draw colored polygon using passed in points
1249
+ * @param {Array} points - Array of Vector2 points
1250
+ * @param {Color} [color=(1,1,1,1)]
1251
+ * @param {Number} [lineWidth=0]
1252
+ * @param {Color} [lineColor=(0,0,0,1)]
1253
+ * @param {Boolean} [screenSpace=false]
1254
+ * @param {CanvasRenderingContext2D} [context=mainContext]
1255
+ * @memberof Draw */
1256
+ export function drawPoly(points: any[], color?: Color, lineWidth?: number, lineColor?: Color, screenSpace?: boolean, context?: CanvasRenderingContext2D): void;
1257
+ /** Draw colored ellipse using passed in point
1258
+ * @param {Vector2} pos
1259
+ * @param {Number} [width=1]
1260
+ * @param {Number} [height=1]
1261
+ * @param {Number} [angle=0]
1262
+ * @param {Color} [color=(1,1,1,1)]
1263
+ * @param {Number} [lineWidth=0]
1264
+ * @param {Color} [lineColor=(0,0,0,1)]
1265
+ * @param {Boolean} [screenSpace=false]
1266
+ * @param {CanvasRenderingContext2D} [context=mainContext]
1267
+ * @memberof Draw */
1268
+ export function drawEllipse(pos: Vector2, width?: number, height?: number, angle?: number, color?: Color, lineWidth?: number, lineColor?: Color, screenSpace?: boolean, context?: CanvasRenderingContext2D): void;
1269
+ /** Draw colored circle using passed in point
1270
+ * @param {Vector2} pos
1271
+ * @param {Number} [radius=1]
1272
+ * @param {Color} [color=(1,1,1,1)]
1273
+ * @param {Number} [lineWidth=0]
1274
+ * @param {Color} [lineColor=(0,0,0,1)]
1275
+ * @param {Boolean} [screenSpace=false]
1276
+ * @param {CanvasRenderingContext2D} [context=mainContext]
1277
+ * @memberof Draw */
1278
+ export function drawCircle(pos: Vector2, radius?: number, color?: Color, lineWidth?: number, lineColor?: Color, screenSpace?: boolean, context?: CanvasRenderingContext2D): void;
1248
1279
  /** Draw directly to a 2d canvas context in world space
1249
1280
  * @param {Vector2} pos
1250
1281
  * @param {Vector2} size
@@ -1403,6 +1434,23 @@ declare module "littlejsengine" {
1403
1434
  * @param {WebGLTexture} texture
1404
1435
  * @memberof WebGL */
1405
1436
  export function glSetTexture(texture: WebGLTexture): void;
1437
+ /** Set antialiasing for webgl canvas
1438
+ * @param {Boolean} [antialias]
1439
+ * @memberof WebGL */
1440
+ export function glSetAntialias(antialias?: boolean): void;
1441
+ /** Shoule webgl be setup with antialiasing, must be set before calling engineInit
1442
+ * @type {Boolean}
1443
+ * @memberof WebGL */
1444
+ export let glAntialias: boolean;
1445
+ export let glShader: any;
1446
+ export let glActiveTexture: any;
1447
+ export let glArrayBuffer: any;
1448
+ export let glGeometryBuffer: any;
1449
+ export let glPositionData: any;
1450
+ export let glColorData: any;
1451
+ export let glInstanceCount: any;
1452
+ export let glAdditive: any;
1453
+ export let glBatchAdditive: any;
1406
1454
  /**
1407
1455
  * LittleJS Input System
1408
1456
  * - Tracks keyboard down, pressed, and released
@@ -953,6 +953,7 @@ class Vector2
953
953
  * @param {Number} [length] */
954
954
  setDirection(direction, length=1)
955
955
  {
956
+ direction = mod(direction, 4);
956
957
  ASSERT(direction==0 || direction==1 || direction==2 || direction==3);
957
958
  return vec2(direction%2 ? direction-1 ? -length : length : 0,
958
959
  direction%2 ? 0 : direction ? -length : length);
@@ -2135,6 +2136,7 @@ class EngineObject
2135
2136
  this.pos.x = oldPos.x;
2136
2137
  this.velocity.x *= -this.elasticity;
2137
2138
  }
2139
+ debugOverlay && debugPhysics && debugRect(this.pos, this.size, '#f00');
2138
2140
  }
2139
2141
  }
2140
2142
  }
@@ -2567,6 +2569,22 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
2567
2569
  drawTile(pos, size, undefined, color, angle, false, undefined, useWebGL, screenSpace, context);
2568
2570
  }
2569
2571
 
2572
+ /** Draw colored line between two points
2573
+ * @param {Vector2} posA
2574
+ * @param {Vector2} posB
2575
+ * @param {Number} [thickness]
2576
+ * @param {Color} [color=(1,1,1,1)]
2577
+ * @param {Boolean} [useWebGL=glEnable]
2578
+ * @param {Boolean} [screenSpace=false]
2579
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
2580
+ * @memberof Draw */
2581
+ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
2582
+ {
2583
+ const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
2584
+ const size = vec2(thickness, halfDelta.length()*2);
2585
+ drawRect(posA.add(halfDelta), size, color, halfDelta.angle(), useWebGL, screenSpace, context);
2586
+ }
2587
+
2570
2588
  /** Draw colored polygon using passed in points
2571
2589
  * @param {Array} points - Array of Vector2 points
2572
2590
  * @param {Color} [color=(1,1,1,1)]
@@ -2635,22 +2653,6 @@ function drawEllipse(pos, width=1, height=1, angle=0, color=new Color, lineWidth
2635
2653
  function drawCircle(pos, radius=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), screenSpace, context=mainContext)
2636
2654
  { drawEllipse(pos, radius, radius, 0, color, lineWidth, lineColor, screenSpace, context); }
2637
2655
 
2638
- /** Draw colored line between two points
2639
- * @param {Vector2} posA
2640
- * @param {Vector2} posB
2641
- * @param {Number} [thickness]
2642
- * @param {Color} [color=(1,1,1,1)]
2643
- * @param {Boolean} [useWebGL=glEnable]
2644
- * @param {Boolean} [screenSpace=false]
2645
- * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
2646
- * @memberof Draw */
2647
- function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
2648
- {
2649
- const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
2650
- const size = vec2(thickness, halfDelta.length()*2);
2651
- drawRect(posA.add(halfDelta), size, color, halfDelta.angle(), useWebGL, screenSpace, context);
2652
- }
2653
-
2654
2656
  /** Draw directly to a 2d canvas context in world space
2655
2657
  * @param {Vector2} pos
2656
2658
  * @param {Vector2} size
@@ -2842,13 +2844,14 @@ function isFullscreen() { return !!document.fullscreenElement; }
2842
2844
  * @memberof Draw */
2843
2845
  function toggleFullscreen()
2844
2846
  {
2847
+ const rootElement = mainCanvas.parentElement;
2845
2848
  if (isFullscreen())
2846
2849
  {
2847
2850
  if (document.exitFullscreen)
2848
2851
  document.exitFullscreen();
2849
2852
  }
2850
- else if (engineRoot.requestFullscreen)
2851
- engineRoot.requestFullscreen();
2853
+ else if (rootElement.requestFullscreen)
2854
+ rootElement.requestFullscreen();
2852
2855
  }
2853
2856
  /**
2854
2857
  * LittleJS Input System
@@ -3019,7 +3022,6 @@ function inputInit()
3019
3022
 
3020
3023
  onkeydown = (e)=>
3021
3024
  {
3022
- if (debug && e.target != engineRoot) return;
3023
3025
  if (!e.repeat)
3024
3026
  {
3025
3027
  isUsingGamepad = false;
@@ -3032,7 +3034,6 @@ function inputInit()
3032
3034
 
3033
3035
  onkeyup = (e)=>
3034
3036
  {
3035
- if (debug && e.target != engineRoot) return;
3036
3037
  inputData[0][e.code] = 4;
3037
3038
  if (inputWASDEmulateDirection)
3038
3039
  inputData[0][remapKey(e.code)] = 4;
@@ -3234,7 +3235,7 @@ function touchInputInit()
3234
3235
  // set event pos and pass it along
3235
3236
  const p = vec2(e.touches[0].clientX, e.touches[0].clientY);
3236
3237
  mousePosScreen = mouseToScreen(p);
3237
- wasTouching ? isUsingGamepad = false : inputData[0][button] = 3;
3238
+ wasTouching ? isUsingGamepad = touchGamepadEnable : inputData[0][button] = 3;
3238
3239
  }
3239
3240
  else if (wasTouching)
3240
3241
  inputData[0][button] = inputData[0][button] & 2 | 4;
@@ -4030,6 +4031,7 @@ function tileCollisionTest(pos, size=vec2(), object)
4030
4031
  if (tileData && (!object || object.collideWithTile(tileData, vec2(x, y))))
4031
4032
  return true;
4032
4033
  }
4034
+ return false;
4033
4035
  }
4034
4036
 
4035
4037
  /** Return the center of first tile hit (does not return the exact intersection)
@@ -4053,7 +4055,7 @@ function tileCollisionRaycast(posStart, posEnd, object)
4053
4055
  let xi = unit.x * (delta.x < 0 ? posStart.x - pos.x : pos.x - posStart.x + 1);
4054
4056
  let yi = unit.y * (delta.y < 0 ? posStart.y - pos.y : pos.y - posStart.y + 1);
4055
4057
 
4056
- while (1)
4058
+ while (true)
4057
4059
  {
4058
4060
  // check for tile collision
4059
4061
  const tileData = getTileCollisionData(pos);
@@ -4862,6 +4864,11 @@ let glCanvas;
4862
4864
  * @memberof WebGL */
4863
4865
  let glContext;
4864
4866
 
4867
+ /** Shoule webgl be setup with antialiasing, must be set before calling engineInit
4868
+ * @type {Boolean}
4869
+ * @memberof WebGL */
4870
+ let glAntialias = true;
4871
+
4865
4872
  // WebGL internal variables not exposed to documentation
4866
4873
  let glShader, glActiveTexture, glArrayBuffer, glGeometryBuffer, glPositionData, glColorData, glInstanceCount, glAdditive, glBatchAdditive;
4867
4874
 
@@ -4874,10 +4881,11 @@ function glInit()
4874
4881
 
4875
4882
  // create the canvas and textures
4876
4883
  glCanvas = document.createElement('canvas');
4877
- glContext = glCanvas.getContext('webgl2', {antialias:!canvasPixelated});
4884
+ glContext = glCanvas.getContext('webgl2', {antialias:glAntialias});
4878
4885
 
4879
4886
  // some browsers are much faster without copying the gl buffer so we just overlay it instead
4880
- glOverlay && engineRoot.appendChild(glCanvas);
4887
+ const rootElement = mainCanvas.parentElement;
4888
+ glOverlay && rootElement.appendChild(glCanvas);
4881
4889
 
4882
4890
  // setup vertex and fragment shaders
4883
4891
  glShader = glCreateProgram(
@@ -5081,6 +5089,15 @@ function glCopyToContext(context, forceDraw=false)
5081
5089
  context.drawImage(glCanvas, 0, 0);
5082
5090
  }
5083
5091
 
5092
+ /** Set antialiasing for webgl canvas
5093
+ * @param {Boolean} [antialias]
5094
+ * @memberof WebGL */
5095
+ function glSetAntialias(antialias=true)
5096
+ {
5097
+ ASSERT(!glCanvas, 'must be called before engineInit');
5098
+ glAntialias = antialias;
5099
+ }
5100
+
5084
5101
  /** Add a sprite to the gl draw list, used by all gl draw functions
5085
5102
  * @param {Number} x
5086
5103
  * @param {Number} y
@@ -5181,7 +5198,7 @@ const engineName = 'LittleJS';
5181
5198
  * @type {String}
5182
5199
  * @default
5183
5200
  * @memberof Engine */
5184
- const engineVersion = '1.10.2';
5201
+ const engineVersion = '1.10.4';
5185
5202
 
5186
5203
  /** Frames per second to update
5187
5204
  * @type {Number}
@@ -5225,13 +5242,6 @@ let timeReal = 0;
5225
5242
  * @default false
5226
5243
  * @memberof Engine */
5227
5244
  let paused = false;
5228
-
5229
- /** The root element that engine is attached to
5230
- * @type {HTMLElement}
5231
- * @default document.body
5232
- * @memberof Engine */
5233
- let engineRoot;
5234
-
5235
5245
  /** Set if game is paused
5236
5246
  * @param {Boolean} isPaused
5237
5247
  * @memberof Engine */
@@ -5264,7 +5274,7 @@ function engineAddPlugin(updateFunction, renderFunction)
5264
5274
  * @param {Function} gameUpdatePost - Called after physics and objects are updated, setup camera and prepare for render
5265
5275
  * @param {Function} gameRender - Called before objects are rendered, draw any background effects that appear behind objects
5266
5276
  * @param {Function} gameRenderPost - Called after objects are rendered, draw effects or hud that appear above all objects
5267
- * @param {Array} [imageSources=['tiles.png']] - Image to load
5277
+ * @param {Array} [imageSources=[]] - Image to load
5268
5278
  * @param {HTMLElement} [rootElement] - Root element to attach to, the document body by default
5269
5279
  * @memberof Engine */
5270
5280
  function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
@@ -5438,9 +5448,8 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
5438
5448
  (!touchInputEnable ? '' : // no touch css setttings
5439
5449
  'touch-action:none;' + // prevent mobile pinch to resize
5440
5450
  '-webkit-touch-callout:none');// compatibility for ios
5441
- engineRoot = rootElement;
5442
- engineRoot.style.cssText = styleRoot;
5443
- engineRoot.appendChild(mainCanvas = document.createElement('canvas'));
5451
+ rootElement.style.cssText = styleRoot;
5452
+ rootElement.appendChild(mainCanvas = document.createElement('canvas'));
5444
5453
  mainContext = mainCanvas.getContext('2d');
5445
5454
 
5446
5455
  // init stuff and start engine
@@ -5450,7 +5459,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
5450
5459
  glInit();
5451
5460
 
5452
5461
  // create overlay canvas for hud to appear above gl canvas
5453
- engineRoot.appendChild(overlayCanvas = document.createElement('canvas'));
5462
+ rootElement.appendChild(overlayCanvas = document.createElement('canvas'));
5454
5463
  overlayContext = overlayCanvas.getContext('2d');
5455
5464
 
5456
5465
  // set canvas style
@@ -5964,6 +5973,9 @@ export {
5964
5973
  drawTile,
5965
5974
  drawRect,
5966
5975
  drawLine,
5976
+ drawPoly,
5977
+ drawEllipse,
5978
+ drawCircle,
5967
5979
  drawCanvas2D,
5968
5980
  setBlendMode,
5969
5981
  drawTextScreen,
@@ -5984,6 +5996,17 @@ export {
5984
5996
  glDraw,
5985
5997
  glFlush,
5986
5998
  glSetTexture,
5999
+ glSetAntialias,
6000
+ glAntialias,
6001
+ glShader,
6002
+ glActiveTexture,
6003
+ glArrayBuffer,
6004
+ glGeometryBuffer,
6005
+ glPositionData,
6006
+ glColorData,
6007
+ glInstanceCount,
6008
+ glAdditive,
6009
+ glBatchAdditive,
5987
6010
 
5988
6011
  // Input
5989
6012
  keyIsDown,