littlejsengine 1.3.0 → 1.3.8

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.
@@ -53,18 +53,26 @@ let overlayContext;
53
53
  let mainCanvasSize = vec2();
54
54
 
55
55
  /** Convert from screen to world space coordinates
56
+ * - if calling outside of render, you may need to manually set mainCanvasSize
56
57
  * @param {Vector2} screenPos
57
58
  * @return {Vector2}
58
59
  * @memberof Draw */
59
60
  const screenToWorld = (screenPos)=>
60
- screenPos.add(vec2(.5)).subtract(mainCanvasSize.scale(.5)).multiply(vec2(1/cameraScale,-1/cameraScale)).add(cameraPos);
61
+ {
62
+ ASSERT(mainCanvasSize.x && mainCanvasSize.y, 'mainCanvasSize is invalid');
63
+ return screenPos.add(vec2(.5)).subtract(mainCanvasSize.scale(.5)).multiply(vec2(1/cameraScale,-1/cameraScale)).add(cameraPos);
64
+ }
61
65
 
62
66
  /** Convert from world to screen space coordinates
67
+ * - if calling outside of render, you may need to manually set mainCanvasSize
63
68
  * @param {Vector2} worldPos
64
69
  * @return {Vector2}
65
70
  * @memberof Draw */
66
71
  const worldToScreen = (worldPos)=>
67
- worldPos.subtract(cameraPos).multiply(vec2(cameraScale,-cameraScale)).add(mainCanvasSize.scale(.5)).subtract(vec2(.5));
72
+ {
73
+ ASSERT(mainCanvasSize.x && mainCanvasSize.y, 'mainCanvasSize is invalid');
74
+ return worldPos.subtract(cameraPos).multiply(vec2(cameraScale,-cameraScale)).add(mainCanvasSize.scale(.5)).subtract(vec2(.5));
75
+ }
68
76
 
69
77
  /** Draw textured tile centered in world space, with color applied if using WebGL
70
78
  * @param {Vector2} pos - Center of the tile in world space
@@ -165,7 +173,7 @@ function drawTileScreenSpace(pos, size=vec2(1), tileIndex, tileSize, color, angl
165
173
  * @memberof Draw */
166
174
  function drawRectScreenSpace(pos, size, color, angle, useWebGL)
167
175
  {
168
- drawTileSrceenSpace(pos, size, -1, tileSizeDefault, color, angle, 0, 0, useWebGL);
176
+ drawTileScreenSpace(pos, size, -1, tileSizeDefault, color, angle, 0, 0, useWebGL);
169
177
  }
170
178
 
171
179
  /** Draw colored line between two points
@@ -228,14 +236,15 @@ function setBlendMode(additive, useWebGL=glEnable)
228
236
  function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), textAlign='center', font=fontDefault)
229
237
  {
230
238
  overlayContext.fillStyle = color;
231
- overlayContext.lineWidth = lineWidth *= cameraScale;
239
+ overlayContext.lineWidth = lineWidth;
232
240
  overlayContext.strokeStyle = lineColor;
233
241
  overlayContext.textAlign = textAlign;
234
242
  overlayContext.font = size + 'px '+ font;
235
243
  overlayContext.textBaseline = 'middle';
244
+ overlayContext.lineJoin = 'round';
236
245
 
237
246
  pos = pos.copy();
238
- text.split('\n').forEach(line=>
247
+ (text+'').split('\n').forEach(line=>
239
248
  {
240
249
  lineWidth && overlayContext.strokeText(line, pos.x, pos.y);
241
250
  overlayContext.fillText(line, pos.x, pos.y);
@@ -255,7 +264,7 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
255
264
  * @memberof Draw */
256
265
  function drawText(text, pos, size=1, color, lineWidth, lineColor, textAlign, font)
257
266
  {
258
- drawTextScreen(text, worldToScreen(pos), size*cameraScale, color, lineWidth, lineColor, textAlign, font);
267
+ drawTextScreen(text, worldToScreen(pos), size*cameraScale, color, lineWidth*cameraScale, lineColor, textAlign, font);
259
268
  }
