littlejsengine 1.16.1 → 1.16.2
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/dist/littlejs.d.ts +91 -78
- package/dist/littlejs.esm.js +287 -272
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +279 -266
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +184 -175
- package/examples/box2d/gameObjects.js +5 -5
- package/examples/electron/index.html +2 -2
- package/examples/logo.png +0 -0
- package/examples/logo2.png +0 -0
- package/examples/platformer/gameEffects.js +1 -1
- package/examples/shorts/base.html +2 -1
- package/examples/starter/index.html +3 -2
- package/package.json +1 -1
- package/plugins/uiSystem.js +1 -1
- package/reference.md +5 -5
- package/src/engine.js +16 -28
- package/src/engineAudio.js +2 -4
- package/src/engineBuild.js +1 -0
- package/src/engineDebug.js +96 -94
- package/src/engineDraw.js +8 -28
- package/src/engineExport.js +8 -6
- package/src/engineInput.js +3 -6
- package/src/engineMath.js +1201 -0
- package/src/engineMedals.js +4 -4
- package/src/engineObject.js +1 -2
- package/src/engineRelease.js +1 -3
- package/src/engineSettings.js +2 -2
- package/src/engineTileLayer.js +7 -9
- package/src/engineUtilities.js +34 -1179
- package/src/engineWebGL.js +7 -10
package/dist/littlejs.release.js
CHANGED
|
@@ -33,7 +33,7 @@ const engineName = 'LittleJS';
|
|
|
33
33
|
* @type {string}
|
|
34
34
|
* @default
|
|
35
35
|
* @memberof Engine */
|
|
36
|
-
const engineVersion = '1.16.
|
|
36
|
+
const engineVersion = '1.16.2';
|
|
37
37
|
|
|
38
38
|
/** Frames per second to update
|
|
39
39
|
* @type {number}
|
|
@@ -272,33 +272,20 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
272
272
|
if (!wasUpdated)
|
|
273
273
|
updateCanvas();
|
|
274
274
|
|
|
275
|
-
// render
|
|
275
|
+
// render the game and objects
|
|
276
276
|
enginePreRender();
|
|
277
277
|
gameRender();
|
|
278
278
|
engineObjects.sort((a,b)=> a.renderOrder - b.renderOrder);
|
|
279
279
|
for (const o of engineObjects)
|
|
280
280
|
o.destroyed || o.render();
|
|
281
|
+
|
|
282
|
+
// post rendering
|
|
281
283
|
gameRenderPost();
|
|
282
284
|
pluginList.forEach(plugin=>plugin.render?.());
|
|
283
285
|
inputRender();
|
|
284
286
|
debugRender();
|
|
285
287
|
glFlush();
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
if (debugWatermark && !debugVideoCaptureIsActive())
|
|
289
|
-
{
|
|
290
|
-
// update fps display
|
|
291
|
-
mainContext.textAlign = 'right';
|
|
292
|
-
mainContext.textBaseline = 'top';
|
|
293
|
-
mainContext.font = '1em monospace';
|
|
294
|
-
mainContext.fillStyle = '#000';
|
|
295
|
-
const text = engineName + ' ' + 'v' + engineVersion + ' / '
|
|
296
|
-
+ drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
|
|
297
|
-
+ (glEnable ? ' GL' : ' 2D') ;
|
|
298
|
-
mainContext.fillText(text, mainCanvas.width-3, 3);
|
|
299
|
-
mainContext.fillStyle = '#fff';
|
|
300
|
-
mainContext.fillText(text, mainCanvas.width-2, 2);
|
|
301
|
-
}
|
|
288
|
+
debugRenderPost();
|
|
302
289
|
drawCount = 0;
|
|
303
290
|
}
|
|
304
291
|
}
|
|
@@ -364,15 +351,9 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
364
351
|
mainContext.lineJoin = 'round';
|
|
365
352
|
mainContext.lineCap = 'round';
|
|
366
353
|
}
|
|
367
|
-
|
|
368
|
-
//
|
|
369
|
-
|
|
370
|
-
{
|
|
371
|
-
await gameInit();
|
|
372
|
-
engineUpdate();
|
|
373
|
-
}
|
|
374
|
-
if (headlessMode)
|
|
375
|
-
return startEngine();
|
|
354
|
+
|
|
355
|
+
// skip setup if headless
|
|
356
|
+
if (headlessMode) return startEngine();
|
|
376
357
|
|
|
377
358
|
// setup webgl
|
|
378
359
|
glInit(rootElement);
|
|
@@ -387,7 +368,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
387
368
|
'touch-action:none;' + // prevent mobile pinch to resize
|
|
388
369
|
'-webkit-touch-callout:none'; // compatibility for ios
|
|
389
370
|
rootElement.style.cssText = styleRoot;
|
|
390
|
-
|
|
371
|
+
mainCanvas = rootElement.appendChild(document.createElement('canvas'));
|
|
391
372
|
drawContext = mainContext = mainCanvas.getContext('2d');
|
|
392
373
|
|
|
393
374
|
// init stuff and start engine
|
|
@@ -462,6 +443,13 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
462
443
|
await Promise.all(promises);
|
|
463
444
|
return startEngine();
|
|
464
445
|
|
|
446
|
+
async function startEngine()
|
|
447
|
+
{
|
|
448
|
+
// wait for gameInit to load
|
|
449
|
+
await gameInit();
|
|
450
|
+
engineUpdate();
|
|
451
|
+
}
|
|
452
|
+
|
|
465
453
|
///////////////////////////////////////////////////////////////////////////
|
|
466
454
|
// LittleJS Splash Screen
|
|
467
455
|
function drawEngineSplashScreen(t)
|
|
@@ -762,6 +750,7 @@ function LOG (){}
|
|
|
762
750
|
function debugInit (){}
|
|
763
751
|
function debugUpdate (){}
|
|
764
752
|
function debugRender (){}
|
|
753
|
+
function debugRenderPost (){}
|
|
765
754
|
function debugRect (){}
|
|
766
755
|
function debugPoly (){}
|
|
767
756
|
function debugCircle (){}
|
|
@@ -771,9 +760,6 @@ function debugOverlap (){}
|
|
|
771
760
|
function debugText (){}
|
|
772
761
|
function debugClear (){}
|
|
773
762
|
function debugScreenshot (){}
|
|
774
|
-
function debugSaveCanvas (){}
|
|
775
|
-
function debugSaveText (){}
|
|
776
|
-
function debugSaveDataURL(){}
|
|
777
763
|
function debugShowErrors(){}
|
|
778
764
|
function debugVideoCaptureIsActive(){ return false; }
|
|
779
765
|
function debugVideoCaptureStart (){}
|
|
@@ -787,99 +773,99 @@ function debugProtectConstant(o){ return o; }
|
|
|
787
773
|
* - Color - holds a rgba color with some math functions
|
|
788
774
|
* - Timer - tracks time automatically
|
|
789
775
|
* - RandomGenerator - seeded random number generator
|
|
790
|
-
* @namespace
|
|
776
|
+
* @namespace Math
|
|
791
777
|
*/
|
|
792
778
|
|
|
793
779
|
/** The value of PI
|
|
794
780
|
* @type {number}
|
|
795
781
|
* @default Math.PI
|
|
796
|
-
* @memberof
|
|
782
|
+
* @memberof Math */
|
|
797
783
|
const PI = Math.PI;
|
|
798
784
|
|
|
799
785
|
/** Returns absolute value of value passed in
|
|
800
786
|
* @param {number} value
|
|
801
787
|
* @return {number}
|
|
802
|
-
* @memberof
|
|
788
|
+
* @memberof Math */
|
|
803
789
|
const abs = Math.abs;
|
|
804
790
|
|
|
805
791
|
/** Returns floored value of value passed in
|
|
806
792
|
* @param {number} value
|
|
807
793
|
* @return {number}
|
|
808
|
-
* @memberof
|
|
794
|
+
* @memberof Math */
|
|
809
795
|
const floor = Math.floor;
|
|
810
796
|
|
|
811
797
|
/** Returns ceiled value of value passed in
|
|
812
798
|
* @param {number} value
|
|
813
799
|
* @return {number}
|
|
814
|
-
* @memberof
|
|
800
|
+
* @memberof Math */
|
|
815
801
|
const ceil = Math.ceil;
|
|
816
802
|
|
|
817
803
|
/** Returns rounded value passed in
|
|
818
804
|
* @param {number} value
|
|
819
805
|
* @return {number}
|
|
820
|
-
* @memberof
|
|
806
|
+
* @memberof Math */
|
|
821
807
|
const round = Math.round;
|
|
822
808
|
|
|
823
809
|
/** Returns lowest value passed in
|
|
824
810
|
* @param {...number} values
|
|
825
811
|
* @return {number}
|
|
826
|
-
* @memberof
|
|
812
|
+
* @memberof Math */
|
|
827
813
|
const min = Math.min;
|
|
828
814
|
|
|
829
815
|
/** Returns highest value passed in
|
|
830
816
|
* @param {...number} values
|
|
831
817
|
* @return {number}
|
|
832
|
-
* @memberof
|
|
818
|
+
* @memberof Math */
|
|
833
819
|
const max = Math.max;
|
|
834
820
|
|
|
835
821
|
/** Returns the sign of value passed in
|
|
836
822
|
* @param {number} value
|
|
837
823
|
* @return {number}
|
|
838
|
-
* @memberof
|
|
824
|
+
* @memberof Math */
|
|
839
825
|
const sign = Math.sign;
|
|
840
826
|
|
|
841
827
|
/** Returns hypotenuse of values passed in
|
|
842
828
|
* @param {...number} values
|
|
843
829
|
* @return {number}
|
|
844
|
-
* @memberof
|
|
830
|
+
* @memberof Math */
|
|
845
831
|
const hypot = Math.hypot;
|
|
846
832
|
|
|
847
833
|
/** Returns log2 of value passed in
|
|
848
834
|
* @param {number} value
|
|
849
835
|
* @return {number}
|
|
850
|
-
* @memberof
|
|
836
|
+
* @memberof Math */
|
|
851
837
|
const log2 = Math.log2;
|
|
852
838
|
|
|
853
839
|
/** Returns sin of value passed in
|
|
854
840
|
* @param {number} value
|
|
855
841
|
* @return {number}
|
|
856
|
-
* @memberof
|
|
842
|
+
* @memberof Math */
|
|
857
843
|
const sin = Math.sin;
|
|
858
844
|
|
|
859
845
|
/** Returns cos of value passed in
|
|
860
846
|
* @param {number} value
|
|
861
847
|
* @return {number}
|
|
862
|
-
* @memberof
|
|
848
|
+
* @memberof Math */
|
|
863
849
|
const cos = Math.cos;
|
|
864
850
|
|
|
865
851
|
/** Returns tan of value passed in
|
|
866
852
|
* @param {number} value
|
|
867
853
|
* @return {number}
|
|
868
|
-
* @memberof
|
|
854
|
+
* @memberof Math */
|
|
869
855
|
const tan = Math.tan;
|
|
870
856
|
|
|
871
857
|
/** Returns atan2 of values passed in
|
|
872
858
|
* @param {number} y
|
|
873
859
|
* @param {number} x
|
|
874
860
|
* @return {number}
|
|
875
|
-
* @memberof
|
|
861
|
+
* @memberof Math */
|
|
876
862
|
const atan2 = Math.atan2;
|
|
877
863
|
|
|
878
864
|
/** Returns first parm modulo the second param, but adjusted so negative numbers work as expected
|
|
879
865
|
* @param {number} dividend
|
|
880
866
|
* @param {number} [divisor]
|
|
881
867
|
* @return {number}
|
|
882
|
-
* @memberof
|
|
868
|
+
* @memberof Math */
|
|
883
869
|
function mod(dividend, divisor=1) { return ((dividend % divisor) + divisor) % divisor; }
|
|
884
870
|
|
|
885
871
|
/** Clamps the value between max and min
|
|
@@ -887,7 +873,7 @@ function mod(dividend, divisor=1) { return ((dividend % divisor) + divisor) % di
|
|
|
887
873
|
* @param {number} [min]
|
|
888
874
|
* @param {number} [max]
|
|
889
875
|
* @return {number}
|
|
890
|
-
* @memberof
|
|
876
|
+
* @memberof Math */
|
|
891
877
|
function clamp(value, min=0, max=1) { return value < min ? min : value > max ? max : value; }
|
|
892
878
|
|
|
893
879
|
/** Returns what percentage the value is between valueA and valueB
|
|
@@ -895,7 +881,7 @@ function clamp(value, min=0, max=1) { return value < min ? min : value > max ? m
|
|
|
895
881
|
* @param {number} valueA
|
|
896
882
|
* @param {number} valueB
|
|
897
883
|
* @return {number}
|
|
898
|
-
* @memberof
|
|
884
|
+
* @memberof Math */
|
|
899
885
|
function percent(value, valueA, valueB)
|
|
900
886
|
{ return (valueB-=valueA) ? clamp((value-valueA)/valueB) : 0; }
|
|
901
887
|
|
|
@@ -904,7 +890,7 @@ function percent(value, valueA, valueB)
|
|
|
904
890
|
* @param {number} valueB
|
|
905
891
|
* @param {number} percent
|
|
906
892
|
* @return {number}
|
|
907
|
-
* @memberof
|
|
893
|
+
* @memberof Math */
|
|
908
894
|
function lerp(valueA, valueB, percent)
|
|
909
895
|
{ return valueA + clamp(percent) * (valueB-valueA); }
|
|
910
896
|
|
|
@@ -916,7 +902,7 @@ function lerp(valueA, valueB, percent)
|
|
|
916
902
|
* @param {number} lerpA
|
|
917
903
|
* @param {number} lerpB
|
|
918
904
|
* @return {number}
|
|
919
|
-
* @memberof
|
|
905
|
+
* @memberof Math */
|
|
920
906
|
function percentLerp(value, percentA, percentB, lerpA, lerpB)
|
|
921
907
|
{ return lerp(lerpA, lerpB, percent(value, percentA, percentB)); }
|
|
922
908
|
|
|
@@ -925,7 +911,7 @@ function percentLerp(value, percentA, percentB, lerpA, lerpB)
|
|
|
925
911
|
* @param {number} valueB
|
|
926
912
|
* @param {number} [wrapSize]
|
|
927
913
|
* @return {number}
|
|
928
|
-
* @memberof
|
|
914
|
+
* @memberof Math */
|
|
929
915
|
function distanceWrap(valueA, valueB, wrapSize=1)
|
|
930
916
|
{ const d = (valueA - valueB) % wrapSize; return d*2 % wrapSize - d; }
|
|
931
917
|
|
|
@@ -935,7 +921,7 @@ function distanceWrap(valueA, valueB, wrapSize=1)
|
|
|
935
921
|
* @param {number} percent
|
|
936
922
|
* @param {number} [wrapSize]
|
|
937
923
|
* @return {number}
|
|
938
|
-
* @memberof
|
|
924
|
+
* @memberof Math */
|
|
939
925
|
function lerpWrap(valueA, valueB, percent, wrapSize=1)
|
|
940
926
|
{ return valueA + clamp(percent) * distanceWrap(valueB, valueA, wrapSize); }
|
|
941
927
|
|
|
@@ -943,7 +929,7 @@ function lerpWrap(valueA, valueB, percent, wrapSize=1)
|
|
|
943
929
|
* @param {number} angleA
|
|
944
930
|
* @param {number} angleB
|
|
945
931
|
* @return {number}
|
|
946
|
-
* @memberof
|
|
932
|
+
* @memberof Math */
|
|
947
933
|
function distanceAngle(angleA, angleB) { return distanceWrap(angleA, angleB, 2*PI); }
|
|
948
934
|
|
|
949
935
|
/** Linearly interpolates between the angles passed in with wrapping
|
|
@@ -951,25 +937,25 @@ function distanceAngle(angleA, angleB) { return distanceWrap(angleA, angleB, 2*P
|
|
|
951
937
|
* @param {number} angleB
|
|
952
938
|
* @param {number} percent
|
|
953
939
|
* @return {number}
|
|
954
|
-
* @memberof
|
|
940
|
+
* @memberof Math */
|
|
955
941
|
function lerpAngle(angleA, angleB, percent) { return lerpWrap(angleA, angleB, percent, 2*PI); }
|
|
956
942
|
|
|
957
943
|
/** Applies smoothstep function to the percentage value
|
|
958
944
|
* @param {number} percent
|
|
959
945
|
* @return {number}
|
|
960
|
-
* @memberof
|
|
946
|
+
* @memberof Math */
|
|
961
947
|
function smoothStep(percent) { return percent * percent * (3 - 2 * percent); }
|
|
962
948
|
|
|
963
949
|
/** Checks if the value passed in is a power of two
|
|
964
950
|
* @param {number} value
|
|
965
951
|
* @return {boolean}
|
|
966
|
-
* @memberof
|
|
952
|
+
* @memberof Math */
|
|
967
953
|
function isPowerOfTwo(value) { return !(value & (value - 1)); }
|
|
968
954
|
|
|
969
955
|
/** Returns the nearest power of two not less than the value
|
|
970
956
|
* @param {number} value
|
|
971
957
|
* @return {number}
|
|
972
|
-
* @memberof
|
|
958
|
+
* @memberof Math */
|
|
973
959
|
function nearestPowerOfTwo(value) { return 2**ceil(log2(value)); }
|
|
974
960
|
|
|
975
961
|
/** Returns true if two axis aligned bounding boxes are overlapping
|
|
@@ -979,7 +965,7 @@ function nearestPowerOfTwo(value) { return 2**ceil(log2(value)); }
|
|
|
979
965
|
* @param {Vector2} posB - Center of box B
|
|
980
966
|
* @param {Vector2} [sizeB=(0,0)] - Size of box B, uses a point if undefined
|
|
981
967
|
* @return {boolean} - True if overlapping
|
|
982
|
-
* @memberof
|
|
968
|
+
* @memberof Math */
|
|
983
969
|
function isOverlapping(posA, sizeA, posB, sizeB=vec2())
|
|
984
970
|
{
|
|
985
971
|
const dx = (posA.x - posB.x)*2;
|
|
@@ -995,7 +981,7 @@ function isOverlapping(posA, sizeA, posB, sizeB=vec2())
|
|
|
995
981
|
* @param {Vector2} pos - Center of box
|
|
996
982
|
* @param {Vector2} size - Size of box
|
|
997
983
|
* @return {boolean} - True if intersecting
|
|
998
|
-
* @memberof
|
|
984
|
+
* @memberof Math */
|
|
999
985
|
function isIntersecting(start, end, pos, size)
|
|
1000
986
|
{
|
|
1001
987
|
// Liang-Barsky algorithm
|
|
@@ -1036,52 +1022,29 @@ function isIntersecting(start, end, pos, size)
|
|
|
1036
1022
|
* @param {number} [t=time] - Value to use for time of the wave
|
|
1037
1023
|
* @param {number} [offset] - Value to use for time offset of the wave
|
|
1038
1024
|
* @return {number} - Value waving between 0 and amplitude
|
|
1039
|
-
* @memberof
|
|
1025
|
+
* @memberof Math */
|
|
1040
1026
|
function wave(frequency=1, amplitude=1, t=time, offset=0)
|
|
1041
1027
|
{ return amplitude/2 * (1 - cos(offset + t*frequency*2*PI)); }
|
|
1042
1028
|
|
|
1043
|
-
/** Formats seconds to mm:ss style for display purposes
|
|
1044
|
-
* @param {number} t - time in seconds
|
|
1045
|
-
* @return {string}
|
|
1046
|
-
* @memberof Utilities */
|
|
1047
|
-
function formatTime(t)
|
|
1048
|
-
{
|
|
1049
|
-
const sign = t < 0 ? '-' : '';
|
|
1050
|
-
t = abs(t)|0;
|
|
1051
|
-
return sign + (t/60|0) + ':' + (t%60<10?'0':'') + t%60;
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
/** Fetches a JSON file from a URL and returns the parsed JSON object. Must be used with await!
|
|
1055
|
-
* @param {string} url - URL of JSON file
|
|
1056
|
-
* @return {Promise<object>}
|
|
1057
|
-
* @memberof Utilities */
|
|
1058
|
-
async function fetchJSON(url)
|
|
1059
|
-
{
|
|
1060
|
-
const response = await fetch(url);
|
|
1061
|
-
if (!response.ok)
|
|
1062
|
-
throw new Error(`Failed to fetch JSON from ${url}: ${response.status} ${response.statusText}`);
|
|
1063
|
-
return response.json();
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
1029
|
/**
|
|
1067
1030
|
* Check if object is a valid number, not NaN or undefined, but it may be infinite
|
|
1068
1031
|
* @param {any} n
|
|
1069
1032
|
* @return {boolean}
|
|
1070
|
-
* @memberof
|
|
1033
|
+
* @memberof Math */
|
|
1071
1034
|
function isNumber(n) { return typeof n === 'number' && !isNaN(n); }
|
|
1072
1035
|
|
|
1073
1036
|
/**
|
|
1074
1037
|
* Check if object is a valid string or can be converted to one
|
|
1075
1038
|
* @param {any} s
|
|
1076
1039
|
* @return {boolean}
|
|
1077
|
-
* @memberof
|
|
1040
|
+
* @memberof Math */
|
|
1078
1041
|
function isString(s) { return s !== undefined && s !== null && typeof s.toString() === 'string'; }
|
|
1079
1042
|
|
|
1080
1043
|
/**
|
|
1081
1044
|
* Check if object is an array
|
|
1082
1045
|
* @param {any} a
|
|
1083
1046
|
* @return {boolean}
|
|
1084
|
-
* @memberof
|
|
1047
|
+
* @memberof Math */
|
|
1085
1048
|
function isArray(a) { return Array.isArray(a); }
|
|
1086
1049
|
|
|
1087
1050
|
/**
|
|
@@ -1097,7 +1060,7 @@ function isArray(a) { return Array.isArray(a); }
|
|
|
1097
1060
|
* @param {LineTestFunction} testFunction - Check if colliding
|
|
1098
1061
|
* @param {Vector2} [normal] - Optional vector to store the normal
|
|
1099
1062
|
* @return {Vector2|undefined} - Position of the collision or undefined if none found
|
|
1100
|
-
* @memberof
|
|
1063
|
+
* @memberof Math */
|
|
1101
1064
|
function lineTest(posStart, posEnd, testFunction, normal)
|
|
1102
1065
|
{
|
|
1103
1066
|
ASSERT(isVector2(posStart), 'posStart must be a vec2');
|
|
@@ -1109,8 +1072,7 @@ function lineTest(posStart, posEnd, testFunction, normal)
|
|
|
1109
1072
|
const dx = posEnd.x - posStart.x;
|
|
1110
1073
|
const dy = posEnd.y - posStart.y;
|
|
1111
1074
|
const totalLength = hypot(dx, dy);
|
|
1112
|
-
if (!totalLength)
|
|
1113
|
-
return;
|
|
1075
|
+
if (!totalLength) return;
|
|
1114
1076
|
|
|
1115
1077
|
// current integer cell we are in
|
|
1116
1078
|
const pos = posStart.floor();
|
|
@@ -1344,14 +1306,14 @@ class RandomGenerator
|
|
|
1344
1306
|
* let a = vec2(0, 1); // vector with coordinates (0, 1)
|
|
1345
1307
|
* a = vec2(5); // set a to (5, 5)
|
|
1346
1308
|
* b = vec2(); // set b to (0, 0)
|
|
1347
|
-
* @memberof
|
|
1309
|
+
* @memberof Math */
|
|
1348
1310
|
function vec2(x=0, y) { return new Vector2(x, y === undefined ? x : y); }
|
|
1349
1311
|
|
|
1350
1312
|
/**
|
|
1351
1313
|
* Check if object is a valid Vector2
|
|
1352
1314
|
* @param {any} v
|
|
1353
1315
|
* @return {boolean}
|
|
1354
|
-
* @memberof
|
|
1316
|
+
* @memberof Math */
|
|
1355
1317
|
function isVector2(v) { return v instanceof Vector2 && v.isValid(); }
|
|
1356
1318
|
|
|
1357
1319
|
// vector2 asserts
|
|
@@ -1601,7 +1563,7 @@ class Vector2
|
|
|
1601
1563
|
* @param {number} [b=1] - blue
|
|
1602
1564
|
* @param {number} [a=1] - alpha
|
|
1603
1565
|
* @return {Color}
|
|
1604
|
-
* @memberof
|
|
1566
|
+
* @memberof Math
|
|
1605
1567
|
*/
|
|
1606
1568
|
function rgb(r, g, b, a) { return new Color(r, g, b, a); }
|
|
1607
1569
|
|
|
@@ -1612,14 +1574,14 @@ function rgb(r, g, b, a) { return new Color(r, g, b, a); }
|
|
|
1612
1574
|
* @param {number} [l=1] - lightness
|
|
1613
1575
|
* @param {number} [a=1] - alpha
|
|
1614
1576
|
* @return {Color}
|
|
1615
|
-
* @memberof
|
|
1577
|
+
* @memberof Math */
|
|
1616
1578
|
function hsl(h, s, l, a) { return new Color().setHSLA(h, s, l, a); }
|
|
1617
1579
|
|
|
1618
1580
|
/**
|
|
1619
1581
|
* Check if object is a valid Color
|
|
1620
1582
|
* @param {any} c
|
|
1621
1583
|
* @return {boolean}
|
|
1622
|
-
* @memberof
|
|
1584
|
+
* @memberof Math */
|
|
1623
1585
|
function isColor(c) { return c instanceof Color && c.isValid(); }
|
|
1624
1586
|
|
|
1625
1587
|
// color asserts
|
|
@@ -1800,7 +1762,7 @@ class Color
|
|
|
1800
1762
|
toString(useAlpha = true)
|
|
1801
1763
|
{
|
|
1802
1764
|
if (debug && !this.isValid())
|
|
1803
|
-
return
|
|
1765
|
+
return '#000';
|
|
1804
1766
|
const toHex = (c)=> ((c=clamp(c)*255|0)<16 ? '0' : '') + c.toString(16);
|
|
1805
1767
|
return '#' + toHex(this.r) + toHex(this.g) + toHex(this.b) + (useAlpha ? toHex(this.a) : '');
|
|
1806
1768
|
}
|
|
@@ -1857,67 +1819,67 @@ class Color
|
|
|
1857
1819
|
|
|
1858
1820
|
/** Color - White #ffffff
|
|
1859
1821
|
* @type {Color}
|
|
1860
|
-
* @memberof
|
|
1822
|
+
* @memberof Math */
|
|
1861
1823
|
const WHITE = debugProtectConstant(rgb());
|
|
1862
1824
|
|
|
1863
1825
|
/** Color - Clear White #757474ff with 0 alpha
|
|
1864
1826
|
* @type {Color}
|
|
1865
|
-
* @memberof
|
|
1827
|
+
* @memberof Math */
|
|
1866
1828
|
const CLEAR_WHITE = debugProtectConstant(rgb(1,1,1,0));
|
|
1867
1829
|
|
|
1868
1830
|
/** Color - Black #000000
|
|
1869
1831
|
* @type {Color}
|
|
1870
|
-
* @memberof
|
|
1832
|
+
* @memberof Math */
|
|
1871
1833
|
const BLACK = debugProtectConstant(rgb(0,0,0));
|
|
1872
1834
|
|
|
1873
1835
|
/** Color - Clear Black #000000 with 0 alpha
|
|
1874
1836
|
* @type {Color}
|
|
1875
|
-
* @memberof
|
|
1837
|
+
* @memberof Math */
|
|
1876
1838
|
const CLEAR_BLACK = debugProtectConstant(rgb(0,0,0,0));
|
|
1877
1839
|
|
|
1878
1840
|
/** Color - Gray #808080
|
|
1879
1841
|
* @type {Color}
|
|
1880
|
-
* @memberof
|
|
1842
|
+
* @memberof Math */
|
|
1881
1843
|
const GRAY = debugProtectConstant(rgb(.5,.5,.5));
|
|
1882
1844
|
|
|
1883
1845
|
/** Color - Red #ff0000
|
|
1884
1846
|
* @type {Color}
|
|
1885
|
-
* @memberof
|
|
1847
|
+
* @memberof Math */
|
|
1886
1848
|
const RED = debugProtectConstant(rgb(1,0,0));
|
|
1887
1849
|
|
|
1888
1850
|
/** Color - Orange #ff8000
|
|
1889
1851
|
* @type {Color}
|
|
1890
|
-
* @memberof
|
|
1852
|
+
* @memberof Math */
|
|
1891
1853
|
const ORANGE = debugProtectConstant(rgb(1,.5,0));
|
|
1892
1854
|
|
|
1893
1855
|
/** Color - Yellow #ffff00
|
|
1894
1856
|
* @type {Color}
|
|
1895
|
-
* @memberof
|
|
1857
|
+
* @memberof Math */
|
|
1896
1858
|
const YELLOW = debugProtectConstant(rgb(1,1,0));
|
|
1897
1859
|
|
|
1898
1860
|
/** Color - Green #00ff00
|
|
1899
1861
|
* @type {Color}
|
|
1900
|
-
* @memberof
|
|
1862
|
+
* @memberof Math */
|
|
1901
1863
|
const GREEN = debugProtectConstant(rgb(0,1,0));
|
|
1902
1864
|
|
|
1903
1865
|
/** Color - Cyan #00ffff
|
|
1904
1866
|
* @type {Color}
|
|
1905
|
-
* @memberof
|
|
1867
|
+
* @memberof Math */
|
|
1906
1868
|
const CYAN = debugProtectConstant(rgb(0,1,1));
|
|
1907
1869
|
|
|
1908
1870
|
/** Color - Blue #0000ff
|
|
1909
1871
|
* @type {Color}
|
|
1910
|
-
* @memberof
|
|
1872
|
+
* @memberof Math */
|
|
1911
1873
|
const BLUE = debugProtectConstant(rgb(0,0,1));
|
|
1912
1874
|
|
|
1913
1875
|
/** Color - Purple #8000ff
|
|
1914
1876
|
* @type {Color}
|
|
1915
|
-
* @memberof
|
|
1877
|
+
* @memberof Math */
|
|
1916
1878
|
const PURPLE = debugProtectConstant(rgb(.5,0,1));
|
|
1917
1879
|
|
|
1918
1880
|
/** Color - Magenta #ff00ff
|
|
1919
1881
|
* @type {Color}
|
|
1920
|
-
* @memberof
|
|
1882
|
+
* @memberof Math */
|
|
1921
1883
|
const MAGENTA = debugProtectConstant(rgb(1,0,1));
|
|
1922
1884
|
|
|
1923
1885
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -2003,6 +1965,84 @@ class Timer
|
|
|
2003
1965
|
* @return {number} */
|
|
2004
1966
|
valueOf() { return this.get(); }
|
|
2005
1967
|
}
|
|
1968
|
+
/**
|
|
1969
|
+
* LittleJS Utility Classes and Functions
|
|
1970
|
+
* - General purpose math library
|
|
1971
|
+
* - Vector2 - fast, simple, easy 2D vector class
|
|
1972
|
+
* - Color - holds a rgba color with some math functions
|
|
1973
|
+
* - Timer - tracks time automatically
|
|
1974
|
+
* - RandomGenerator - seeded random number generator
|
|
1975
|
+
* @namespace Utilities
|
|
1976
|
+
*/
|
|
1977
|
+
|
|
1978
|
+
/** Formats seconds to mm:ss style for display purposes
|
|
1979
|
+
* @param {number} t - time in seconds
|
|
1980
|
+
* @return {string}
|
|
1981
|
+
* @memberof Utilities */
|
|
1982
|
+
function formatTime(t)
|
|
1983
|
+
{
|
|
1984
|
+
const sign = t < 0 ? '-' : '';
|
|
1985
|
+
t = abs(t)|0;
|
|
1986
|
+
return sign + (t/60|0) + ':' + (t%60<10?'0':'') + t%60;
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
/** Fetches a JSON file from a URL and returns the parsed JSON object. Must be used with await!
|
|
1990
|
+
* @param {string} url - URL of JSON file
|
|
1991
|
+
* @return {Promise<object>}
|
|
1992
|
+
* @memberof Utilities */
|
|
1993
|
+
async function fetchJSON(url)
|
|
1994
|
+
{
|
|
1995
|
+
const response = await fetch(url);
|
|
1996
|
+
if (!response.ok)
|
|
1997
|
+
throw new Error(`Failed to fetch JSON from ${url}: ${response.status} ${response.statusText}`);
|
|
1998
|
+
return response.json();
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2002
|
+
|
|
2003
|
+
/** Save a text file to disk
|
|
2004
|
+
* @param {string} text
|
|
2005
|
+
* @param {string} [filename]
|
|
2006
|
+
* @param {string} [type]
|
|
2007
|
+
* @memberof Utilities */
|
|
2008
|
+
function saveText(text, filename='text', type='text/plain')
|
|
2009
|
+
{ saveDataURL(URL.createObjectURL(new Blob([text], {'type':type})), filename); }
|
|
2010
|
+
|
|
2011
|
+
/** Save a canvas to disk
|
|
2012
|
+
* @param {HTMLCanvasElement|OffscreenCanvas} canvas
|
|
2013
|
+
* @param {string} [filename]
|
|
2014
|
+
* @param {string} [type]
|
|
2015
|
+
* @memberof Utilities */
|
|
2016
|
+
function saveCanvas(canvas, filename='screenshot', type='image/png')
|
|
2017
|
+
{
|
|
2018
|
+
if (canvas instanceof OffscreenCanvas)
|
|
2019
|
+
{
|
|
2020
|
+
// copy to temporary canvas and save
|
|
2021
|
+
const saveCanvas = document.createElement('canvas');
|
|
2022
|
+
saveCanvas.width = canvas.width;
|
|
2023
|
+
saveCanvas.height = canvas.height;
|
|
2024
|
+
saveCanvas.getContext('2d').drawImage(canvas, 0, 0);
|
|
2025
|
+
saveDataURL(saveCanvas.toDataURL(type), filename);
|
|
2026
|
+
}
|
|
2027
|
+
else
|
|
2028
|
+
saveDataURL(canvas.toDataURL(type), filename);
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
/** Save a data url to disk
|
|
2032
|
+
* @param {string} url
|
|
2033
|
+
* @param {string} [filename]
|
|
2034
|
+
* @param {number} [revokeTime] - how long before revoking the url
|
|
2035
|
+
* @memberof Utilities */
|
|
2036
|
+
function saveDataURL(url, filename='download', revokeTime)
|
|
2037
|
+
{
|
|
2038
|
+
// create link for saving screenshots
|
|
2039
|
+
const link = document.createElement('a');
|
|
2040
|
+
link.download = filename;
|
|
2041
|
+
link.href = url;
|
|
2042
|
+
link.click();
|
|
2043
|
+
if (revokeTime !== undefined)
|
|
2044
|
+
setTimeout(()=> URL.revokeObjectURL(url), revokeTime);
|
|
2045
|
+
}
|
|
2006
2046
|
/**
|
|
2007
2047
|
* LittleJS Engine Settings
|
|
2008
2048
|
* - All settings for the engine are here
|
|
@@ -2040,7 +2080,7 @@ let cameraScale = 32;
|
|
|
2040
2080
|
* @memberof Settings */
|
|
2041
2081
|
let canvasColorTiles = true;
|
|
2042
2082
|
|
|
2043
|
-
/** Color to clear the canvas to before render
|
|
2083
|
+
/** Color to clear the canvas to before render, does not clear if alpha is 0
|
|
2044
2084
|
* @type {Color}
|
|
2045
2085
|
* @memberof Draw */
|
|
2046
2086
|
let canvasClearColor = CLEAR_BLACK;
|
|
@@ -2349,7 +2389,7 @@ function setCameraScale(scale) { cameraScale = scale; }
|
|
|
2349
2389
|
* @memberof Settings */
|
|
2350
2390
|
function setCanvasColorTiles(colorTiles) { canvasColorTiles = colorTiles; }
|
|
2351
2391
|
|
|
2352
|
-
/** Set color to clear the canvas to before render
|
|
2392
|
+
/** Set color to clear the canvas to before render, does not clear if alpha is 0
|
|
2353
2393
|
* @param {Color} color
|
|
2354
2394
|
* @memberof Settings */
|
|
2355
2395
|
function setCanvasClearColor(color) { canvasClearColor = color.copy(); }
|
|
@@ -3107,8 +3147,7 @@ class EngineObject
|
|
|
3107
3147
|
/** Render debug info for this object */
|
|
3108
3148
|
renderDebugInfo()
|
|
3109
3149
|
{
|
|
3110
|
-
if (!debug)
|
|
3111
|
-
return;
|
|
3150
|
+
if (!debug) return;
|
|
3112
3151
|
|
|
3113
3152
|
// show object info for debugging
|
|
3114
3153
|
const size = vec2(max(this.size.x, .2), max(this.size.y, .2));
|
|
@@ -3150,11 +3189,6 @@ let mainCanvas;
|
|
|
3150
3189
|
* @memberof Draw */
|
|
3151
3190
|
let mainContext;
|
|
3152
3191
|
|
|
3153
|
-
/** The default canvas to use for drawing, usually mainCanvas
|
|
3154
|
-
* @type {HTMLCanvasElement|OffscreenCanvas}
|
|
3155
|
-
* @memberof Draw */
|
|
3156
|
-
let drawCanvas;
|
|
3157
|
-
|
|
3158
3192
|
/** The default 2d context to use for drawing, usually mainContext
|
|
3159
3193
|
* @type {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D}
|
|
3160
3194
|
* @memberof Draw */
|
|
@@ -3742,7 +3776,11 @@ function drawCanvas2D(pos, size, angle=0, mirror=false, drawFunction, screenSpac
|
|
|
3742
3776
|
ASSERT(typeof drawFunction === 'function', 'drawFunction must be a function');
|
|
3743
3777
|
|
|
3744
3778
|
if (!screenSpace)
|
|
3745
|
-
|
|
3779
|
+
{
|
|
3780
|
+
pos = worldToScreen(pos);
|
|
3781
|
+
size = size.scale(cameraScale);
|
|
3782
|
+
angle -= cameraAngle;
|
|
3783
|
+
}
|
|
3746
3784
|
context.save();
|
|
3747
3785
|
context.translate(pos.x+.5, pos.y+.5);
|
|
3748
3786
|
context.rotate(angle);
|
|
@@ -3794,9 +3832,9 @@ function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, f
|
|
|
3794
3832
|
* @param {string} [fontStyle]
|
|
3795
3833
|
* @param {number} [maxWidth]
|
|
3796
3834
|
* @param {number} [angle]
|
|
3797
|
-
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=
|
|
3835
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=drawContext]
|
|
3798
3836
|
* @memberof Draw */
|
|
3799
|
-
function drawTextScreen(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK, textAlign='center', font=fontDefault, fontStyle='', maxWidth, angle=0, context=
|
|
3837
|
+
function drawTextScreen(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK, textAlign='center', font=fontDefault, fontStyle='', maxWidth, angle=0, context=drawContext)
|
|
3800
3838
|
{
|
|
3801
3839
|
ASSERT(isString(text), 'text must be a string');
|
|
3802
3840
|
ASSERT(isVector2(pos), 'pos must be a vec2');
|
|
@@ -3937,25 +3975,6 @@ function screenToWorldTransform(screenPos, screenSize, screenAngle=0)
|
|
|
3937
3975
|
];
|
|
3938
3976
|
}
|
|
3939
3977
|
|
|
3940
|
-
/** Convert world space transform to screen space
|
|
3941
|
-
* @param {Vector2} worldPos
|
|
3942
|
-
* @param {Vector2} worldSize
|
|
3943
|
-
* @param {number} [worldAngle]
|
|
3944
|
-
* @return {[Vector2, Vector2, number]} - [pos, size, angle]
|
|
3945
|
-
* @memberof Draw */
|
|
3946
|
-
function worldToScreenTransform(worldPos, worldSize, worldAngle=0)
|
|
3947
|
-
{
|
|
3948
|
-
ASSERT(isVector2(worldPos), 'worldPos must be a vec2');
|
|
3949
|
-
ASSERT(isVector2(worldSize), 'worldSize must be a vec2');
|
|
3950
|
-
ASSERT(isNumber(worldAngle), 'worldAngle must be a number');
|
|
3951
|
-
|
|
3952
|
-
return [
|
|
3953
|
-
worldToScreen(worldPos),
|
|
3954
|
-
worldSize.scale(cameraScale),
|
|
3955
|
-
worldAngle - cameraAngle
|
|
3956
|
-
];
|
|
3957
|
-
}
|
|
3958
|
-
|
|
3959
3978
|
/** Get the size of the camera window in world space
|
|
3960
3979
|
* @return {Vector2}
|
|
3961
3980
|
* @memberof Draw */
|
|
@@ -4178,7 +4197,7 @@ class FontImage
|
|
|
4178
4197
|
* @param {boolean} [center]
|
|
4179
4198
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=drawContext]
|
|
4180
4199
|
*/
|
|
4181
|
-
drawTextScreen(text, pos, scale=4, center=true, context=
|
|
4200
|
+
drawTextScreen(text, pos, scale=4, center=true, context=drawContext)
|
|
4182
4201
|
{
|
|
4183
4202
|
context.save();
|
|
4184
4203
|
const size = this.tileSize;
|
|
@@ -4571,8 +4590,7 @@ function inputInit()
|
|
|
4571
4590
|
}
|
|
4572
4591
|
function onMouseDown(e)
|
|
4573
4592
|
{
|
|
4574
|
-
if (isTouchDevice && touchInputEnable)
|
|
4575
|
-
return;
|
|
4593
|
+
if (isTouchDevice && touchInputEnable) return;
|
|
4576
4594
|
|
|
4577
4595
|
// fix stalled audio requiring user interaction
|
|
4578
4596
|
if (soundEnable && !headlessMode && audioContext && !audioIsRunning())
|
|
@@ -4623,8 +4641,7 @@ function inputInit()
|
|
|
4623
4641
|
let wasTouching;
|
|
4624
4642
|
function handleTouch(e)
|
|
4625
4643
|
{
|
|
4626
|
-
if (!touchInputEnable)
|
|
4627
|
-
return;
|
|
4644
|
+
if (!touchInputEnable) return;
|
|
4628
4645
|
|
|
4629
4646
|
// route touch to gamepad
|
|
4630
4647
|
if (touchGamepadEnable)
|
|
@@ -4688,8 +4705,7 @@ function inputInit()
|
|
|
4688
4705
|
}
|
|
4689
4706
|
|
|
4690
4707
|
// don't process touch gamepad if paused
|
|
4691
|
-
if (paused)
|
|
4692
|
-
return;
|
|
4708
|
+
if (paused) return;
|
|
4693
4709
|
|
|
4694
4710
|
// get center of left and right sides
|
|
4695
4711
|
const stickCenter = vec2(touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
@@ -5375,8 +5391,7 @@ class SoundInstance
|
|
|
5375
5391
|
/** Pause this sound instance */
|
|
5376
5392
|
pause()
|
|
5377
5393
|
{
|
|
5378
|
-
if (this.isPaused())
|
|
5379
|
-
return;
|
|
5394
|
+
if (this.isPaused()) return;
|
|
5380
5395
|
|
|
5381
5396
|
// save current time and stop sound
|
|
5382
5397
|
this.pausedTime = this.getCurrentTime();
|
|
@@ -5388,8 +5403,7 @@ class SoundInstance
|
|
|
5388
5403
|
/** Unpauses this sound instance */
|
|
5389
5404
|
resume()
|
|
5390
5405
|
{
|
|
5391
|
-
if (!this.isPaused())
|
|
5392
|
-
return;
|
|
5406
|
+
if (!this.isPaused()) return;
|
|
5393
5407
|
|
|
5394
5408
|
// restart sound from paused time
|
|
5395
5409
|
this.start(this.pausedTime);
|
|
@@ -6127,12 +6141,11 @@ class TileLayer extends CanvasLayer
|
|
|
6127
6141
|
if (!this.context) return;
|
|
6128
6142
|
|
|
6129
6143
|
// save current render settings
|
|
6130
|
-
/** @type {[
|
|
6131
|
-
this.savedRenderSettings = [
|
|
6144
|
+
/** @type {[CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D, Vector2, Vector2, number, Color]} */
|
|
6145
|
+
this.savedRenderSettings = [drawContext, mainCanvasSize, cameraPos, cameraScale, canvasClearColor];
|
|
6132
6146
|
|
|
6133
6147
|
// set the draw canvas and context to this layer
|
|
6134
6148
|
// use camera settings to match this layer's canvas
|
|
6135
|
-
drawCanvas = this.canvas;
|
|
6136
6149
|
drawContext = this.context;
|
|
6137
6150
|
cameraPos = this.size.scale(.5);
|
|
6138
6151
|
const tileSize = this.tileInfo ? this.tileInfo.size : vec2(1);
|
|
@@ -6142,8 +6155,8 @@ class TileLayer extends CanvasLayer
|
|
|
6142
6155
|
if (clear)
|
|
6143
6156
|
{
|
|
6144
6157
|
// clear and set size
|
|
6145
|
-
|
|
6146
|
-
|
|
6158
|
+
this.canvas.width = mainCanvasSize.x;
|
|
6159
|
+
this.canvas.height = mainCanvasSize.y;
|
|
6147
6160
|
}
|
|
6148
6161
|
|
|
6149
6162
|
// disable smoothing for pixel art
|
|
@@ -6160,10 +6173,10 @@ class TileLayer extends CanvasLayer
|
|
|
6160
6173
|
|
|
6161
6174
|
ASSERT(drawContext === this.context, 'must call redrawStart() before drawing tiles');
|
|
6162
6175
|
glCopyToContext(drawContext);
|
|
6163
|
-
//
|
|
6176
|
+
//saveCanvas(this.canvas);
|
|
6164
6177
|
|
|
6165
6178
|
// set stuff back to normal
|
|
6166
|
-
[
|
|
6179
|
+
[drawContext, mainCanvasSize, cameraPos, cameraScale, canvasClearColor] = this.savedRenderSettings;
|
|
6167
6180
|
}
|
|
6168
6181
|
|
|
6169
6182
|
/** Draw the tile at a given position in the tile grid
|
|
@@ -6231,8 +6244,7 @@ class TileCollisionLayer extends TileLayer
|
|
|
6231
6244
|
/** Destroy this tile layer */
|
|
6232
6245
|
destroy()
|
|
6233
6246
|
{
|
|
6234
|
-
if (this.destroyed)
|
|
6235
|
-
return;
|
|
6247
|
+
if (this.destroyed) return;
|
|
6236
6248
|
|
|
6237
6249
|
// remove from collision layers array and destroy
|
|
6238
6250
|
const index = tileCollisionLayers.indexOf(this);
|
|
@@ -6769,10 +6781,11 @@ function medalsInit(saveName)
|
|
|
6769
6781
|
|
|
6770
6782
|
// engine automatically renders medals
|
|
6771
6783
|
engineAddPlugin(undefined, medalsRender);
|
|
6784
|
+
|
|
6785
|
+
// plugin functions
|
|
6772
6786
|
function medalsRender()
|
|
6773
6787
|
{
|
|
6774
|
-
if (!medalsDisplayQueue.length)
|
|
6775
|
-
return;
|
|
6788
|
+
if (!medalsDisplayQueue.length) return;
|
|
6776
6789
|
|
|
6777
6790
|
// update first medal in queue
|
|
6778
6791
|
const medal = medalsDisplayQueue[0];
|
|
@@ -6862,8 +6875,7 @@ class Medal
|
|
|
6862
6875
|
/** Unlocks a medal if not already unlocked */
|
|
6863
6876
|
unlock()
|
|
6864
6877
|
{
|
|
6865
|
-
if (medalsPreventUnlock || this.unlocked)
|
|
6866
|
-
return;
|
|
6878
|
+
if (medalsPreventUnlock || this.unlocked) return;
|
|
6867
6879
|
|
|
6868
6880
|
// save the medal
|
|
6869
6881
|
ASSERT(medalsSaveName, 'save name must be set');
|
|
@@ -7096,8 +7108,7 @@ function glInit(rootElement)
|
|
|
7096
7108
|
|
|
7097
7109
|
function glSetInstancedMode()
|
|
7098
7110
|
{
|
|
7099
|
-
if (!glPolyMode)
|
|
7100
|
-
return;
|
|
7111
|
+
if (!glPolyMode) return;
|
|
7101
7112
|
|
|
7102
7113
|
// setup instanced mode
|
|
7103
7114
|
glFlush();
|
|
@@ -7130,8 +7141,7 @@ function glSetInstancedMode()
|
|
|
7130
7141
|
|
|
7131
7142
|
function glSetPolyMode()
|
|
7132
7143
|
{
|
|
7133
|
-
if (glPolyMode)
|
|
7134
|
-
return;
|
|
7144
|
+
if (glPolyMode) return;
|
|
7135
7145
|
|
|
7136
7146
|
// setup poly mode
|
|
7137
7147
|
glFlush();
|
|
@@ -7210,8 +7220,8 @@ function glClearCanvas()
|
|
|
7210
7220
|
if (!glContext) return;
|
|
7211
7221
|
|
|
7212
7222
|
// clear and set to same size as main canvas
|
|
7213
|
-
glCanvas.width =
|
|
7214
|
-
glCanvas.height =
|
|
7223
|
+
glCanvas.width = mainCanvasSize.x;
|
|
7224
|
+
glCanvas.height = mainCanvasSize.y;
|
|
7215
7225
|
glContext.viewport(0, 0, glCanvas.width, glCanvas.height);
|
|
7216
7226
|
const color = canvasClearColor;
|
|
7217
7227
|
if (color.a > 0)
|
|
@@ -7227,8 +7237,7 @@ function glClearCanvas()
|
|
|
7227
7237
|
function glSetTexture(texture, wrap=false)
|
|
7228
7238
|
{
|
|
7229
7239
|
// must flush cache with the old texture to set a new one
|
|
7230
|
-
if (!glContext || texture === glActiveTexture)
|
|
7231
|
-
return;
|
|
7240
|
+
if (!glContext || texture === glActiveTexture) return;
|
|
7232
7241
|
|
|
7233
7242
|
glFlush();
|
|
7234
7243
|
glActiveTexture = texture;
|
|
@@ -7324,6 +7333,7 @@ function glCreateTexture(image)
|
|
|
7324
7333
|
function glDeleteTexture(texture)
|
|
7325
7334
|
{
|
|
7326
7335
|
if (!glContext) return;
|
|
7336
|
+
|
|
7327
7337
|
glContext.deleteTexture(texture);
|
|
7328
7338
|
}
|
|
7329
7339
|
|
|
@@ -7408,8 +7418,7 @@ function glFlush()
|
|
|
7408
7418
|
* @memberof WebGL */
|
|
7409
7419
|
function glCopyToContext(context)
|
|
7410
7420
|
{
|
|
7411
|
-
if (!glEnable || !glContext)
|
|
7412
|
-
return;
|
|
7421
|
+
if (!glEnable || !glContext) return;
|
|
7413
7422
|
|
|
7414
7423
|
glFlush();
|
|
7415
7424
|
context.drawImage(glCanvas, 0, 0);
|
|
@@ -9005,7 +9014,7 @@ class UIObject
|
|
|
9005
9014
|
this.onUpdate();
|
|
9006
9015
|
|
|
9007
9016
|
// unset active if disabled
|
|
9008
|
-
if (this.disabled && this
|
|
9017
|
+
if (this.disabled && this === uiSystem.activeObject)
|
|
9009
9018
|
uiSystem.activeObject = undefined;
|
|
9010
9019
|
|
|
9011
9020
|
const wasHover = uiSystem.lastHoverObject === this;
|