littlejsengine 1.2.9 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/build.bat +6 -6
- package/buildSetup.bat +10 -0
- package/engine/engine.all.js +78 -39
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.release.js +77 -38
- package/engine/engine.js +1 -1
- package/engine/engineAudio.js +5 -7
- package/engine/engineBuild.bat +3 -4
- package/engine/engineDebug.js +1 -1
- package/engine/engineDraw.js +5 -4
- package/engine/engineInput.js +5 -1
- package/engine/engineMedals.js +1 -1
- package/engine/engineObject.js +22 -19
- package/engine/engineParticles.js +1 -1
- package/engine/engineSettings.js +5 -0
- package/engine/engineUtilities.js +31 -3
- package/engine/engineWebGL.js +1 -1
- package/engine/index.d.ts +18 -6
- package/examples/breakout/index.html +3 -3
- package/examples/particles/index.html +151 -103
- package/examples/platformer/index.html +5 -5
- package/examples/puzzle/game.js +3 -1
- package/examples/puzzle/index.html +2 -2
- package/examples/stress/index.html +1 -1
- package/game.js +10 -21
- package/index.html +13 -13
- package/package.json +1 -8
|
@@ -288,7 +288,7 @@ class Vector2
|
|
|
288
288
|
/** Returns a new vector in same direction as this one with the length passed in
|
|
289
289
|
* @param {Number} [length=1]
|
|
290
290
|
* @return {Vector2} */
|
|
291
|
-
normalize(length=1) { const l = this.length(); return l ? this.scale(length/l) : new Vector2(length); }
|
|
291
|
+
normalize(length=1) { const l = this.length(); return l ? this.scale(length/l) : new Vector2(0, length); }
|
|
292
292
|
|
|
293
293
|
/** Returns a new vector clamped to length passed in
|
|
294
294
|
* @param {Number} [length=1]
|
|
@@ -333,7 +333,7 @@ class Vector2
|
|
|
333
333
|
|
|
334
334
|
/** Returns the area this vector covers as a rectangle
|
|
335
335
|
* @return {Number} */
|
|
336
|
-
area() { return this.x * this.y; }
|
|
336
|
+
area() { return abs(this.x * this.y); }
|
|
337
337
|
|
|
338
338
|
/** Returns a new vector that is p percent between this and the vector passed in
|
|
339
339
|
* @param {Vector2} vector
|
|
@@ -481,6 +481,34 @@ class Color
|
|
|
481
481
|
return '#' + toHex(this.r) + toHex(this.g) + toHex(this.b);
|
|
482
482
|
}
|
|
483
483
|
|
|
484
|
+
/** Returns this color expressed in hsla format
|
|
485
|
+
* @return {Array} */
|
|
486
|
+
getHSLA()
|
|
487
|
+
{
|
|
488
|
+
const r = this.r;
|
|
489
|
+
const g = this.g;
|
|
490
|
+
const b = this.b;
|
|
491
|
+
const a = this.a;
|
|
492
|
+
const max = Math.max(r, g, b);
|
|
493
|
+
const min = Math.min(r, g, b);
|
|
494
|
+
const l = (max + min) / 2;
|
|
495
|
+
|
|
496
|
+
let h = 0, s = 0;
|
|
497
|
+
if (max != min)
|
|
498
|
+
{
|
|
499
|
+
let d = max - min;
|
|
500
|
+
s = l > .5 ? d / (2 - max - min) : d / (max + min);
|
|
501
|
+
if (r == max)
|
|
502
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
503
|
+
else if (g == max)
|
|
504
|
+
h = (b - r) / d + 2;
|
|
505
|
+
else if (b == max)
|
|
506
|
+
h = (r - g) / d + 4;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return [h / 6, s, l, a];
|
|
510
|
+
}
|
|
511
|
+
|
|
484
512
|
/** Set this color from a hex code
|
|
485
513
|
* @param {String} hex - html hex code
|
|
486
514
|
* @return {Color} */
|
|
@@ -542,7 +570,7 @@ class Timer
|
|
|
542
570
|
|
|
543
571
|
/** Returns this timer expressed as a string
|
|
544
572
|
* @return {String} */
|
|
545
|
-
toString() { return this.unset() ? 'unset' : Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ); }
|
|
573
|
+
toString() { if (debug) { return this.unset() ? 'unset' : Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ); } }
|
|
546
574
|
}
|
|
547
575
|
/**
|
|
548
576
|
* LittleJS Engine Settings
|
|
@@ -599,6 +627,11 @@ let tileFixBleedScale = .3;
|
|
|
599
627
|
* @memberof Settings */
|
|
600
628
|
let objectDefaultSize = vec2(1);
|
|
601
629
|
|
|
630
|
+
/** Enable physics solver for collisions between objects
|
|
631
|
+
* @default
|
|
632
|
+
* @memberof Settings */
|
|
633
|
+
let enablePhysicsSolver = 1;
|
|
634
|
+
|
|
602
635
|
/** Default object mass for collison calcuations (how heavy objects are)
|
|
603
636
|
* @default
|
|
604
637
|
* @memberof Settings */
|
|
@@ -785,7 +818,7 @@ let medalDisplayIconSize = 50;
|
|
|
785
818
|
const engineName = 'LittleJS';
|
|
786
819
|
|
|
787
820
|
/** Version of engine */
|
|
788
|
-
const engineVersion = '1.
|
|
821
|
+
const engineVersion = '1.3.5';
|
|
789
822
|
|
|
790
823
|
/** Frames per second to update objects
|
|
791
824
|
* @default */
|
|
@@ -1081,7 +1114,7 @@ class EngineObject
|
|
|
1081
1114
|
/** Create an engine object and adds it to the list of objects
|
|
1082
1115
|
* @param {Vector2} [position=new Vector2()] - World space position of the object
|
|
1083
1116
|
* @param {Vector2} [size=objectDefaultSize] - World space size of the object
|
|
1084
|
-
* @param {Number} [tileIndex=-1] - Tile to use to render object
|
|
1117
|
+
* @param {Number} [tileIndex=-1] - Tile to use to render object (-1 is untextured)
|
|
1085
1118
|
* @param {Vector2} [tileSize=tileSizeDefault] - Size of tile in source pixels
|
|
1086
1119
|
* @param {Number} [angle=0] - Angle the object is rotated by
|
|
1087
1120
|
* @param {Color} [color] - Color to apply to tile when rendered
|
|
@@ -1098,7 +1131,7 @@ class EngineObject
|
|
|
1098
1131
|
this.size = size;
|
|
1099
1132
|
/** @property {Vector2} - Size of object used for drawing, uses size if not set */
|
|
1100
1133
|
this.drawSize;
|
|
1101
|
-
/** @property {Number} - Tile to use to render object
|
|
1134
|
+
/** @property {Number} - Tile to use to render object (-1 is untextured) */
|
|
1102
1135
|
this.tileIndex = tileIndex;
|
|
1103
1136
|
/** @property {Vector2} - Size of tile in source pixels */
|
|
1104
1137
|
this.tileSize = tileSize;
|
|
@@ -1110,7 +1143,7 @@ class EngineObject
|
|
|
1110
1143
|
this.additiveColor;
|
|
1111
1144
|
|
|
1112
1145
|
// set object defaults
|
|
1113
|
-
/** @property {Number} [mass=objectDefaultMass] - How heavy the object is */
|
|
1146
|
+
/** @property {Number} [mass=objectDefaultMass] - How heavy the object is, static if 0 */
|
|
1114
1147
|
this.mass = objectDefaultMass;
|
|
1115
1148
|
/** @property {Number} [damping=objectDefaultDamping] - How much to slow down velocity each frame (0-1) */
|
|
1116
1149
|
this.damping = objectDefaultDamping;
|
|
@@ -1164,7 +1197,7 @@ class EngineObject
|
|
|
1164
1197
|
ASSERT(this.angleDamping >= 0 && this.angleDamping <= 1);
|
|
1165
1198
|
ASSERT(this.damping >= 0 && this.damping <= 1);
|
|
1166
1199
|
|
|
1167
|
-
if (!this.mass) // do not update collision for fixed objects
|
|
1200
|
+
if (!enablePhysicsSolver || !this.mass) // do not update collision for fixed objects
|
|
1168
1201
|
return;
|
|
1169
1202
|
|
|
1170
1203
|
const wasMovingDown = this.velocity.y < 0;
|
|
@@ -1174,7 +1207,7 @@ class EngineObject
|
|
|
1174
1207
|
const groundSpeed = this.groundObject.velocity ? this.groundObject.velocity.x : 0;
|
|
1175
1208
|
this.velocity.x = groundSpeed + (this.velocity.x - groundSpeed) * this.friction;
|
|
1176
1209
|
this.groundObject = 0;
|
|
1177
|
-
//debugPhysics && debugPoint(this.pos.subtract(vec2(0,this.size.y/2)), '#0f0');
|
|
1210
|
+
//debugOverlay && debugPhysics && debugPoint(this.pos.subtract(vec2(0,this.size.y/2)), '#0f0');
|
|
1178
1211
|
}
|
|
1179
1212
|
|
|
1180
1213
|
if (this.collideSolidObjects)
|
|
@@ -1206,7 +1239,7 @@ class EngineObject
|
|
|
1206
1239
|
if (o.mass) // push away if not fixed
|
|
1207
1240
|
o.velocity = o.velocity.subtract(velocity);
|
|
1208
1241
|
|
|
1209
|
-
debugPhysics && debugAABB(this.pos, this.size, o.pos, o.size, '#f00');
|
|
1242
|
+
debugOverlay && debugPhysics && debugAABB(this.pos, this.size, o.pos, o.size, '#f00');
|
|
1210
1243
|
continue;
|
|
1211
1244
|
}
|
|
1212
1245
|
|
|
@@ -1269,7 +1302,7 @@ class EngineObject
|
|
|
1269
1302
|
else // bounce if other object is fixed
|
|
1270
1303
|
this.velocity.x *= -this.elasticity;
|
|
1271
1304
|
}
|
|
1272
|
-
debugPhysics && debugAABB(this.pos, this.size, o.pos, o.size, '#f0f');
|
|
1305
|
+
debugOverlay && debugPhysics && debugAABB(this.pos, this.size, o.pos, o.size, '#f0f');
|
|
1273
1306
|
}
|
|
1274
1307
|
}
|
|
1275
1308
|
if (this.collideTiles)
|
|
@@ -1402,18 +1435,21 @@ class EngineObject
|
|
|
1402
1435
|
|
|
1403
1436
|
toString()
|
|
1404
1437
|
{
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
text
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1438
|
+
if (debug)
|
|
1439
|
+
{
|
|
1440
|
+
let text = 'type = ' + this.constructor.name;
|
|
1441
|
+
if (this.pos.x || this.pos.y)
|
|
1442
|
+
text += '\npos = ' + this.pos;
|
|
1443
|
+
if (this.velocity.x || this.velocity.y)
|
|
1444
|
+
text += '\nvelocity = ' + this.velocity;
|
|
1445
|
+
if (this.size.x || this.size.y)
|
|
1446
|
+
text += '\nsize = ' + this.size;
|
|
1447
|
+
if (this.angle)
|
|
1448
|
+
text += '\nangle = ' + this.angle.toFixed(3);
|
|
1449
|
+
if (this.color)
|
|
1450
|
+
text += '\ncolor = ' + this.color;
|
|
1451
|
+
return text;
|
|
1452
|
+
}
|
|
1417
1453
|
}
|
|
1418
1454
|
}
|
|
1419
1455
|
/**
|
|
@@ -1583,7 +1619,7 @@ function drawTileScreenSpace(pos, size=vec2(1), tileIndex, tileSize, color, angl
|
|
|
1583
1619
|
* @memberof Draw */
|
|
1584
1620
|
function drawRectScreenSpace(pos, size, color, angle, useWebGL)
|
|
1585
1621
|
{
|
|
1586
|
-
|
|
1622
|
+
drawTileScreenSpace(pos, size, -1, tileSizeDefault, color, angle, 0, 0, useWebGL);
|
|
1587
1623
|
}
|
|
1588
1624
|
|
|
1589
1625
|
/** Draw colored line between two points
|
|
@@ -1646,14 +1682,15 @@ function setBlendMode(additive, useWebGL=glEnable)
|
|
|
1646
1682
|
function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), textAlign='center', font=fontDefault)
|
|
1647
1683
|
{
|
|
1648
1684
|
overlayContext.fillStyle = color;
|
|
1649
|
-
overlayContext.lineWidth = lineWidth
|
|
1685
|
+
overlayContext.lineWidth = lineWidth;
|
|
1650
1686
|
overlayContext.strokeStyle = lineColor;
|
|
1651
1687
|
overlayContext.textAlign = textAlign;
|
|
1652
1688
|
overlayContext.font = size + 'px '+ font;
|
|
1653
1689
|
overlayContext.textBaseline = 'middle';
|
|
1690
|
+
overlayContext.lineJoin = 'round';
|
|
1654
1691
|
|
|
1655
1692
|
pos = pos.copy();
|
|
1656
|
-
text.split('\n').forEach(line=>
|
|
1693
|
+
(text+'').split('\n').forEach(line=>
|
|
1657
1694
|
{
|
|
1658
1695
|
lineWidth && overlayContext.strokeText(line, pos.x, pos.y);
|
|
1659
1696
|
overlayContext.fillText(line, pos.x, pos.y);
|
|
@@ -1673,7 +1710,7 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
|
|
|
1673
1710
|
* @memberof Draw */
|
|
1674
1711
|
function drawText(text, pos, size=1, color, lineWidth, lineColor, textAlign, font)
|
|
1675
1712
|
{
|
|
1676
|
-
drawTextScreen(text, worldToScreen(pos), size*cameraScale, color, lineWidth, lineColor, textAlign, font);
|
|
1713
|
+
drawTextScreen(text, worldToScreen(pos), size*cameraScale, color, lineWidth*cameraScale, lineColor, textAlign, font);
|
|
1677
1714
|
}
|
|
1678
1715
|
|
|
1679
1716
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -1867,6 +1904,10 @@ let mouseWheel = 0;
|
|
|
1867
1904
|
* @memberof Input */
|
|
1868
1905
|
let isUsingGamepad = 0;
|
|
1869
1906
|
|
|
1907
|
+
/** Prevents input continuing to the default browser handling (false by default)
|
|
1908
|
+
* @memberof Input */
|
|
1909
|
+
let preventDefaultInput = 0;
|
|
1910
|
+
|
|
1870
1911
|
/** Returns true if gamepad button is down
|
|
1871
1912
|
* @param {Number} button
|
|
1872
1913
|
* @param {Number} [gamepad=0]
|
|
@@ -1930,7 +1971,7 @@ onkeydown = (e)=>
|
|
|
1930
1971
|
{
|
|
1931
1972
|
if (debug && e.target != document.body) return;
|
|
1932
1973
|
e.repeat || (inputData[isUsingGamepad = 0][remapKeyCode(e.keyCode)] = 3);
|
|
1933
|
-
|
|
1974
|
+
preventDefaultInput && e.preventDefault();
|
|
1934
1975
|
}
|
|
1935
1976
|
onkeyup = (e)=>
|
|
1936
1977
|
{
|
|
@@ -2494,8 +2535,7 @@ function zzfxG
|
|
|
2494
2535
|
)
|
|
2495
2536
|
{
|
|
2496
2537
|
// init parameters
|
|
2497
|
-
let PI2 = PI*2,
|
|
2498
|
-
startSlide = slide *= 500 * PI2 / zzfxR / zzfxR, b=[],
|
|
2538
|
+
let PI2 = PI*2, startSlide = slide *= 500 * PI2 / zzfxR / zzfxR, b=[],
|
|
2499
2539
|
startFrequency = frequency *= (1 + randomness*rand(-1,1)) * PI2 / zzfxR,
|
|
2500
2540
|
t=0, tm=0, i=0, j=1, r=0, c=0, s=0, f, length;
|
|
2501
2541
|
|
|
@@ -2519,15 +2559,15 @@ function zzfxG
|
|
|
2519
2559
|
{
|
|
2520
2560
|
s = shape? shape>1? shape>2? shape>3? // wave shape
|
|
2521
2561
|
Math.sin((t%PI2)**3) : // 4 noise
|
|
2522
|
-
|
|
2562
|
+
max(min(Math.tan(t),1),-1): // 3 tan
|
|
2523
2563
|
1-(2*t/PI2%2+2)%2: // 2 saw
|
|
2524
|
-
1-4*abs(Math.round(t/PI2)-t/PI2):
|
|
2564
|
+
1-4*abs(Math.round(t/PI2)-t/PI2): // 1 triangle
|
|
2525
2565
|
Math.sin(t); // 0 sin
|
|
2526
2566
|
|
|
2527
2567
|
s = (repeatTime ?
|
|
2528
2568
|
1 - tremolo + tremolo*Math.sin(PI2*i/repeatTime) // tremolo
|
|
2529
2569
|
: 1) *
|
|
2530
|
-
sign(s)*(abs(s)**shapeCurve) *
|
|
2570
|
+
sign(s)*(abs(s)**shapeCurve) * // curve 0=square, 2=pointy
|
|
2531
2571
|
volume * soundVolume * ( // envelope
|
|
2532
2572
|
i < attack ? i/attack : // attack
|
|
2533
2573
|
i < attack + decay ? // decay
|
|
@@ -2588,7 +2628,6 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
|
2588
2628
|
let notFirstBeat;
|
|
2589
2629
|
let stop;
|
|
2590
2630
|
let instrument;
|
|
2591
|
-
let pitch;
|
|
2592
2631
|
let attenuation;
|
|
2593
2632
|
let outSampleOffset;
|
|
2594
2633
|
let isSequenceEnd;
|
|
@@ -2607,7 +2646,7 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
|
2607
2646
|
for (; hasMore; channelIndex++) {
|
|
2608
2647
|
|
|
2609
2648
|
// reset current values
|
|
2610
|
-
sampleBuffer = [hasMore = notFirstBeat =
|
|
2649
|
+
sampleBuffer = [hasMore = notFirstBeat = outSampleOffset = 0];
|
|
2611
2650
|
|
|
2612
2651
|
// for each pattern in sequence
|
|
2613
2652
|
sequence.forEach((patternIndex, sequenceIndex) => {
|
|
@@ -3132,7 +3171,7 @@ class ParticleEmitter extends EngineObject
|
|
|
3132
3171
|
// particle settings
|
|
3133
3172
|
/** @property {Number} - How long particles live */
|
|
3134
3173
|
this.particleTime = particleTime;
|
|
3135
|
-
/** @property {Number} -
|
|
3174
|
+
/** @property {Number} - How big are particles at start */
|
|
3136
3175
|
this.sizeStart = sizeStart;
|
|
3137
3176
|
/** @property {Number} - How big are particles at end */
|
|
3138
3177
|
this.sizeEnd = sizeEnd;
|
|
@@ -3495,7 +3534,7 @@ class Newgrounds
|
|
|
3495
3534
|
cipher && (this.cryptoJS = CryptoJS());
|
|
3496
3535
|
|
|
3497
3536
|
// get session id from url search params
|
|
3498
|
-
const url = new URL(
|
|
3537
|
+
const url = new URL(location.href);
|
|
3499
3538
|
this.session_id = url.searchParams.get('ngio_session_id') || 0;
|
|
3500
3539
|
|
|
3501
3540
|
if (this.session_id == 0)
|
|
@@ -3848,7 +3887,7 @@ function glFlush()
|
|
|
3848
3887
|
* @memberof WebGL */
|
|
3849
3888
|
function glCopyToContext(context, forceDraw)
|
|
3850
3889
|
{
|
|
3851
|
-
if (!glEnable || !glBatchCount) return;
|
|
3890
|
+
if ((!glEnable || !glBatchCount) && !forceDraw) return;
|
|
3852
3891
|
|
|
3853
3892
|
glFlush();
|
|
3854
3893
|
|
package/engine/engine.js
CHANGED
package/engine/engineAudio.js
CHANGED
|
@@ -289,8 +289,7 @@ function zzfxG
|
|
|
289
289
|
)
|
|
290
290
|
{
|
|
291
291
|
// init parameters
|
|
292
|
-
let PI2 = PI*2,
|
|
293
|
-
startSlide = slide *= 500 * PI2 / zzfxR / zzfxR, b=[],
|
|
292
|
+
let PI2 = PI*2, startSlide = slide *= 500 * PI2 / zzfxR / zzfxR, b=[],
|
|
294
293
|
startFrequency = frequency *= (1 + randomness*rand(-1,1)) * PI2 / zzfxR,
|
|
295
294
|
t=0, tm=0, i=0, j=1, r=0, c=0, s=0, f, length;
|
|
296
295
|
|
|
@@ -314,15 +313,15 @@ function zzfxG
|
|
|
314
313
|
{
|
|
315
314
|
s = shape? shape>1? shape>2? shape>3? // wave shape
|
|
316
315
|
Math.sin((t%PI2)**3) : // 4 noise
|
|
317
|
-
|
|
316
|
+
max(min(Math.tan(t),1),-1): // 3 tan
|
|
318
317
|
1-(2*t/PI2%2+2)%2: // 2 saw
|
|
319
|
-
1-4*abs(Math.round(t/PI2)-t/PI2):
|
|
318
|
+
1-4*abs(Math.round(t/PI2)-t/PI2): // 1 triangle
|
|
320
319
|
Math.sin(t); // 0 sin
|
|
321
320
|
|
|
322
321
|
s = (repeatTime ?
|
|
323
322
|
1 - tremolo + tremolo*Math.sin(PI2*i/repeatTime) // tremolo
|
|
324
323
|
: 1) *
|
|
325
|
-
sign(s)*(abs(s)**shapeCurve) *
|
|
324
|
+
sign(s)*(abs(s)**shapeCurve) * // curve 0=square, 2=pointy
|
|
326
325
|
volume * soundVolume * ( // envelope
|
|
327
326
|
i < attack ? i/attack : // attack
|
|
328
327
|
i < attack + decay ? // decay
|
|
@@ -383,7 +382,6 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
|
383
382
|
let notFirstBeat;
|
|
384
383
|
let stop;
|
|
385
384
|
let instrument;
|
|
386
|
-
let pitch;
|
|
387
385
|
let attenuation;
|
|
388
386
|
let outSampleOffset;
|
|
389
387
|
let isSequenceEnd;
|
|
@@ -402,7 +400,7 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
|
402
400
|
for (; hasMore; channelIndex++) {
|
|
403
401
|
|
|
404
402
|
// reset current values
|
|
405
|
-
sampleBuffer = [hasMore = notFirstBeat =
|
|
403
|
+
sampleBuffer = [hasMore = notFirstBeat = outSampleOffset = 0];
|
|
406
404
|
|
|
407
405
|
// for each pattern in sequence
|
|
408
406
|
sequence.forEach((patternIndex, sequenceIndex) => {
|
package/engine/engineBuild.bat
CHANGED
|
@@ -79,7 +79,7 @@ copy engine.all.release.js %OUTPUT_FILENAME%
|
|
|
79
79
|
|
|
80
80
|
rem check code with closure
|
|
81
81
|
move %OUTPUT_FILENAME% %OUTPUT_FILENAME%.temp
|
|
82
|
-
call google-closure-compiler --js
|
|
82
|
+
call npx google-closure-compiler --js=%OUTPUT_FILENAME%.temp --js_output_file=%OUTPUT_FILENAME% --language_out=ECMASCRIPT_2019 --warning_level=VERBOSE --jscomp_off=*
|
|
83
83
|
del %OUTPUT_FILENAME%.temp
|
|
84
84
|
if %ERRORLEVEL% NEQ 0 (
|
|
85
85
|
pause
|
|
@@ -87,15 +87,14 @@ if %ERRORLEVEL% NEQ 0 (
|
|
|
87
87
|
)
|
|
88
88
|
|
|
89
89
|
rem lightly minify with uglify
|
|
90
|
-
call uglifyjs -o %OUTPUT_FILENAME% -- %OUTPUT_FILENAME%
|
|
90
|
+
call npx uglifyjs -o %OUTPUT_FILENAME% -- %OUTPUT_FILENAME%
|
|
91
91
|
if %ERRORLEVEL% NEQ 0 (
|
|
92
92
|
pause
|
|
93
93
|
exit /b %ERRORLEVEL%
|
|
94
94
|
)
|
|
95
95
|
|
|
96
96
|
rem --- BUILD TYPESCRIPT DEFINITIONS ---
|
|
97
|
-
|
|
98
|
-
call tsc engine.all.js --declaration --allowJs --emitDeclarationOnly --outFile index.d.ts
|
|
97
|
+
call npx tsc engine.all.js --declaration --allowJs --emitDeclarationOnly --outFile index.d.ts
|
|
99
98
|
if %ERRORLEVEL% NEQ 0 (
|
|
100
99
|
pause
|
|
101
100
|
exit /b %ERRORLEVEL%
|
package/engine/engineDebug.js
CHANGED
|
@@ -30,7 +30,7 @@ const enableAsserts = 1;
|
|
|
30
30
|
* @memberof Debug */
|
|
31
31
|
const debugPointSize = .5;
|
|
32
32
|
|
|
33
|
-
/** True if watermark with FPS should be down
|
|
33
|
+
/** True if watermark with FPS should be down, false in release builds
|
|
34
34
|
* @default
|
|
35
35
|
* @memberof Debug */
|
|
36
36
|
let showWatermark = 1;
|
package/engine/engineDraw.js
CHANGED
|
@@ -165,7 +165,7 @@ function drawTileScreenSpace(pos, size=vec2(1), tileIndex, tileSize, color, angl
|
|
|
165
165
|
* @memberof Draw */
|
|
166
166
|
function drawRectScreenSpace(pos, size, color, angle, useWebGL)
|
|
167
167
|
{
|
|
168
|
-
|
|
168
|
+
drawTileScreenSpace(pos, size, -1, tileSizeDefault, color, angle, 0, 0, useWebGL);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
/** Draw colored line between two points
|
|
@@ -228,14 +228,15 @@ function setBlendMode(additive, useWebGL=glEnable)
|
|
|
228
228
|
function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), textAlign='center', font=fontDefault)
|
|
229
229
|
{
|
|
230
230
|
overlayContext.fillStyle = color;
|
|
231
|
-
overlayContext.lineWidth = lineWidth
|
|
231
|
+
overlayContext.lineWidth = lineWidth;
|
|
232
232
|
overlayContext.strokeStyle = lineColor;
|
|
233
233
|
overlayContext.textAlign = textAlign;
|
|
234
234
|
overlayContext.font = size + 'px '+ font;
|
|
235
235
|
overlayContext.textBaseline = 'middle';
|
|
236
|
+
overlayContext.lineJoin = 'round';
|
|
236
237
|
|
|
237
238
|
pos = pos.copy();
|
|
238
|
-
text.split('\n').forEach(line=>
|
|
239
|
+
(text+'').split('\n').forEach(line=>
|
|
239
240
|
{
|
|
240
241
|
lineWidth && overlayContext.strokeText(line, pos.x, pos.y);
|
|
241
242
|
overlayContext.fillText(line, pos.x, pos.y);
|
|
@@ -255,7 +256,7 @@ function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineCol
|
|
|
255
256
|
* @memberof Draw */
|
|
256
257
|
function drawText(text, pos, size=1, color, lineWidth, lineColor, textAlign, font)
|
|
257
258
|
{
|
|
258
|
-
drawTextScreen(text, worldToScreen(pos), size*cameraScale, color, lineWidth, lineColor, textAlign, font);
|
|
259
|
+
drawTextScreen(text, worldToScreen(pos), size*cameraScale, color, lineWidth*cameraScale, lineColor, textAlign, font);
|
|
259
260
|
}
|
|
260
261
|
|
|
261
262
|
///////////////////////////////////////////////////////////////////////////////
|
package/engine/engineInput.js
CHANGED
|
@@ -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
|
-
|
|
140
|
+
preventDefaultInput && e.preventDefault();
|
|
137
141
|
}
|
|
138
142
|
onkeyup = (e)=>
|
|
139
143
|
{
|
package/engine/engineMedals.js
CHANGED
|
@@ -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(
|
|
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)
|
package/engine/engineObject.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
-
|
|
359
|
-
|
|
360
|
-
text
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
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} -
|
|
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;
|
package/engine/engineSettings.js
CHANGED
|
@@ -53,6 +53,11 @@ let tileFixBleedScale = .3;
|
|
|
53
53
|
* @memberof Settings */
|
|
54
54
|
let objectDefaultSize = vec2(1);
|
|
55
55
|
|
|
56
|
+
/** Enable physics solver for collisions between objects
|
|
57
|
+
* @default
|
|
58
|
+
* @memberof Settings */
|
|
59
|
+
let enablePhysicsSolver = 1;
|
|
60
|
+
|
|
56
61
|
/** Default object mass for collison calcuations (how heavy objects are)
|
|
57
62
|
* @default
|
|
58
63
|
* @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
|
|
@@ -448,6 +448,34 @@ class Color
|
|
|
448
448
|
return '#' + toHex(this.r) + toHex(this.g) + toHex(this.b);
|
|
449
449
|
}
|
|
450
450
|
|
|
451
|
+
/** Returns this color expressed in hsla format
|
|
452
|
+
* @return {Array} */
|
|
453
|
+
getHSLA()
|
|
454
|
+
{
|
|
455
|
+
const r = this.r;
|
|
456
|
+
const g = this.g;
|
|
457
|
+
const b = this.b;
|
|
458
|
+
const a = this.a;
|
|
459
|
+
const max = Math.max(r, g, b);
|
|
460
|
+
const min = Math.min(r, g, b);
|
|
461
|
+
const l = (max + min) / 2;
|
|
462
|
+
|
|
463
|
+
let h = 0, s = 0;
|
|
464
|
+
if (max != min)
|
|
465
|
+
{
|
|
466
|
+
let d = max - min;
|
|
467
|
+
s = l > .5 ? d / (2 - max - min) : d / (max + min);
|
|
468
|
+
if (r == max)
|
|
469
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
470
|
+
else if (g == max)
|
|
471
|
+
h = (b - r) / d + 2;
|
|
472
|
+
else if (b == max)
|
|
473
|
+
h = (r - g) / d + 4;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
return [h / 6, s, l, a];
|
|
477
|
+
}
|
|
478
|
+
|
|
451
479
|
/** Set this color from a hex code
|
|
452
480
|
* @param {String} hex - html hex code
|
|
453
481
|
* @return {Color} */
|
|
@@ -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
|
}
|
package/engine/engineWebGL.js
CHANGED