260
269
 
261
270
  ///////////////////////////////////////////////////////////////////////////////
@@ -70,6 +70,10 @@ let mouseWheel = 0;
70
70
  * @memberof Input */
71
71
  let isUsingGamepad = 0;
72
72
 
73
+ /** Prevents input continuing to the default browser handling (false by default)
74
+ * @memberof Input */
75
+ let preventDefaultInput = 0;
76
+
73
77
  /** Returns true if gamepad button is down
74
78
  * @param {Number} button
75
79
  * @param {Number} [gamepad=0]
@@ -133,7 +137,7 @@ onkeydown = (e)=>
133
137
  {
134
138
  if (debug && e.target != document.body) return;
135
139
  e.repeat || (inputData[isUsingGamepad = 0][remapKeyCode(e.keyCode)] = 3);
136
- debug || e.preventDefault();
140
+ preventDefaultInput && e.preventDefault();
137
141
  }
138
142
  onkeyup = (e)=>
139
143
  {
@@ -158,7 +162,7 @@ const mouseToScreen = (mousePos)=>
158
162
  return vec2(); // fix bug that can occur if user clicks before page loads
159
163
 
160
164
  const rect = mainCanvas.getBoundingClientRect();
161
- return mainCanvasSize.multiply(
165
+ return vec2(mainCanvas.width, mainCanvas.height).multiply(
162
166
  vec2(percent(mousePos.x, rect.left, rect.right), percent(mousePos.y, rect.top, rect.bottom)));
163
167
  }
164
168
 
@@ -192,7 +192,7 @@ class Newgrounds
192
192
  cipher && (this.cryptoJS = CryptoJS());
193
193
 
194
194
  // get session id from url search params
195
- const url = new URL(window.location.href);
195
+ const url = new URL(location.href);
196
196
  this.session_id = url.searchParams.get('ngio_session_id') || 0;
197
197
 
198
198
  if (this.session_id == 0)
@@ -34,7 +34,7 @@ class EngineObject
34
34
  /** Create an engine object and adds it to the list of objects
35
35
  * @param {Vector2} [position=new Vector2()] - World space position of the object
36
36
  * @param {Vector2} [size=objectDefaultSize] - World space size of the object
37
- * @param {Number} [tileIndex=-1] - Tile to use to render object, untextured if -1
37
+ * @param {Number} [tileIndex=-1] - Tile to use to render object (-1 is untextured)
38
38
  * @param {Vector2} [tileSize=tileSizeDefault] - Size of tile in source pixels
39
39
  * @param {Number} [angle=0] - Angle the object is rotated by
40
40
  * @param {Color} [color] - Color to apply to tile when rendered
@@ -51,7 +51,7 @@ class EngineObject
51
51
  this.size = size;
52
52
  /** @property {Vector2} - Size of object used for drawing, uses size if not set */
53
53
  this.drawSize;
54
- /** @property {Number} - Tile to use to render object, untextured if -1 */
54
+ /** @property {Number} - Tile to use to render object (-1 is untextured) */
55
55
  this.tileIndex = tileIndex;
56
56
  /** @property {Vector2} - Size of tile in source pixels */
57
57
  this.tileSize = tileSize;
@@ -63,7 +63,7 @@ class EngineObject
63
63
  this.additiveColor;
64
64
 
65
65
  // set object defaults
66
- /** @property {Number} [mass=objectDefaultMass] - How heavy the object is */
66
+ /** @property {Number} [mass=objectDefaultMass] - How heavy the object is, static if 0 */
67
67
  this.mass = objectDefaultMass;
68
68
  /** @property {Number} [damping=objectDefaultDamping] - How much to slow down velocity each frame (0-1) */
69
69
  this.damping = objectDefaultDamping;
@@ -117,7 +117,7 @@ class EngineObject
117
117
  ASSERT(this.angleDamping >= 0 && this.angleDamping <= 1);
118
118
  ASSERT(this.damping >= 0 && this.damping <= 1);
119
119
 
120
- if (!this.mass) // do not update collision for fixed objects
120
+ if (!enablePhysicsSolver || !this.mass) // do not update collision for fixed objects
121
121
  return;
122
122
 
123
123
  const wasMovingDown = this.velocity.y < 0;
@@ -127,7 +127,7 @@ class EngineObject
127
127
  const groundSpeed = this.groundObject.velocity ? this.groundObject.velocity.x : 0;
128
128
  this.velocity.x = groundSpeed + (this.velocity.x - groundSpeed) * this.friction;
129
129
  this.groundObject = 0;
130
- //debugPhysics && debugPoint(this.pos.subtract(vec2(0,this.size.y/2)), '#0f0');
130
+ //debugOverlay && debugPhysics && debugPoint(this.pos.subtract(vec2(0,this.size.y/2)), '#0f0');
131
131
  }
132
132
 
133
133
  if (this.collideSolidObjects)
@@ -159,7 +159,7 @@ class EngineObject
159
159
  if (o.mass) // push away if not fixed
160
160
  o.velocity = o.velocity.subtract(velocity);
161
161
 
162
- debugPhysics && debugAABB(this.pos, this.size, o.pos, o.size, '#f00');
162
+ debugOverlay && debugPhysics && debugAABB(this.pos, this.size, o.pos, o.size, '#f00');
163
163
  continue;
164
164
  }
165
165
 
@@ -222,7 +222,7 @@ class EngineObject
222
222
  else // bounce if other object is fixed
223
223
  this.velocity.x *= -this.elasticity;
224
224
  }
225
- debugPhysics && debugAABB(this.pos, this.size, o.pos, o.size, '#f0f');
225
+ debugOverlay && debugPhysics && debugAABB(this.pos, this.size, o.pos, o.size, '#f0f');
226
226
  }
227
227
  }
228
228
  if (this.collideTiles)
@@ -355,17 +355,20 @@ class EngineObject
355
355
 
356
356
  toString()
357
357
  {
358
- let text = 'type = ' + this.constructor.name;
359
- if (this.pos.x || this.pos.y)
360
- text += '\npos = ' + this.pos;
361
- if (this.velocity.x || this.velocity.y)
362
- text += '\nvelocity = ' + this.velocity;
363
- if (this.size.x || this.size.y)
364
- text += '\nsize = ' + this.size;
365
- if (this.angle)
366
- text += '\nangle = ' + this.angle.toFixed(3);
367
- if (this.color)
368
- text += '\ncolor = ' + this.color;
369
- return text;
358
+ if (debug)
359
+ {
360
+ let text = 'type = ' + this.constructor.name;
361
+ if (this.pos.x || this.pos.y)
362
+ text += '\npos = ' + this.pos;
363
+ if (this.velocity.x || this.velocity.y)
364
+ text += '\nvelocity = ' + this.velocity;
365
+ if (this.size.x || this.size.y)
366
+ text += '\nsize = ' + this.size;
367
+ if (this.angle)
368
+ text += '\nangle = ' + this.angle.toFixed(3);
369
+ if (this.color)
370
+ text += '\ncolor = ' + this.color;
371
+ return text;
372
+ }
370
373
  }
371
374
  }
@@ -113,7 +113,7 @@ class ParticleEmitter extends EngineObject
113
113
  // particle settings
114
114
  /** @property {Number} - How long particles live */
115
115
  this.particleTime = particleTime;
116
- /** @property {Number} - How big are particles at start */
116
+ /** @property {Number} - How big are particles at start */
117
117
  this.sizeStart = sizeStart;
118
118
  /** @property {Number} - How big are particles at end */
119
119
  this.sizeEnd = sizeEnd;
@@ -8,9 +8,9 @@
8
8
 
9
9
  'use strict';
10
10
 
11
+ let showWatermark = 0;
12
+ let godMode = 0;
11
13
  const debug = 0;
12
- const showWatermark = 0;
13
- const godMode = 0;
14
14
  const debugOverlay = 0;
15
15
  const debugPhysics = 0;
16
16
  const debugParticles = 0;
@@ -14,7 +14,8 @@
14
14
  * @memberof Settings */
15
15
  let canvasMaxSize = vec2(1920, 1200);
16
16
 
17
- /** Fixed size of the canvas, if enabled cavnvas size never changes
17
+ /** Fixed size of the canvas, if enabled canvas size never changes
18
+ * - you may also need to set mainCanvasSize if using screen space coords in startup
18
19
  * @type {Vector2}
19
20
  * @default
20
21
  * @memberof Settings */
@@ -53,6 +54,11 @@ let tileFixBleedScale = .3;
53
54
  * @memberof Settings */
54
55
  let objectDefaultSize = vec2(1);
55
56
 
57
+ /** Enable physics solver for collisions between objects
58
+ * @default
59
+ * @memberof Settings */
60
+ let enablePhysicsSolver = 1;
61
+
56
62
  /** Default object mass for collison calcuations (how heavy objects are)
57
63
  * @default
58
64
  * @memberof Settings */
@@ -255,7 +255,7 @@ class Vector2
255
255
  /** Returns a new vector in same direction as this one with the length passed in
256
256
  * @param {Number} [length=1]
257
257
  * @return {Vector2} */
258
- normalize(length=1) { const l = this.length(); return l ? this.scale(length/l) : new Vector2(length); }
258
+ normalize(length=1) { const l = this.length(); return l ? this.scale(length/l) : new Vector2(0, length); }
259
259
 
260
260
  /** Returns a new vector clamped to length passed in
261
261
  * @param {Number} [length=1]
@@ -300,7 +300,7 @@ class Vector2
300
300
 
301
301
  /** Returns the area this vector covers as a rectangle
302
302
  * @return {Number} */
303
- area() { return this.x * this.y; }
303
+ area() { return abs(this.x * this.y); }
304
304
 
305
305
  /** Returns a new vector that is p percent between this and the vector passed in
306
306
  * @param {Vector2} vector
@@ -409,6 +409,34 @@ class Color
409
409
  return this;
410
410
  }
411
411
 
412
+ /** Returns this color expressed in hsla format
413
+ * @return {Array} */
414
+ getHSLA()
415
+ {
416
+ const r = this.r;
417
+ const g = this.g;
418
+ const b = this.b;
419
+ const a = this.a;
420
+ const max = Math.max(r, g, b);
421
+ const min = Math.min(r, g, b);
422
+ const l = (max + min) / 2;
423
+
424
+ let h = 0, s = 0;
425
+ if (max != min)
426
+ {
427
+ let d = max - min;
428
+ s = l > .5 ? d / (2 - max - min) : d / (max + min);
429
+ if (r == max)
430
+ h = (g - b) / d + (g < b ? 6 : 0);
431
+ else if (g == max)
432
+ h = (b - r) / d + 2;
433
+ else if (b == max)
434
+ h = (r - g) / d + 4;
435
+ }
436
+
437
+ return [h / 6, s, l, a];
438
+ }
439
+
412
440
  /** Returns a new color that has each component randomly adjusted
413
441
  * @param {Number} [amount=.05]
414
442
  * @param {Number} [alphaAmount=0]
@@ -440,14 +468,6 @@ class Color
440
468
  return (this.r*255|0) + (this.g*255<<8) + (this.b*255<<16) + (this.a*255<<24);
441
469
  }
442
470
 
443
- /** Returns this color expressed as a hex code
444
- * @return {String} */
445
- hex()
446
- {
447
- const toHex = (c)=> ((c=c*255|0)<16 ? '0' : '') + c.toString(16);
448
- return '#' + toHex(this.r) + toHex(this.g) + toHex(this.b);
449
- }
450
-
451
471
  /** Set this color from a hex code
452
472
  * @param {String} hex - html hex code
453
473
  * @return {Color} */
@@ -461,6 +481,14 @@ class Color
461
481
  ASSERT(this.r>=0 && this.r<=1 && this.g>=0 && this.g<=1 && this.b>=0 && this.b<=1);
462
482
  return this;
463
483
  }
484
+
485
+ /** Returns this color expressed as a hex code
486
+ * @return {String} */
487
+ getHex()
488
+ {
489
+ const toHex = (c)=> ((c=c*255|0)<16 ? '0' : '') + c.toString(16);
490
+ return '#' + toHex(this.r) + toHex(this.g) + toHex(this.b);
491
+ }
464
492
  }
465
493
 
466
494
  ///////////////////////////////////////////////////////////////////////////////
@@ -509,5 +537,5 @@ class Timer
509
537
 
510
538
  /** Returns this timer expressed as a string
511
539
  * @return {String} */
512
- toString() { return this.unset() ? 'unset' : Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ); }
540
+ toString() { if (debug) { return this.unset() ? 'unset' : Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ); } }
513
541
  }
@@ -244,7 +244,7 @@ function glFlush()
244
244
  * @memberof WebGL */
245
245
  function glCopyToContext(context, forceDraw)
246
246
  {
247
- if (!glEnable || !glBatchCount) return;
247
+ if ((!glEnable || !glBatchCount) && !forceDraw) return;
248
248
 
249
249
  glFlush();
250
250
 
package/engine/index.d.ts CHANGED
@@ -240,7 +240,7 @@ declare const enableAsserts: 1;
240
240
  * @default
241
241
  * @memberof Debug */
242
242
  declare const debugPointSize: 0.5;
243
- /** True if watermark with FPS should be down
243
+ /** True if watermark with FPS should be down, false in release builds
244
244
  * @default
245
245
  * @memberof Debug */
246
246
  declare let showWatermark: number;
@@ -629,6 +629,9 @@ declare class Color {
629
629
  * @param {Number} [alpha=1]
630
630
  * @return {Color} */
631
631
  setHSLA(h?: number, s?: number, l?: number, a?: number): Color;
632
+ /** Returns this color expressed in hsla format
633
+ * @return {Array} */
634
+ getHSLA(): any[];
632
635
  /** Returns a new color that has each component randomly adjusted
633
636
  * @param {Number} [amount=.05]
634
637
  * @param {Number} [alphaAmount=0]
@@ -640,13 +643,13 @@ declare class Color {
640
643
  /** Returns this color expressed as 32 bit integer RGBA value
641
644
  * @return {Number} */
642
645
  rgbaInt(): number;
643
- /** Returns this color expressed as a hex code
644
- * @return {String} */
645
- hex(): string;
646
646
  /** Set this color from a hex code
647
647
  * @param {String} hex - html hex code
648
648
  * @return {Color} */
649
649
  setHex(hex: string): Color;
650
+ /** Returns this color expressed as a hex code
651
+ * @return {String} */
652
+ getHex(): string;
650
653
  }
651
654
  /**
652
655
  * Timer object tracks how long has passed since it was set
@@ -692,7 +695,8 @@ declare class Timer {
692
695
  * @default
693
696
  * @memberof Settings */
694
697
  declare let canvasMaxSize: Vector2;
695
- /** Fixed size of the canvas, if enabled cavnvas size never changes
698
+ /** Fixed size of the canvas, if enabled canvas size never changes
699
+ * - you may also need to set mainCanvasSize if using screen space coords in startup
696
700
  * @type {Vector2}
697
701
  * @default
698
702
  * @memberof Settings */
@@ -719,6 +723,10 @@ declare let tileFixBleedScale: number;
719
723
  * @default
720
724
  * @memberof Settings */
721
725
  declare let objectDefaultSize: Vector2;
726
+ /** Enable physics solver for collisions between objects
727
+ * @default
728
+ * @memberof Settings */
729
+ declare let enablePhysicsSolver: number;
722
730
  /** Default object mass for collison calcuations (how heavy objects are)
723
731
  * @default
724
732
  * @memberof Settings */
@@ -867,7 +875,7 @@ declare class EngineObject {
867
875
  /** Create an engine object and adds it to the list of objects
868
876
  * @param {Vector2} [position=new Vector2()] - World space position of the object
869
877
  * @param {Vector2} [size=objectDefaultSize] - World space size of the object
870
- * @param {Number} [tileIndex=-1] - Tile to use to render object, untextured if -1
878
+ * @param {Number} [tileIndex=-1] - Tile to use to render object (-1 is untextured)
871
879
  * @param {Vector2} [tileSize=tileSizeDefault] - Size of tile in source pixels
872
880
  * @param {Number} [angle=0] - Angle the object is rotated by
873
881
  * @param {Color} [color] - Color to apply to tile when rendered
@@ -878,7 +886,7 @@ declare class EngineObject {
878
886
  pos: Vector2;
879
887
  /** @property {Vector2} - World space width and height of the object */
880
888
  size: Vector2;
881
- /** @property {Number} - Tile to use to render object, untextured if -1 */
889
+ /** @property {Number} - Tile to use to render object (-1 is untextured) */
882
890
  tileIndex: number;
883
891
  /** @property {Vector2} - Size of tile in source pixels */
884
892
  tileSize: Vector2;
@@ -886,7 +894,7 @@ declare class EngineObject {
886
894
  angle: number;
887
895
  /** @property {Color} - Color to apply when rendered */
888
896
  color: Color;
889
- /** @property {Number} [mass=objectDefaultMass] - How heavy the object is */
897
+ /** @property {Number} [mass=objectDefaultMass] - How heavy the object is, static if 0 */
890
898
  mass: number;
891
899
  /** @property {Number} [damping=objectDefaultDamping] - How much to slow down velocity each frame (0-1) */
892
900
  damping: number;
@@ -984,11 +992,13 @@ declare let overlayContext: CanvasRenderingContext2D;
984
992
  * @memberof Draw */
985
993
  declare let mainCanvasSize: Vector2;
986
994
  /** Convert from screen to world space coordinates
995
+ * - if calling outside of render, you may need to manually set mainCanvasSize
987
996
  * @param {Vector2} screenPos
988
997
  * @return {Vector2}
989
998
  * @memberof Draw */
990
999
  declare function screenToWorld(screenPos: Vector2): Vector2;
991
1000
  /** Convert from world to screen space coordinates
1001
+ * - if calling outside of render, you may need to manually set mainCanvasSize
992
1002
  * @param {Vector2} worldPos
993
1003
  * @return {Vector2}
994
1004
  * @memberof Draw */
@@ -1092,6 +1102,9 @@ declare let mouseWheel: number;
1092
1102
  /** Returns true if user is using gamepad (has more recently pressed a gamepad button)
1093
1103
  * @memberof Input */
1094
1104
  declare let isUsingGamepad: number;
1105
+ /** Prevents input continuing to the default browser handling (false by default)
1106
+ * @memberof Input */
1107
+ declare let preventDefaultInput: number;
1095
1108
  /** Returns true if gamepad button is down
1096
1109
  * @param {Number} button
1097
1110
  * @param {Number} [gamepad=0]
@@ -1428,7 +1441,7 @@ declare class ParticleEmitter extends EngineObject {
1428
1441
  randomColorLinear: boolean;
1429
1442
  /** @property {Number} - How long particles live */
1430
1443
  particleTime: number;
1431
- /** @property {Number} - How big are particles at start */
1444
+ /** @property {Number} - How big are particles at start */
1432
1445
  sizeStart: number;
1433
1446
  /** @property {Number} - How big are particles at end */
1434
1447
  sizeEnd: number;
@@ -1617,7 +1630,7 @@ declare const gl_VERTEX_BYTE_STRIDE: number;
1617
1630
  /** Name of engine */
1618
1631
  declare const engineName: "LittleJS";
1619
1632
  /** Version of engine */
1620
- declare const engineVersion: "1.3.0";
1633
+ declare const engineVersion: "1.3.8";
1621
1634
  /** Frames per second to update objects
1622
1635
  * @default */
1623
1636
  declare const frameRate: 60;
@@ -5,6 +5,6 @@
5
5
  <link rel=icon type=image/png href=../../favicon.png>
6
6
  </head><body>
7
7
 
8
- <script src=../../engine/engine.all.js?104></script>
9
- <script src=game.js?104></script>
10
- <script src=gameObjects.js?104></script>
8
+ <script src=../../engine/engine.all.js?111></script>
9
+ <script src=game.js?111></script>
10
+ <script src=gameObjects.js?111></script>