littlejsengine 1.4.6 → 1.4.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.
- package/README.md +80 -0
- package/build.bat +7 -3
- package/engine/engine.all.js +276 -295
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.module.js +286 -318
- package/engine/engine.all.module.min.js +1 -0
- package/engine/engine.all.release.js +276 -295
- package/engine/engine.js +28 -30
- package/engine/engineAudio.js +8 -15
- package/engine/engineBuild.bat +10 -3
- package/engine/engineDraw.js +14 -18
- package/engine/engineExport.js +10 -23
- package/engine/engineFont.png +0 -0
- package/engine/engineInput.js +86 -69
- package/engine/engineMedals.js +25 -32
- package/engine/engineObject.js +2 -2
- package/engine/engineParticles.js +7 -6
- package/engine/engineSettings.js +28 -28
- package/engine/engineTileLayer.js +15 -16
- package/engine/engineUtilities.js +26 -13
- package/engine/engineWebGL.js +38 -67
- package/engine/index.d.ts +52 -43
- package/examples/breakout/index.html +3 -3
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +12 -12
- package/examples/platformer/index.html +6 -6
- package/examples/puzzle/index.html +2 -2
- package/examples/stress/index.html +1 -1
- package/favicon.png +0 -0
- package/game.js +6 -8
- package/index.html +13 -13
- package/package.json +1 -1
- package/engine/engine.all.release.module.js +0 -4457
|
@@ -492,7 +492,7 @@ const wave = (frequency=1, amplitude=1, t=time)=> amplitude/2 * (1 - Math.cos(t*
|
|
|
492
492
|
* @param {Number} t - time in seconds
|
|
493
493
|
* @return {String}
|
|
494
494
|
* @memberof Utilities */
|
|
495
|
-
const formatTime = (t)=> (t/60|0)+':'+(t%60<10?'0':'')+(t%60|0);
|
|
495
|
+
const formatTime = (t)=> (t/60|0) + ':' + (t%60<10?'0':'') + (t%60|0);
|
|
496
496
|
|
|
497
497
|
///////////////////////////////////////////////////////////////////////////////
|
|
498
498
|
|
|
@@ -516,7 +516,7 @@ const randInt = (a=1, b=0)=> rand(a,b)|0;
|
|
|
516
516
|
/** Randomly returns either -1 or 1
|
|
517
517
|
* @return {Number}
|
|
518
518
|
* @memberof Random */
|
|
519
|
-
const randSign = ()=> (
|
|
519
|
+
const randSign = ()=> randInt(2) * 2 - 1;
|
|
520
520
|
|
|
521
521
|
/** Returns a random Vector2 within a circular shape
|
|
522
522
|
* @param {Number} [radius=1]
|
|
@@ -540,10 +540,15 @@ const randVector = (length=1)=> new Vector2().setAngle(rand(2*PI), length);
|
|
|
540
540
|
const randColor = (cA = new Color, cB = new Color(0,0,0,1), linear)=>
|
|
541
541
|
linear ? cA.lerp(cB, rand()) : new Color(rand(cA.r,cB.r),rand(cA.g,cB.g),rand(cA.b,cB.b),rand(cA.a,cB.a));
|
|
542
542
|
|
|
543
|
-
/**
|
|
543
|
+
/** Seed used by the randSeeded function
|
|
544
544
|
* @memberof Random */
|
|
545
545
|
let randSeed = 1;
|
|
546
546
|
|
|
547
|
+
/** Set seed used by the randSeeded function, should not be 0
|
|
548
|
+
* @param {Number} seed
|
|
549
|
+
* @memberof Random */
|
|
550
|
+
const setRandSeed = (seed)=> randSeed = seed;
|
|
551
|
+
|
|
547
552
|
/** Returns a seeded random value between the two values passed in using randSeed
|
|
548
553
|
* @param {Number} [valueA=1]
|
|
549
554
|
* @param {Number} [valueB=0]
|
|
@@ -571,6 +576,14 @@ const randSeeded = (a=1, b=0)=>
|
|
|
571
576
|
*/
|
|
572
577
|
const vec2 = (x=0, y)=> x.x == undefined ? new Vector2(x, y == undefined? x : y) : new Vector2(x.x, x.y);
|
|
573
578
|
|
|
579
|
+
/**
|
|
580
|
+
* Check if object is a valid Vector2
|
|
581
|
+
* @param {Vector2} vector
|
|
582
|
+
* @return {Boolean}
|
|
583
|
+
* @memberof Utilities
|
|
584
|
+
*/
|
|
585
|
+
const isVector2 = (v)=> !isNaN(v.x) && !isNaN(v.y);
|
|
586
|
+
|
|
574
587
|
/**
|
|
575
588
|
* 2D Vector object with vector math library
|
|
576
589
|
* <br> - Functions do not change this so they can be chained together
|
|
@@ -600,27 +613,27 @@ class Vector2
|
|
|
600
613
|
/** Returns a copy of this vector plus the vector passed in
|
|
601
614
|
* @param {Vector2} vector
|
|
602
615
|
* @return {Vector2} */
|
|
603
|
-
add(v) { ASSERT(v
|
|
616
|
+
add(v) { ASSERT(isVector2(v)); return new Vector2(this.x + v.x, this.y + v.y); }
|
|
604
617
|
|
|
605
618
|
/** Returns a copy of this vector minus the vector passed in
|
|
606
619
|
* @param {Vector2} vector
|
|
607
620
|
* @return {Vector2} */
|
|
608
|
-
subtract(v) { ASSERT(v
|
|
621
|
+
subtract(v) { ASSERT(isVector2(v)); return new Vector2(this.x - v.x, this.y - v.y); }
|
|
609
622
|
|
|
610
623
|
/** Returns a copy of this vector times the vector passed in
|
|
611
624
|
* @param {Vector2} vector
|
|
612
625
|
* @return {Vector2} */
|
|
613
|
-
multiply(v) { ASSERT(v
|
|
626
|
+
multiply(v) { ASSERT(isVector2(v)); return new Vector2(this.x * v.x, this.y * v.y); }
|
|
614
627
|
|
|
615
628
|
/** Returns a copy of this vector divided by the vector passed in
|
|
616
629
|
* @param {Vector2} vector
|
|
617
630
|
* @return {Vector2} */
|
|
618
|
-
divide(v) { ASSERT(v
|
|
631
|
+
divide(v) { ASSERT(isVector2(v)); return new Vector2(this.x / v.x, this.y / v.y); }
|
|
619
632
|
|
|
620
633
|
/** Returns a copy of this vector scaled by the vector passed in
|
|
621
634
|
* @param {Number} scale
|
|
622
635
|
* @return {Vector2} */
|
|
623
|
-
scale(s) { ASSERT(s
|
|
636
|
+
scale(s) { ASSERT(!isVector2(s)); return new Vector2(this.x * s, this.y * s); }
|
|
624
637
|
|
|
625
638
|
/** Returns the length of this vector
|
|
626
639
|
* @return {Number} */
|
|
@@ -653,12 +666,12 @@ class Vector2
|
|
|
653
666
|
/** Returns the dot product of this and the vector passed in
|
|
654
667
|
* @param {Vector2} vector
|
|
655
668
|
* @return {Number} */
|
|
656
|
-
dot(v) { ASSERT(v
|
|
669
|
+
dot(v) { ASSERT(isVector2(v)); return this.x*v.x + this.y*v.y; }
|
|
657
670
|
|
|
658
671
|
/** Returns the cross product of this and the vector passed in
|
|
659
672
|
* @param {Vector2} vector
|
|
660
673
|
* @return {Number} */
|
|
661
|
-
cross(v) { ASSERT(v
|
|
674
|
+
cross(v) { ASSERT(isVector2(v)); return this.x*v.y - this.y*v.x; }
|
|
662
675
|
|
|
663
676
|
/** Returns the angle of this vector, up is angle 0
|
|
664
677
|
* @return {Number} */
|
|
@@ -694,7 +707,7 @@ class Vector2
|
|
|
694
707
|
* @param {Vector2} vector
|
|
695
708
|
* @param {Number} percent
|
|
696
709
|
* @return {Vector2} */
|
|
697
|
-
lerp(v, p) { ASSERT(v
|
|
710
|
+
lerp(v, p) { ASSERT(isVector2(v)); return this.add(v.subtract(this).scale(clamp(p))); }
|
|
698
711
|
|
|
699
712
|
/** Returns true if this vector is within the bounds of an array size passed in
|
|
700
713
|
* @param {Vector2} arraySize
|
|
@@ -705,7 +718,7 @@ class Vector2
|
|
|
705
718
|
* @param {float} digits - precision to display
|
|
706
719
|
* @return {String} */
|
|
707
720
|
toString(digits=3)
|
|
708
|
-
{ return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`; }
|
|
721
|
+
{ if (debug) { return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`; }}
|
|
709
722
|
}
|
|
710
723
|
|
|
711
724
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -943,7 +956,7 @@ class Timer
|
|
|
943
956
|
|
|
944
957
|
/** Returns this timer expressed as a string
|
|
945
958
|
* @return {String} */
|
|
946
|
-
toString() { if (debug) { return this.unset() ? 'unset' : Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ); }
|
|
959
|
+
toString() { if (debug) { return this.unset() ? 'unset' : Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ); }}
|
|
947
960
|
|
|
948
961
|
/** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
|
|
949
962
|
* @return {Number} */
|
|
@@ -956,6 +969,20 @@ class Timer
|
|
|
956
969
|
|
|
957
970
|
'use strict';
|
|
958
971
|
|
|
972
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
973
|
+
// Camera settings
|
|
974
|
+
|
|
975
|
+
/** Position of camera in world space
|
|
976
|
+
* @type {Vector2}
|
|
977
|
+
* @default
|
|
978
|
+
* @memberof Settings */
|
|
979
|
+
let cameraPos = vec2();
|
|
980
|
+
|
|
981
|
+
/** Scale of camera in world space
|
|
982
|
+
* @default
|
|
983
|
+
* @memberof Settings */
|
|
984
|
+
let cameraScale = 16;
|
|
985
|
+
|
|
959
986
|
///////////////////////////////////////////////////////////////////////////////
|
|
960
987
|
// Display settings
|
|
961
988
|
|
|
@@ -982,6 +1009,19 @@ let cavasPixelated = 1;
|
|
|
982
1009
|
* @memberof Settings */
|
|
983
1010
|
let fontDefault = 'arial';
|
|
984
1011
|
|
|
1012
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
1013
|
+
// WebGL settings
|
|
1014
|
+
|
|
1015
|
+
/** Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)
|
|
1016
|
+
* @default
|
|
1017
|
+
* @memberof Settings */
|
|
1018
|
+
let glEnable = 1;
|
|
1019
|
+
|
|
1020
|
+
/** Fixes slow rendering in some browsers by not compositing the WebGL canvas
|
|
1021
|
+
* @default
|
|
1022
|
+
* @memberof Settings */
|
|
1023
|
+
let glOverlay = 1;
|
|
1024
|
+
|
|
985
1025
|
///////////////////////////////////////////////////////////////////////////////
|
|
986
1026
|
// Tile sheet settings
|
|
987
1027
|
|
|
@@ -1050,33 +1090,6 @@ let gravity = 0;
|
|
|
1050
1090
|
* @memberof Settings */
|
|
1051
1091
|
let particleEmitRateScale = 1;
|
|
1052
1092
|
|
|
1053
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1054
|
-
// Camera settings
|
|
1055
|
-
|
|
1056
|
-
/** Position of camera in world space
|
|
1057
|
-
* @type {Vector2}
|
|
1058
|
-
* @default
|
|
1059
|
-
* @memberof Settings */
|
|
1060
|
-
let cameraPos = vec2();
|
|
1061
|
-
|
|
1062
|
-
/** Scale of camera in world space
|
|
1063
|
-
* @default
|
|
1064
|
-
* @memberof Settings */
|
|
1065
|
-
let cameraScale = max(tileSizeDefault.x, tileSizeDefault.y);
|
|
1066
|
-
|
|
1067
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
1068
|
-
// WebGL settings
|
|
1069
|
-
|
|
1070
|
-
/** Enable webgl rendering, webgl can be disabled and removed from build (with some features disabled)
|
|
1071
|
-
* @default
|
|
1072
|
-
* @memberof Settings */
|
|
1073
|
-
let glEnable = 1;
|
|
1074
|
-
|
|
1075
|
-
/** Fixes slow rendering in some browsers by not compositing the WebGL canvas
|
|
1076
|
-
* @default
|
|
1077
|
-
* @memberof Settings */
|
|
1078
|
-
let glOverlay = 1;
|
|
1079
|
-
|
|
1080
1093
|
///////////////////////////////////////////////////////////////////////////////
|
|
1081
1094
|
// Input settings
|
|
1082
1095
|
|
|
@@ -1110,7 +1123,7 @@ let touchGamepadAnalog = 1;
|
|
|
1110
1123
|
/** Size of virutal gamepad for touch devices in pixels
|
|
1111
1124
|
* @default
|
|
1112
1125
|
* @memberof Settings */
|
|
1113
|
-
let touchGamepadSize =
|
|
1126
|
+
let touchGamepadSize = 99;
|
|
1114
1127
|
|
|
1115
1128
|
/** Transparency of touch gamepad overlay
|
|
1116
1129
|
* @default
|
|
@@ -1217,7 +1230,7 @@ class EngineObject
|
|
|
1217
1230
|
constructor(pos=vec2(), size=objectDefaultSize, tileIndex=-1, tileSize=tileSizeDefault, angle=0, color, renderOrder=0)
|
|
1218
1231
|
{
|
|
1219
1232
|
// set passed in params
|
|
1220
|
-
ASSERT(pos &&
|
|
1233
|
+
ASSERT(isVector2(pos) && isVector2(size)); // ensure pos and size are vec2s
|
|
1221
1234
|
|
|
1222
1235
|
/** @property {Vector2} - World space position of the object */
|
|
1223
1236
|
this.pos = pos.copy();
|
|
@@ -1307,7 +1320,7 @@ class EngineObject
|
|
|
1307
1320
|
if (this.collideSolidObjects)
|
|
1308
1321
|
{
|
|
1309
1322
|
// check collisions against solid objects
|
|
1310
|
-
const epsilon =
|
|
1323
|
+
const epsilon = .001; // necessary to push slightly outside of the collision
|
|
1311
1324
|
for (const o of engineObjectsCollide)
|
|
1312
1325
|
{
|
|
1313
1326
|
// non solid objects don't collide with eachother
|
|
@@ -1570,11 +1583,6 @@ class EngineObject
|
|
|
1570
1583
|
|
|
1571
1584
|
'use strict';
|
|
1572
1585
|
|
|
1573
|
-
/** Tile sheet for batch rendering system
|
|
1574
|
-
* @type {Image}
|
|
1575
|
-
* @memberof Draw */
|
|
1576
|
-
const tileImage = new Image();
|
|
1577
|
-
|
|
1578
1586
|
/** The primary 2D canvas visible to the user
|
|
1579
1587
|
* @type {HTMLCanvasElement}
|
|
1580
1588
|
* @memberof Draw */
|
|
@@ -1600,6 +1608,14 @@ let overlayContext;
|
|
|
1600
1608
|
* @memberof Draw */
|
|
1601
1609
|
let mainCanvasSize = vec2();
|
|
1602
1610
|
|
|
1611
|
+
/** Tile sheet for batch rendering system
|
|
1612
|
+
* @type {Image}
|
|
1613
|
+
* @memberof Draw */
|
|
1614
|
+
const tileImage = new Image;
|
|
1615
|
+
|
|
1616
|
+
// Engine internal variables not exposed to documentation
|
|
1617
|
+
let tileImageSize, tileImageFixBleed, drawCount;
|
|
1618
|
+
|
|
1603
1619
|
/** Convert from screen to world space coordinates
|
|
1604
1620
|
* - if calling outside of render, you may need to manually set mainCanvasSize
|
|
1605
1621
|
* @param {Vector2} screenPos
|
|
@@ -1624,7 +1640,7 @@ const worldToScreen = (worldPos)=>
|
|
|
1624
1640
|
|
|
1625
1641
|
/** Draw textured tile centered in world space, with color applied if using WebGL
|
|
1626
1642
|
* @param {Vector2} pos - Center of the tile in world space
|
|
1627
|
-
* @param {Vector2} [size=new Vector2(1,1)] - Size of the tile in world space
|
|
1643
|
+
* @param {Vector2} [size=new Vector2(1,1)] - Size of the tile in world space
|
|
1628
1644
|
* @param {Number} [tileIndex=-1] - Tile index to use, negative is untextured
|
|
1629
1645
|
* @param {Vector2} [tileSize=tileSizeDefault] - Tile size in source pixels
|
|
1630
1646
|
* @param {Color} [color=new Color(1,1,1)] - Color to modulate with
|
|
@@ -1843,10 +1859,10 @@ class FontImage
|
|
|
1843
1859
|
*/
|
|
1844
1860
|
constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1), startTileIndex=0, context=overlayContext)
|
|
1845
1861
|
{
|
|
1846
|
-
if (!
|
|
1862
|
+
if (!engineFontImage)
|
|
1847
1863
|
{
|
|
1848
1864
|
// load default font image
|
|
1849
|
-
engineFontImage = new Image
|
|
1865
|
+
engineFontImage = new Image;
|
|
1850
1866
|
engineFontImage.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAAYAQAAAAA9+x6JAAAAAnRSTlMAAHaTzTgAAAGiSURBVHjaZZABhxxBEIUf6ECLBdFY+Q0PMNgf0yCgsSAGZcT9sgIPtBWwIA5wgAPEoHUyJeeSlW+gjK+fegWwtROWpVQEyWh2npdpBmTUFVhb29RINgLIukoXr5LIAvYQ5ve+1FqWEMqNKTX3FAJHyQDRZvmKWubAACcv5z5Gtg2oyCWE+Yk/8JZQX1jTTCpKAFGIgza+dJCNBF2UskRlsgwitHbSV0QLgt9sTPtsRlvJjEr8C/FARWA2bJ/TtJ7lko34dNDn6usJUMzuErP89UUBJbWeozrwLLncXczd508deAjLWipLO4Q5XGPcJvPu92cNDaN0P5G1FL0nSOzddZOrJ6rNhbXGmeDvO3TF7DeJWl4bvaYQTNHCTeuqKZmbjHaSOFes+IX/+IhHrnAkXOAsfn24EM68XieIECoccD4KZLk/odiwzeo2rovYdhvb2HYFgyznJyDpYJdYOmfXgVdJTaUi4xA2uWYNYec9BLeqdl9EsoTw582mSFDX2DxVLbNt9U3YYoeatBad1c2Tj8t2akrjaIGJNywKB/7h75/gN3vCMSaadIUTAAAAAElFTkSuQmCC';
|
|
1851
1867
|
}
|
|
1852
1868
|
|
|
@@ -1913,7 +1929,7 @@ class FontImage
|
|
|
1913
1929
|
/** Returns true if fullscreen mode is active
|
|
1914
1930
|
* @return {Boolean}
|
|
1915
1931
|
* @memberof Draw */
|
|
1916
|
-
const isFullscreen =()=> document.fullscreenElement;
|
|
1932
|
+
const isFullscreen = ()=> document.fullscreenElement;
|
|
1917
1933
|
|
|
1918
1934
|
/** Toggle fullsceen mode
|
|
1919
1935
|
* @memberof Draw */
|
|
@@ -1923,16 +1939,9 @@ function toggleFullscreen()
|
|
|
1923
1939
|
{
|
|
1924
1940
|
if (document.exitFullscreen)
|
|
1925
1941
|
document.exitFullscreen();
|
|
1926
|
-
else if (document.mozCancelFullScreen)
|
|
1927
|
-
document.mozCancelFullScreen();
|
|
1928
|
-
}
|
|
1929
|
-
else
|
|
1930
|
-
{
|
|
1931
|
-
if (document.body.webkitRequestFullScreen)
|
|
1932
|
-
document.body.webkitRequestFullScreen();
|
|
1933
|
-
else if (document.body.mozRequestFullScreen)
|
|
1934
|
-
document.body.mozRequestFullScreen();
|
|
1935
1942
|
}
|
|
1943
|
+
else if (document.body.requestFullscreen)
|
|
1944
|
+
document.body.requestFullscreen();
|
|
1936
1945
|
}
|
|
1937
1946
|
|
|
1938
1947
|
/**
|
|
@@ -1951,7 +1960,7 @@ function toggleFullscreen()
|
|
|
1951
1960
|
* @param {Number} [device=0]
|
|
1952
1961
|
* @return {Boolean}
|
|
1953
1962
|
* @memberof Input */
|
|
1954
|
-
const keyIsDown = (key, device=0)=> inputData[device] && inputData[device][key] & 1
|
|
1963
|
+
const keyIsDown = (key, device=0)=> inputData[device] && inputData[device][key] & 1;
|
|
1955
1964
|
|
|
1956
1965
|
/** Returns true if device key was pressed this frame
|
|
1957
1966
|
* @param {Number} key
|
|
@@ -2190,32 +2199,41 @@ const isTouchDevice = window.ontouchstart !== undefined;
|
|
|
2190
2199
|
// try to enable touch mouse
|
|
2191
2200
|
if (isTouchDevice)
|
|
2192
2201
|
{
|
|
2193
|
-
//
|
|
2194
|
-
let wasTouching,
|
|
2195
|
-
|
|
2202
|
+
// override mouse events
|
|
2203
|
+
let wasTouching, mouseDown = onmousedown, mouseUp = onmouseup;
|
|
2204
|
+
onmousedown = onmouseup = ()=> 0;
|
|
2205
|
+
|
|
2206
|
+
// setup touch input
|
|
2207
|
+
ontouchstart = (e)=>
|
|
2196
2208
|
{
|
|
2197
|
-
|
|
2209
|
+
// fix mobile audio, force it to play a sound on first touch
|
|
2210
|
+
zzfx(0);
|
|
2198
2211
|
|
|
2199
|
-
//
|
|
2200
|
-
|
|
2201
|
-
if (touching)
|
|
2212
|
+
// handle all touch events the same way
|
|
2213
|
+
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
2202
2214
|
{
|
|
2203
|
-
|
|
2204
|
-
hadTouch || zzfx(0, hadTouch=1);
|
|
2215
|
+
e.button = 0; // all touches are left click
|
|
2205
2216
|
|
|
2206
|
-
//
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2217
|
+
// check if touching and pass to mouse events
|
|
2218
|
+
const touching = e.touches.length;
|
|
2219
|
+
if (touching)
|
|
2220
|
+
{
|
|
2221
|
+
// set event pos and pass it along
|
|
2222
|
+
e.x = e.touches[0].clientX;
|
|
2223
|
+
e.y = e.touches[0].clientY;
|
|
2224
|
+
wasTouching ? onmousemove(e) : mouseDown(e);
|
|
2225
|
+
}
|
|
2226
|
+
else if (wasTouching)
|
|
2227
|
+
mouseUp(e);
|
|
2228
|
+
|
|
2229
|
+
// set was touching
|
|
2230
|
+
wasTouching = touching;
|
|
2213
2231
|
|
|
2214
|
-
|
|
2215
|
-
|
|
2232
|
+
// must return true so the document will get focus
|
|
2233
|
+
return true;
|
|
2234
|
+
}
|
|
2216
2235
|
|
|
2217
|
-
|
|
2218
|
-
return true;
|
|
2236
|
+
return ontouchstart(e);
|
|
2219
2237
|
}
|
|
2220
2238
|
}
|
|
2221
2239
|
|
|
@@ -2223,7 +2241,7 @@ if (isTouchDevice)
|
|
|
2223
2241
|
// touch gamepad, virtual on screen gamepad emulator for touch devices
|
|
2224
2242
|
|
|
2225
2243
|
// touch input internal variables
|
|
2226
|
-
let touchGamepadTimer = new Timer, touchGamepadButtons
|
|
2244
|
+
let touchGamepadTimer = new Timer, touchGamepadButtons, touchGamepadStick;
|
|
2227
2245
|
|
|
2228
2246
|
// create the touch gamepad, called automatically by the engine
|
|
2229
2247
|
function touchGamepadCreate()
|
|
@@ -2231,65 +2249,73 @@ function touchGamepadCreate()
|
|
|
2231
2249
|
if (!touchGamepadEnable || !isTouchDevice)
|
|
2232
2250
|
return;
|
|
2233
2251
|
|
|
2234
|
-
|
|
2252
|
+
// touch input internal variables
|
|
2253
|
+
touchGamepadButtons = [];
|
|
2254
|
+
touchGamepadStick = vec2();
|
|
2255
|
+
|
|
2256
|
+
// setup touch input
|
|
2257
|
+
ontouchstart = (e)=>
|
|
2235
2258
|
{
|
|
2236
|
-
|
|
2237
|
-
|
|
2259
|
+
// fix mobile audio, force it to play a sound on first touch
|
|
2260
|
+
zzfx(0);
|
|
2238
2261
|
|
|
2239
|
-
|
|
2240
|
-
touchGamepadStick = vec2();
|
|
2241
|
-
touchGamepadButtons = [];
|
|
2242
|
-
|
|
2243
|
-
const touching = e.touches.length;
|
|
2244
|
-
if (touching)
|
|
2262
|
+
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
2245
2263
|
{
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
if (paused)
|
|
2264
|
+
// clear touch gamepad input
|
|
2265
|
+
touchGamepadStick = vec2();
|
|
2266
|
+
touchGamepadButtons = [];
|
|
2267
|
+
|
|
2268
|
+
const touching = e.touches.length;
|
|
2269
|
+
if (touching)
|
|
2253
2270
|
{
|
|
2254
|
-
//
|
|
2255
|
-
|
|
2256
|
-
|
|
2271
|
+
// set that gamepad is active
|
|
2272
|
+
isUsingGamepad = 1;
|
|
2273
|
+
touchGamepadTimer.set();
|
|
2274
|
+
|
|
2275
|
+
if (paused)
|
|
2276
|
+
{
|
|
2277
|
+
// touch anywhere to press start when paused
|
|
2278
|
+
touchGamepadButtons[9] = 1;
|
|
2279
|
+
return;
|
|
2280
|
+
}
|
|
2257
2281
|
}
|
|
2258
|
-
}
|
|
2259
2282
|
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2283
|
+
// get center of left and right sides
|
|
2284
|
+
const stickCenter = vec2(touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
2285
|
+
const buttonCenter = mainCanvasSize.subtract(vec2(touchGamepadSize, touchGamepadSize));
|
|
2286
|
+
const startCenter = mainCanvasSize.scale(.5);
|
|
2264
2287
|
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
{
|
|
2268
|
-
const touchPos = mouseToScreen(vec2(touch.clientX, touch.clientY));
|
|
2269
|
-
if (touchPos.distance(stickCenter) < touchGamepadSize)
|
|
2288
|
+
// check each touch point
|
|
2289
|
+
for (const touch of e.touches)
|
|
2270
2290
|
{
|
|
2271
|
-
|
|
2272
|
-
if (
|
|
2273
|
-
touchGamepadStick = touchPos.subtract(stickCenter).scale(2/touchGamepadSize).clampLength();
|
|
2274
|
-
else
|
|
2291
|
+
const touchPos = mouseToScreen(vec2(touch.clientX, touch.clientY));
|
|
2292
|
+
if (touchPos.distance(stickCenter) < touchGamepadSize)
|
|
2275
2293
|
{
|
|
2276
|
-
//
|
|
2277
|
-
|
|
2278
|
-
|
|
2294
|
+
// virtual analog stick
|
|
2295
|
+
if (touchGamepadAnalog)
|
|
2296
|
+
touchGamepadStick = touchPos.subtract(stickCenter).scale(2/touchGamepadSize).clampLength();
|
|
2297
|
+
else
|
|
2298
|
+
{
|
|
2299
|
+
// 8 way dpad
|
|
2300
|
+
const angle = touchPos.subtract(stickCenter).angle();
|
|
2301
|
+
touchGamepadStick.setAngle((angle * 4 / PI + 8.5 | 0) * PI / 4);
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
else if (touchPos.distance(buttonCenter) < touchGamepadSize)
|
|
2305
|
+
{
|
|
2306
|
+
// virtual face buttons
|
|
2307
|
+
const button = touchPos.subtract(buttonCenter).direction();
|
|
2308
|
+
touchGamepadButtons[button] = 1;
|
|
2309
|
+
}
|
|
2310
|
+
else if (touchPos.distance(startCenter) < touchGamepadSize)
|
|
2311
|
+
{
|
|
2312
|
+
// virtual start button in center
|
|
2313
|
+
touchGamepadButtons[9] = 1;
|
|
2279
2314
|
}
|
|
2280
|
-
}
|
|
2281
|
-
else if (touchPos.distance(buttonCenter) < touchGamepadSize)
|
|
2282
|
-
{
|
|
2283
|
-
// virtual face buttons
|
|
2284
|
-
const button = touchPos.subtract(buttonCenter).direction();
|
|
2285
|
-
touchGamepadButtons[button] = 1;
|
|
2286
|
-
}
|
|
2287
|
-
else if (touchPos.distance(startCenter) < touchGamepadSize)
|
|
2288
|
-
{
|
|
2289
|
-
// virtual start button in center
|
|
2290
|
-
touchGamepadButtons[9] = 1;
|
|
2291
2315
|
}
|
|
2292
2316
|
}
|
|
2317
|
+
|
|
2318
|
+
return ontouchstart(e);
|
|
2293
2319
|
}
|
|
2294
2320
|
}
|
|
2295
2321
|
|
|
@@ -2407,7 +2433,7 @@ class Sound
|
|
|
2407
2433
|
{
|
|
2408
2434
|
if (!soundEnable) return;
|
|
2409
2435
|
|
|
2410
|
-
let pan
|
|
2436
|
+
let pan;
|
|
2411
2437
|
if (pos)
|
|
2412
2438
|
{
|
|
2413
2439
|
const range = this.range;
|
|
@@ -2437,7 +2463,7 @@ class Sound
|
|
|
2437
2463
|
* @param {Number} [volume=1] - How much to scale volume by (in addition to range fade)
|
|
2438
2464
|
* @return {AudioBufferSourceNode} - The audio, can be used to stop sound later
|
|
2439
2465
|
*/
|
|
2440
|
-
playNote(semitoneOffset, pos, volume
|
|
2466
|
+
playNote(semitoneOffset, pos, volume)
|
|
2441
2467
|
{
|
|
2442
2468
|
if (!soundEnable) return;
|
|
2443
2469
|
|
|
@@ -2492,7 +2518,7 @@ class Music
|
|
|
2492
2518
|
* @param {Boolean} [loop=1] - True if the music should loop when it reaches the end
|
|
2493
2519
|
* @return {AudioBufferSourceNode} - The audio node, can be used to stop sound later
|
|
2494
2520
|
*/
|
|
2495
|
-
play(volume
|
|
2521
|
+
play(volume, loop = 1)
|
|
2496
2522
|
{
|
|
2497
2523
|
if (!soundEnable) return;
|
|
2498
2524
|
|
|
@@ -2574,7 +2600,7 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0)
|
|
|
2574
2600
|
|
|
2575
2601
|
// create audio context
|
|
2576
2602
|
if (!audioContext)
|
|
2577
|
-
audioContext = new
|
|
2603
|
+
audioContext = new AudioContext;
|
|
2578
2604
|
|
|
2579
2605
|
// fix stalled audio
|
|
2580
2606
|
audioContext.resume();
|
|
@@ -2593,18 +2619,13 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0)
|
|
|
2593
2619
|
source.playbackRate.value = rate;
|
|
2594
2620
|
source.loop = loop;
|
|
2595
2621
|
|
|
2596
|
-
// create and connect gain node (createGain is more
|
|
2622
|
+
// create and connect gain node (createGain is more widely spported then GainNode construtor)
|
|
2597
2623
|
const gainNode = audioContext.createGain();
|
|
2598
2624
|
gainNode.gain.value = soundVolume*volume;
|
|
2599
2625
|
gainNode.connect(audioContext.destination);
|
|
2600
2626
|
|
|
2601
|
-
// connect source to gain
|
|
2602
|
-
(
|
|
2603
|
-
window.StereoPannerNode ? // create pan node if possible
|
|
2604
|
-
source.connect(new StereoPannerNode(audioContext, {'pan':clamp(pan, -1, 1)}))
|
|
2605
|
-
: source
|
|
2606
|
-
)
|
|
2607
|
-
.connect(gainNode);
|
|
2627
|
+
// connect source to stereo panner and gain
|
|
2628
|
+
source.connect(new StereoPannerNode(audioContext, {'pan':clamp(pan, -1, 1)})).connect(gainNode);
|
|
2608
2629
|
|
|
2609
2630
|
// play and return sound
|
|
2610
2631
|
source.start();
|
|
@@ -2722,10 +2743,8 @@ function zzfxG
|
|
|
2722
2743
|
* @memberof Audio */
|
|
2723
2744
|
function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
2724
2745
|
{
|
|
2746
|
+
let i, j, k;
|
|
2725
2747
|
let instrumentParameters;
|
|
2726
|
-
let i;
|
|
2727
|
-
let j;
|
|
2728
|
-
let k;
|
|
2729
2748
|
let note;
|
|
2730
2749
|
let sample;
|
|
2731
2750
|
let patternChannel;
|
|
@@ -2895,14 +2914,11 @@ function tileCollisionRaycast(posStart, posEnd, object)
|
|
|
2895
2914
|
{
|
|
2896
2915
|
// test if a ray collides with tiles from start to end
|
|
2897
2916
|
// todo: a way to get the exact hit point, it must still register as inside the hit tile
|
|
2898
|
-
posStart = posStart.floor();
|
|
2899
|
-
posEnd = posEnd.floor();
|
|
2900
|
-
const posDelta = posEnd.subtract(posStart);
|
|
2917
|
+
const posDelta = (posEnd = posEnd.floor()).subtract(posStart = posStart.floor());
|
|
2901
2918
|
const dx = abs(posDelta.x), dy = -abs(posDelta.y);
|
|
2902
2919
|
const sx = sign(posDelta.x), sy = sign(posDelta.y);
|
|
2903
|
-
let e = dx + dy;
|
|
2904
2920
|
|
|
2905
|
-
for (let x = posStart.x, y = posStart.y;;)
|
|
2921
|
+
for (let x = posStart.x, y = posStart.y, e = dx + dy;;)
|
|
2906
2922
|
{
|
|
2907
2923
|
const tileData = getTileCollisionData(vec2(x,y));
|
|
2908
2924
|
if (tileData && (object ? object.collideWithTileRaycast(tileData, new Vector2(x, y)) : tileData > 0))
|
|
@@ -2994,7 +3010,7 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
|
|
|
2994
3010
|
// init tile data
|
|
2995
3011
|
this.data = [];
|
|
2996
3012
|
for (let j = this.size.area(); j--;)
|
|
2997
|
-
this.data.push(new TileLayerData
|
|
3013
|
+
this.data.push(new TileLayerData);
|
|
2998
3014
|
}
|
|
2999
3015
|
|
|
3000
3016
|
/** Set data at a given position in the array
|
|
@@ -3050,21 +3066,23 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
|
|
|
3050
3066
|
* @param {Boolean} [clear=0] - Should it clear the canvas before drawing */
|
|
3051
3067
|
redrawStart(clear = 0)
|
|
3052
3068
|
{
|
|
3053
|
-
if (clear)
|
|
3054
|
-
{
|
|
3055
|
-
// clear and set size
|
|
3056
|
-
this.canvas.width = this.size.x * this.tileSize.x;
|
|
3057
|
-
this.canvas.height = this.size.y * this.tileSize.y;
|
|
3058
|
-
}
|
|
3059
|
-
|
|
3060
3069
|
// save current render settings
|
|
3061
|
-
this.savedRenderSettings = [mainCanvas, mainContext, cameraPos, cameraScale];
|
|
3070
|
+
this.savedRenderSettings = [mainCanvas, mainContext, mainCanvasSize, cameraPos, cameraScale];
|
|
3062
3071
|
|
|
3063
|
-
// use normal rendering system to render the tiles
|
|
3072
|
+
// hack: use normal rendering system to render the tiles
|
|
3064
3073
|
mainCanvas = this.canvas;
|
|
3065
3074
|
mainContext = this.context;
|
|
3066
3075
|
cameraPos = this.size.scale(.5);
|
|
3067
3076
|
cameraScale = this.tileSize.x;
|
|
3077
|
+
|
|
3078
|
+
if (clear)
|
|
3079
|
+
{
|
|
3080
|
+
// clear and set size
|
|
3081
|
+
mainCanvas.width = this.size.x * this.tileSize.x;
|
|
3082
|
+
mainCanvas.height = this.size.y * this.tileSize.y;
|
|
3083
|
+
}
|
|
3084
|
+
|
|
3085
|
+
// begin a new render for the tile canvas
|
|
3068
3086
|
enginePreRender();
|
|
3069
3087
|
}
|
|
3070
3088
|
|
|
@@ -3076,7 +3094,7 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
|
|
|
3076
3094
|
//debugSaveCanvas(this.canvas);
|
|
3077
3095
|
|
|
3078
3096
|
// set stuff back to normal
|
|
3079
|
-
[mainCanvas, mainContext, cameraPos, cameraScale] = this.savedRenderSettings;
|
|
3097
|
+
[mainCanvas, mainContext, mainCanvasSize, cameraPos, cameraScale] = this.savedRenderSettings;
|
|
3080
3098
|
}
|
|
3081
3099
|
|
|
3082
3100
|
/** Draw the tile at a given position
|
|
@@ -3317,7 +3335,7 @@ class ParticleEmitter extends EngineObject
|
|
|
3317
3335
|
this.parent && super.update();
|
|
3318
3336
|
|
|
3319
3337
|
// update emitter
|
|
3320
|
-
if (!this.emitTime
|
|
3338
|
+
if (!this.emitTime | this.getAliveTime() <= this.emitTime)
|
|
3321
3339
|
{
|
|
3322
3340
|
// emit particles
|
|
3323
3341
|
if (this.emitRate * particleEmitRateScale)
|
|
@@ -3339,9 +3357,9 @@ class ParticleEmitter extends EngineObject
|
|
|
3339
3357
|
{
|
|
3340
3358
|
// spawn a particle
|
|
3341
3359
|
let pos = this.emitSize.x != undefined ? // check if vec2 was used for size
|
|
3342
|
-
(new Vector2(rand(
|
|
3343
|
-
.multiply(this.emitSize).rotate(this.angle) // box emitter
|
|
3344
|
-
: randInCircle(this.emitSize
|
|
3360
|
+
(new Vector2(rand(-1,1), rand(-1,1)))
|
|
3361
|
+
.multiply(this.emitSize/2).rotate(this.angle) // box emitter
|
|
3362
|
+
: randInCircle(this.emitSize/2); // circle emitter
|
|
3345
3363
|
let angle = rand(this.particleConeAngle, -this.particleConeAngle);
|
|
3346
3364
|
if (!this.localSpace)
|
|
3347
3365
|
{
|
|
@@ -3384,7 +3402,7 @@ class ParticleEmitter extends EngineObject
|
|
|
3384
3402
|
particle.additive = this.additive;
|
|
3385
3403
|
particle.renderOrder = this.renderOrder;
|
|
3386
3404
|
particle.trailScale = this.trailScale;
|
|
3387
|
-
particle.mirror =
|
|
3405
|
+
particle.mirror = randInt(2);
|
|
3388
3406
|
particle.localSpaceEmitter = this.localSpace && this;
|
|
3389
3407
|
|
|
3390
3408
|
// setup callbacks for particles
|
|
@@ -3413,7 +3431,8 @@ class Particle extends EngineObject
|
|
|
3413
3431
|
* @param {Vector2} [tileSize=tileSizeDefault] - Size of tile in source pixels
|
|
3414
3432
|
* @param {Number} [angle=0] - Angle to rotate the particle
|
|
3415
3433
|
*/
|
|
3416
|
-
constructor(pos, tileIndex, tileSize, angle)
|
|
3434
|
+
constructor(pos, tileIndex, tileSize, angle)
|
|
3435
|
+
{ super(pos, new Vector2, tileIndex, tileSize, angle); }
|
|
3417
3436
|
|
|
3418
3437
|
/** Render the particle, automatically called each frame, sorted by renderOrder */
|
|
3419
3438
|
render()
|
|
@@ -3533,7 +3552,7 @@ class Medal
|
|
|
3533
3552
|
this.name = name;
|
|
3534
3553
|
this.description = description;
|
|
3535
3554
|
this.icon = icon;
|
|
3536
|
-
this.image = new Image
|
|
3555
|
+
this.image = new Image;
|
|
3537
3556
|
if (src)
|
|
3538
3557
|
this.image.src = src;
|
|
3539
3558
|
}
|
|
@@ -3548,10 +3567,7 @@ class Medal
|
|
|
3548
3567
|
ASSERT(medalsSaveName); // save name must be set
|
|
3549
3568
|
localStorage[this.storageKey()] = this.unlocked = 1;
|
|
3550
3569
|
medalsDisplayQueue.push(this);
|
|
3551
|
-
|
|
3552
|
-
// save for newgrounds and OS13K
|
|
3553
3570
|
newgrounds && newgrounds.unlockMedal(this.id);
|
|
3554
|
-
localStorage['OS13kTrophy,' + this.icon + ',' + medalsSaveName + ',' + this.name] = this.description;
|
|
3555
3571
|
}
|
|
3556
3572
|
|
|
3557
3573
|
/** Render a medal
|
|
@@ -3567,20 +3583,19 @@ class Medal
|
|
|
3567
3583
|
// draw containing rect and clip to that region
|
|
3568
3584
|
context.save();
|
|
3569
3585
|
context.beginPath();
|
|
3570
|
-
context.fillStyle =
|
|
3571
|
-
context.
|
|
3572
|
-
context.strokeStyle = '#000';
|
|
3586
|
+
context.fillStyle = new Color(.9,.9,.9);
|
|
3587
|
+
context.strokeStyle = new Color(0,0,0);
|
|
3573
3588
|
context.lineWidth = 3;
|
|
3589
|
+
context.fill(context.rect(x, y, width, medalDisplayHeight));
|
|
3574
3590
|
context.stroke();
|
|
3575
3591
|
context.clip();
|
|
3576
3592
|
|
|
3577
3593
|
// draw the icon and text
|
|
3578
|
-
this.renderIcon(x+15+medalDisplayIconSize/2, y+medalDisplayHeight/2);
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
context.fillText(this.description, x+medalDisplayIconSize+30, y+60);
|
|
3594
|
+
this.renderIcon(vec2(x+15+medalDisplayIconSize/2, y+medalDisplayHeight/2));
|
|
3595
|
+
const pos = vec2(x+medalDisplayIconSize+30, y+28);
|
|
3596
|
+
drawTextScreen(this.name, pos, 38, new Color(0,0,0), 0, 0, 'left');
|
|
3597
|
+
pos.y += 32;
|
|
3598
|
+
drawTextScreen(this.description, pos, 24, new Color(0,0,0), 0, 0, 'left');
|
|
3584
3599
|
context.restore();
|
|
3585
3600
|
}
|
|
3586
3601
|
|
|
@@ -3589,18 +3604,13 @@ class Medal
|
|
|
3589
3604
|
* @param {Number} y - Screen space Y position
|
|
3590
3605
|
* @param {Number} [size=medalDisplayIconSize] - Screen space size
|
|
3591
3606
|
*/
|
|
3592
|
-
renderIcon(
|
|
3607
|
+
renderIcon(pos, size=medalDisplayIconSize)
|
|
3593
3608
|
{
|
|
3594
3609
|
// draw the image or icon
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
context.textAlign = 'center';
|
|
3598
|
-
context.textBaseline = 'middle';
|
|
3599
|
-
context.font = size*.7 + 'px '+ fontDefault;
|
|
3600
|
-
if (this.image.src)
|
|
3601
|
-
context.drawImage(this.image, x-size/2, y-size/2, size, size);
|
|
3610
|
+
if (this.image)
|
|
3611
|
+
overlayContext.drawImage(this.image, pos.x-size/2, pos.y-size/2, size, size);
|
|
3602
3612
|
else
|
|
3603
|
-
|
|
3613
|
+
drawTextScreen(this.icon, pos, size*.7, new Color(0,0,0));
|
|
3604
3614
|
}
|
|
3605
3615
|
|
|
3606
3616
|
// Get local storage key used by the medal
|
|
@@ -3658,13 +3668,21 @@ class Newgrounds
|
|
|
3658
3668
|
constructor(app_id, cipher)
|
|
3659
3669
|
{
|
|
3660
3670
|
ASSERT(!newgrounds && app_id);
|
|
3671
|
+
|
|
3672
|
+
// create an instance of CryptoJS for encrypted calls
|
|
3673
|
+
if (cipher)
|
|
3674
|
+
{
|
|
3675
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
3676
|
+
// Crypto-JS - https://github.com/brix/crypto-js [The MIT License (MIT)]
|
|
3677
|
+
// Copyright (c) 2009-2013 Jeff Mott Copyright (c) 2013-2016 Evan Vosberg
|
|
3678
|
+
|
|
3679
|
+
this.cryptoJS = eval(Function("[M='GBMGXz^oVYPPKKbB`agTXU|LxPc_ZBcMrZvCr~wyGfWrwk@ATqlqeTp^N?p{we}jIpEnB_sEr`l?YDkDhWhprc|Er|XETG?pTl`e}dIc[_N~}fzRycIfpW{HTolvoPB_FMe_eH~BTMx]yyOhv?biWPCGc]kABencBhgERHGf{OL`Dj`c^sh@canhy[secghiyotcdOWgO{tJIE^JtdGQRNSCrwKYciZOa]Y@tcRATYKzv|sXpboHcbCBf`}SKeXPFM|RiJsSNaIb]QPc[D]Jy_O^XkOVTZep`ONmntLL`Qz~UupHBX_Ia~WX]yTRJIxG`ioZ{fefLJFhdyYoyLPvqgH?b`[TMnTwwfzDXhfM?rKs^aFr|nyBdPmVHTtAjXoYUloEziWDCw_suyYT~lSMksI~ZNCS[Bex~j]Vz?kx`gdYSEMCsHpjbyxQvw|XxX_^nQYue{sBzVWQKYndtYQMWRef{bOHSfQhiNdtR{o?cUAHQAABThwHPT}F{VvFmgN`E@FiFYS`UJmpQNM`X|tPKHlccT}z}k{sACHL?Rt@MkWplxO`ASgh?hBsuuP|xD~LSH~KBlRs]t|l|_tQAroDRqWS^SEr[sYdPB}TAROtW{mIkE|dWOuLgLmJrucGLpebrAFKWjikTUzS|j}M}szasKOmrjy[?hpwnEfX[jGpLt@^v_eNwSQHNwtOtDgWD{rk|UgASs@mziIXrsHN_|hZuxXlPJOsA^^?QY^yGoCBx{ekLuZzRqQZdsNSx@ezDAn{XNj@fRXIwrDX?{ZQHwTEfu@GhxDOykqts|n{jOeZ@c`dvTY?e^]ATvWpb?SVyg]GC?SlzteilZJAL]mlhLjYZazY__qcVFYvt@|bIQnSno@OXyt]OulzkWqH`rYFWrwGs`v|~XeTsIssLrbmHZCYHiJrX}eEzSssH}]l]IhPQhPoQ}rCXLyhFIT[clhzYOvyHqigxmjz`phKUU^TPf[GRAIhNqSOdayFP@FmKmuIzMOeoqdpxyCOwCthcLq?n`L`tLIBboNn~uXeFcPE{C~mC`h]jUUUQe^`UqvzCutYCgct|SBrAeiYQW?X~KzCz}guXbsUw?pLsg@hDArw?KeJD[BN?GD@wgFWCiHq@Ypp_QKFixEKWqRp]oJFuVIEvjDcTFu~Zz]a{IcXhWuIdMQjJ]lwmGQ|]g~c]Hl]pl`Pd^?loIcsoNir_kikBYyg?NarXZEGYspt_vLBIoj}LI[uBFvm}tbqvC|xyR~a{kob|HlctZslTGtPDhBKsNsoZPuH`U`Fqg{gKnGSHVLJ^O`zmNgMn~{rsQuoymw^JY?iUBvw_~mMr|GrPHTERS[MiNpY[Mm{ggHpzRaJaoFomtdaQ_?xuTRm}@KjU~RtPsAdxa|uHmy}n^i||FVL[eQAPrWfLm^ndczgF~Nk~aplQvTUpHvnTya]kOenZlLAQIm{lPl@CCTchvCF[fI{^zPkeYZTiamoEcKmBMfZhk_j_~Fjp|wPVZlkh_nHu]@tP|hS@^G^PdsQ~f[RqgTDqezxNFcaO}HZhb|MMiNSYSAnQWCDJukT~e|OTgc}sf[cnr?fyzTa|EwEtRG|I~|IO}O]S|rp]CQ}}DWhSjC_|z|oY|FYl@WkCOoPuWuqr{fJu?Brs^_EBI[@_OCKs}?]O`jnDiXBvaIWhhMAQDNb{U`bqVR}oqVAvR@AZHEBY@depD]OLh`kf^UsHhzKT}CS}HQKy}Q~AeMydXPQztWSSzDnghULQgMAmbWIZ|lWWeEXrE^EeNoZApooEmrXe{NAnoDf`m}UNlRdqQ@jOc~HLOMWs]IDqJHYoMziEedGBPOxOb?[X`KxkFRg@`mgFYnP{hSaxwZfBQqTm}_?RSEaQga]w[vxc]hMne}VfSlqUeMo_iqmd`ilnJXnhdj^EEFifvZyxYFRf^VaqBhLyrGlk~qowqzHOBlOwtx?i{m~`n^G?Yxzxux}b{LSlx]dS~thO^lYE}bzKmUEzwW^{rPGhbEov[Plv??xtyKJshbG`KuO?hjBdS@Ru}iGpvFXJRrvOlrKN?`I_n_tplk}kgwSXuKylXbRQ]]?a|{xiT[li?k]CJpwy^o@ebyGQrPfF`aszGKp]baIx~H?ElETtFh]dz[OjGl@C?]VDhr}OE@V]wLTc[WErXacM{We`F|utKKjgllAxvsVYBZ@HcuMgLboFHVZmi}eIXAIFhS@A@FGRbjeoJWZ_NKd^oEH`qgy`q[Tq{x?LRP|GfBFFJV|fgZs`MLbpPYUdIV^]mD@FG]pYAT^A^RNCcXVrPsgk{jTrAIQPs_`mD}rOqAZA[}RETFz]WkXFTz_m{N@{W@_fPKZLT`@aIqf|L^Mb|crNqZ{BVsijzpGPEKQQZGlApDn`ruH}cvF|iXcNqK}cxe_U~HRnKV}sCYb`D~oGvwG[Ca|UaybXea~DdD~LiIbGRxJ_VGheI{ika}KC[OZJLn^IBkPrQj_EuoFwZ}DpoBRcK]Q}?EmTv~i_Tul{bky?Iit~tgS|o}JL_VYcCQdjeJ_MfaA`FgCgc[Ii|CBHwq~nbJeYTK{e`CNstKfTKPzw{jdhp|qsZyP_FcugxCFNpKitlR~vUrx^NrSVsSTaEgnxZTmKc`R|lGJeX}ccKLsQZQhsFkeFd|ckHIVTlGMg`~uPwuHRJS_CPuN_ogXe{Ba}dO_UBhuNXby|h?JlgBIqMKx^_u{molgL[W_iavNQuOq?ap]PGB`clAicnl@k~pA?MWHEZ{HuTLsCpOxxrKlBh]FyMjLdFl|nMIvTHyGAlPogqfZ?PlvlFJvYnDQd}R@uAhtJmDfe|iJqdkYr}r@mEjjIetDl_I`TELfoR|qTBu@Tic[BaXjP?dCS~MUK[HPRI}OUOwAaf|_}HZzrwXvbnNgltjTwkBE~MztTQhtRSWoQHajMoVyBBA`kdgK~h`o[J`dm~pm]tk@i`[F~F]DBlJKklrkR]SNw@{aG~Vhl`KINsQkOy?WhcqUMTGDOM_]bUjVd|Yh_KUCCgIJ|LDIGZCPls{RzbVWVLEhHvWBzKq|^N?DyJB|__aCUjoEgsARki}j@DQXS`RNU|DJ^a~d{sh_Iu{ONcUtSrGWW@cvUjefHHi}eSSGrNtO?cTPBShLqzwMVjWQQCCFB^culBjZHEK_{dO~Q`YhJYFn]jq~XSnG@[lQr]eKrjXpG~L^h~tDgEma^AUFThlaR{xyuP@[^VFwXSeUbVetufa@dX]CLyAnDV@Bs[DnpeghJw^?UIana}r_CKGDySoRudklbgio}kIDpA@McDoPK?iYcG?_zOmnWfJp}a[JLR[stXMo?_^Ng[whQlrDbrawZeSZ~SJstIObdDSfAA{MV}?gNunLOnbMv_~KFQUAjIMj^GkoGxuYtYbGDImEYiwEMyTpMxN_LSnSMdl{bg@dtAnAMvhDTBR_FxoQgANniRqxd`pWv@rFJ|mWNWmh[GMJz_Nq`BIN@KsjMPASXORcdHjf~rJfgZYe_uulzqM_KdPlMsuvU^YJuLtofPhGonVOQxCMuXliNvJIaoC?hSxcxKVVxWlNs^ENDvCtSmO~WxI[itnjs^RDvI@KqG}YekaSbTaB]ki]XM@[ZnDAP~@|BzLRgOzmjmPkRE@_sobkT|SszXK[rZN?F]Z_u}Yue^[BZgLtR}FHzWyxWEX^wXC]MJmiVbQuBzkgRcKGUhOvUc_bga|Tx`KEM`JWEgTpFYVeXLCm|mctZR@uKTDeUONPozBeIkrY`cz]]~WPGMUf`MNUGHDbxZuO{gmsKYkAGRPqjc|_FtblEOwy}dnwCHo]PJhN~JoteaJ?dmYZeB^Xd?X^pOKDbOMF@Ugg^hETLdhwlA}PL@_ur|o{VZosP?ntJ_kG][g{Zq`Tu]dzQlSWiKfnxDnk}KOzp~tdFstMobmy[oPYjyOtUzMWdjcNSUAjRuqhLS@AwB^{BFnqjCmmlk?jpn}TksS{KcKkDboXiwK]qMVjm~V`LgWhjS^nLGwfhAYrjDSBL_{cRus~{?xar_xqPlArrYFd?pHKdMEZzzjJpfC?Hv}mAuIDkyBxFpxhstTx`IO{rp}XGuQ]VtbHerlRc_LFGWK[XluFcNGUtDYMZny[M^nVKVeMllQI[xtvwQnXFlWYqxZZFp_|]^oWX[{pOMpxXxvkbyJA[DrPzwD|LW|QcV{Nw~U^dgguSpG]ClmO@j_TENIGjPWwgdVbHganhM?ema|dBaqla|WBd`poj~klxaasKxGG^xbWquAl~_lKWxUkDFagMnE{zHug{b`A~IYcQYBF_E}wiA}K@yxWHrZ{[d~|ARsYsjeNWzkMs~IOqqp[yzDE|WFrivsidTcnbHFRoW@XpAV`lv_zj?B~tPCppRjgbbDTALeFaOf?VcjnKTQMLyp{NwdylHCqmo?oelhjWuXj~}{fpuX`fra?GNkDiChYgVSh{R[BgF~eQa^WVz}ATI_CpY?g_diae]|ijH`TyNIF}|D_xpmBq_JpKih{Ba|sWzhnAoyraiDvk`h{qbBfsylBGmRH}DRPdryEsSaKS~tIaeF[s]I~xxHVrcNe@Jjxa@jlhZueLQqHh_]twVMqG_EGuwyab{nxOF?`HCle}nBZzlTQjkLmoXbXhOtBglFoMz?eqre`HiE@vNwBulglmQjj]DB@pPkPUgA^sjOAUNdSu_`oAzar?n?eMnw{{hYmslYi[TnlJD'",...']charCodeAtUinyxpf',"for(;e<10359;c[e++]=p-=128,A=A?p-A&&A:p==34&&p)for(p=1;p<128;y=f.map((n,x)=>(U=r[n]*2+1,U=Math.log(U/(h-U)),t-=a[x]*U,U/500)),t=~-h/(1+Math.exp(t))|1,i=o%h<t,o=o%h+(i?t:h-t)*(o>>17)-!i*t,f.map((n,x)=>(U=r[n]+=(i*h/2-r[n]<<13)/((C[n]+=C[n]<5)+1/20)>>13,a[x]+=y[x]*(i-t/h))),p=p*2+i)for(f='010202103203210431053105410642065206541'.split(t=0).map((n,x)=>(U=0,[...n].map((n,x)=>(U=U*997+(c[e-n]|0)|0)),h*32-1&U*997+p+!!A*129)*12+x);o<h*32;o=o*64|M.charCodeAt(d++)&63);for(C=String.fromCharCode(...c);r=/[\0-#?@\\\\~]/.exec(C);)with(C.split(r))C=join(shift());return C")([],[],1<<17,[0,0,0,0,0,0,0,0,0,0,0,0],new Uint16Array(51e6).fill(1<<15),new Uint8Array(51e6),0,0,0,0));
|
|
3680
|
+
}
|
|
3681
|
+
|
|
3661
3682
|
this.app_id = app_id;
|
|
3662
3683
|
this.cipher = cipher;
|
|
3663
3684
|
this.host = location ? location.hostname : '';
|
|
3664
3685
|
|
|
3665
|
-
// create an instance of CryptoJS for encrypted calls
|
|
3666
|
-
cipher && (this.cryptoJS = CryptoJS());
|
|
3667
|
-
|
|
3668
3686
|
// get session id from url search params
|
|
3669
3687
|
const url = new URL(location.href);
|
|
3670
3688
|
this.session_id = url.searchParams.get('ngio_session_id') || 0;
|
|
@@ -3767,12 +3785,6 @@ class Newgrounds
|
|
|
3767
3785
|
return xmlHttp.responseText && JSON.parse(xmlHttp.responseText);
|
|
3768
3786
|
}
|
|
3769
3787
|
}
|
|
3770
|
-
|
|
3771
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
3772
|
-
// Crypto-JS - https://github.com/brix/crypto-js [The MIT License (MIT)]
|
|
3773
|
-
// Copyright (c) 2009-2013 Jeff Mott Copyright (c) 2013-2016 Evan Vosberg
|
|
3774
|
-
|
|
3775
|
-
const CryptoJS=()=>eval(Function("[M='GBMGXz^oVYPPKKbB`agTXU|LxPc_ZBcMrZvCr~wyGfWrwk@ATqlqeTp^N?p{we}jIpEnB_sEr`l?YDkDhWhprc|Er|XETG?pTl`e}dIc[_N~}fzRycIfpW{HTolvoPB_FMe_eH~BTMx]yyOhv?biWPCGc]kABencBhgERHGf{OL`Dj`c^sh@canhy[secghiyotcdOWgO{tJIE^JtdGQRNSCrwKYciZOa]Y@tcRATYKzv|sXpboHcbCBf`}SKeXPFM|RiJsSNaIb]QPc[D]Jy_O^XkOVTZep`ONmntLL`Qz~UupHBX_Ia~WX]yTRJIxG`ioZ{fefLJFhdyYoyLPvqgH?b`[TMnTwwfzDXhfM?rKs^aFr|nyBdPmVHTtAjXoYUloEziWDCw_suyYT~lSMksI~ZNCS[Bex~j]Vz?kx`gdYSEMCsHpjbyxQvw|XxX_^nQYue{sBzVWQKYndtYQMWRef{bOHSfQhiNdtR{o?cUAHQAABThwHPT}F{VvFmgN`E@FiFYS`UJmpQNM`X|tPKHlccT}z}k{sACHL?Rt@MkWplxO`ASgh?hBsuuP|xD~LSH~KBlRs]t|l|_tQAroDRqWS^SEr[sYdPB}TAROtW{mIkE|dWOuLgLmJrucGLpebrAFKWjikTUzS|j}M}szasKOmrjy[?hpwnEfX[jGpLt@^v_eNwSQHNwtOtDgWD{rk|UgASs@mziIXrsHN_|hZuxXlPJOsA^^?QY^yGoCBx{ekLuZzRqQZdsNSx@ezDAn{XNj@fRXIwrDX?{ZQHwTEfu@GhxDOykqts|n{jOeZ@c`dvTY?e^]ATvWpb?SVyg]GC?SlzteilZJAL]mlhLjYZazY__qcVFYvt@|bIQnSno@OXyt]OulzkWqH`rYFWrwGs`v|~XeTsIssLrbmHZCYHiJrX}eEzSssH}]l]IhPQhPoQ}rCXLyhFIT[clhzYOvyHqigxmjz`phKUU^TPf[GRAIhNqSOdayFP@FmKmuIzMOeoqdpxyCOwCthcLq?n`L`tLIBboNn~uXeFcPE{C~mC`h]jUUUQe^`UqvzCutYCgct|SBrAeiYQW?X~KzCz}guXbsUw?pLsg@hDArw?KeJD[BN?GD@wgFWCiHq@Ypp_QKFixEKWqRp]oJFuVIEvjDcTFu~Zz]a{IcXhWuIdMQjJ]lwmGQ|]g~c]Hl]pl`Pd^?loIcsoNir_kikBYyg?NarXZEGYspt_vLBIoj}LI[uBFvm}tbqvC|xyR~a{kob|HlctZslTGtPDhBKsNsoZPuH`U`Fqg{gKnGSHVLJ^O`zmNgMn~{rsQuoymw^JY?iUBvw_~mMr|GrPHTERS[MiNpY[Mm{ggHpzRaJaoFomtdaQ_?xuTRm}@KjU~RtPsAdxa|uHmy}n^i||FVL[eQAPrWfLm^ndczgF~Nk~aplQvTUpHvnTya]kOenZlLAQIm{lPl@CCTchvCF[fI{^zPkeYZTiamoEcKmBMfZhk_j_~Fjp|wPVZlkh_nHu]@tP|hS@^G^PdsQ~f[RqgTDqezxNFcaO}HZhb|MMiNSYSAnQWCDJukT~e|OTgc}sf[cnr?fyzTa|EwEtRG|I~|IO}O]S|rp]CQ}}DWhSjC_|z|oY|FYl@WkCOoPuWuqr{fJu?Brs^_EBI[@_OCKs}?]O`jnDiXBvaIWhhMAQDNb{U`bqVR}oqVAvR@AZHEBY@depD]OLh`kf^UsHhzKT}CS}HQKy}Q~AeMydXPQztWSSzDnghULQgMAmbWIZ|lWWeEXrE^EeNoZApooEmrXe{NAnoDf`m}UNlRdqQ@jOc~HLOMWs]IDqJHYoMziEedGBPOxOb?[X`KxkFRg@`mgFYnP{hSaxwZfBQqTm}_?RSEaQga]w[vxc]hMne}VfSlqUeMo_iqmd`ilnJXnhdj^EEFifvZyxYFRf^VaqBhLyrGlk~qowqzHOBlOwtx?i{m~`n^G?Yxzxux}b{LSlx]dS~thO^lYE}bzKmUEzwW^{rPGhbEov[Plv??xtyKJshbG`KuO?hjBdS@Ru}iGpvFXJRrvOlrKN?`I_n_tplk}kgwSXuKylXbRQ]]?a|{xiT[li?k]CJpwy^o@ebyGQrPfF`aszGKp]baIx~H?ElETtFh]dz[OjGl@C?]VDhr}OE@V]wLTc[WErXacM{We`F|utKKjgllAxvsVYBZ@HcuMgLboFHVZmi}eIXAIFhS@A@FGRbjeoJWZ_NKd^oEH`qgy`q[Tq{x?LRP|GfBFFJV|fgZs`MLbpPYUdIV^]mD@FG]pYAT^A^RNCcXVrPsgk{jTrAIQPs_`mD}rOqAZA[}RETFz]WkXFTz_m{N@{W@_fPKZLT`@aIqf|L^Mb|crNqZ{BVsijzpGPEKQQZGlApDn`ruH}cvF|iXcNqK}cxe_U~HRnKV}sCYb`D~oGvwG[Ca|UaybXea~DdD~LiIbGRxJ_VGheI{ika}KC[OZJLn^IBkPrQj_EuoFwZ}DpoBRcK]Q}?EmTv~i_Tul{bky?Iit~tgS|o}JL_VYcCQdjeJ_MfaA`FgCgc[Ii|CBHwq~nbJeYTK{e`CNstKfTKPzw{jdhp|qsZyP_FcugxCFNpKitlR~vUrx^NrSVsSTaEgnxZTmKc`R|lGJeX}ccKLsQZQhsFkeFd|ckHIVTlGMg`~uPwuHRJS_CPuN_ogXe{Ba}dO_UBhuNXby|h?JlgBIqMKx^_u{molgL[W_iavNQuOq?ap]PGB`clAicnl@k~pA?MWHEZ{HuTLsCpOxxrKlBh]FyMjLdFl|nMIvTHyGAlPogqfZ?PlvlFJvYnDQd}R@uAhtJmDfe|iJqdkYr}r@mEjjIetDl_I`TELfoR|qTBu@Tic[BaXjP?dCS~MUK[HPRI}OUOwAaf|_}HZzrwXvbnNgltjTwkBE~MztTQhtRSWoQHajMoVyBBA`kdgK~h`o[J`dm~pm]tk@i`[F~F]DBlJKklrkR]SNw@{aG~Vhl`KINsQkOy?WhcqUMTGDOM_]bUjVd|Yh_KUCCgIJ|LDIGZCPls{RzbVWVLEhHvWBzKq|^N?DyJB|__aCUjoEgsARki}j@DQXS`RNU|DJ^a~d{sh_Iu{ONcUtSrGWW@cvUjefHHi}eSSGrNtO?cTPBShLqzwMVjWQQCCFB^culBjZHEK_{dO~Q`YhJYFn]jq~XSnG@[lQr]eKrjXpG~L^h~tDgEma^AUFThlaR{xyuP@[^VFwXSeUbVetufa@dX]CLyAnDV@Bs[DnpeghJw^?UIana}r_CKGDySoRudklbgio}kIDpA@McDoPK?iYcG?_zOmnWfJp}a[JLR[stXMo?_^Ng[whQlrDbrawZeSZ~SJstIObdDSfAA{MV}?gNunLOnbMv_~KFQUAjIMj^GkoGxuYtYbGDImEYiwEMyTpMxN_LSnSMdl{bg@dtAnAMvhDTBR_FxoQgANniRqxd`pWv@rFJ|mWNWmh[GMJz_Nq`BIN@KsjMPASXORcdHjf~rJfgZYe_uulzqM_KdPlMsuvU^YJuLtofPhGonVOQxCMuXliNvJIaoC?hSxcxKVVxWlNs^ENDvCtSmO~WxI[itnjs^RDvI@KqG}YekaSbTaB]ki]XM@[ZnDAP~@|BzLRgOzmjmPkRE@_sobkT|SszXK[rZN?F]Z_u}Yue^[BZgLtR}FHzWyxWEX^wXC]MJmiVbQuBzkgRcKGUhOvUc_bga|Tx`KEM`JWEgTpFYVeXLCm|mctZR@uKTDeUONPozBeIkrY`cz]]~WPGMUf`MNUGHDbxZuO{gmsKYkAGRPqjc|_FtblEOwy}dnwCHo]PJhN~JoteaJ?dmYZeB^Xd?X^pOKDbOMF@Ugg^hETLdhwlA}PL@_ur|o{VZosP?ntJ_kG][g{Zq`Tu]dzQlSWiKfnxDnk}KOzp~tdFstMobmy[oPYjyOtUzMWdjcNSUAjRuqhLS@AwB^{BFnqjCmmlk?jpn}TksS{KcKkDboXiwK]qMVjm~V`LgWhjS^nLGwfhAYrjDSBL_{cRus~{?xar_xqPlArrYFd?pHKdMEZzzjJpfC?Hv}mAuIDkyBxFpxhstTx`IO{rp}XGuQ]VtbHerlRc_LFGWK[XluFcNGUtDYMZny[M^nVKVeMllQI[xtvwQnXFlWYqxZZFp_|]^oWX[{pOMpxXxvkbyJA[DrPzwD|LW|QcV{Nw~U^dgguSpG]ClmO@j_TENIGjPWwgdVbHganhM?ema|dBaqla|WBd`poj~klxaasKxGG^xbWquAl~_lKWxUkDFagMnE{zHug{b`A~IYcQYBF_E}wiA}K@yxWHrZ{[d~|ARsYsjeNWzkMs~IOqqp[yzDE|WFrivsidTcnbHFRoW@XpAV`lv_zj?B~tPCppRjgbbDTALeFaOf?VcjnKTQMLyp{NwdylHCqmo?oelhjWuXj~}{fpuX`fra?GNkDiChYgVSh{R[BgF~eQa^WVz}ATI_CpY?g_diae]|ijH`TyNIF}|D_xpmBq_JpKih{Ba|sWzhnAoyraiDvk`h{qbBfsylBGmRH}DRPdryEsSaKS~tIaeF[s]I~xxHVrcNe@Jjxa@jlhZueLQqHh_]twVMqG_EGuwyab{nxOF?`HCle}nBZzlTQjkLmoXbXhOtBglFoMz?eqre`HiE@vNwBulglmQjj]DB@pPkPUgA^sjOAUNdSu_`oAzar?n?eMnw{{hYmslYi[TnlJD'",...']charCodeAtUinyxpf',"for(;e<10359;c[e++]=p-=128,A=A?p-A&&A:p==34&&p)for(p=1;p<128;y=f.map((n,x)=>(U=r[n]*2+1,U=Math.log(U/(h-U)),t-=a[x]*U,U/500)),t=~-h/(1+Math.exp(t))|1,i=o%h<t,o=o%h+(i?t:h-t)*(o>>17)-!i*t,f.map((n,x)=>(U=r[n]+=(i*h/2-r[n]<<13)/((C[n]+=C[n]<5)+1/20)>>13,a[x]+=y[x]*(i-t/h))),p=p*2+i)for(f='010202103203210431053105410642065206541'.split(t=0).map((n,x)=>(U=0,[...n].map((n,x)=>(U=U*997+(c[e-n]|0)|0)),h*32-1&U*997+p+!!A*129)*12+x);o<h*32;o=o*64|M.charCodeAt(d++)&63);for(C=String.fromCharCode(...c);r=/[\0-#?@\\\\~]/.exec(C);)with(C.split(r))C=join(shift());return C")([],[],1<<17,[0,0,0,0,0,0,0,0,0,0,0,0],new Uint16Array(51e6).fill(1<<15),new Uint8Array(51e6),0,0,0,0));
|
|
3776
3788
|
/**
|
|
3777
3789
|
* LittleJS WebGL Interface
|
|
3778
3790
|
* <br> - All webgl used by the engine is wrapped up here
|
|
@@ -3802,7 +3814,7 @@ let glContext;
|
|
|
3802
3814
|
let glTileTexture;
|
|
3803
3815
|
|
|
3804
3816
|
// WebGL internal variables not exposed to documentation
|
|
3805
|
-
let glActiveTexture, glShader, glArrayBuffer,
|
|
3817
|
+
let glActiveTexture, glShader, glArrayBuffer, glPositionData, glColorData, glBatchCount, glBatchAdditive, glAdditive;
|
|
3806
3818
|
|
|
3807
3819
|
///////////////////////////////////////////////////////////////////////////////
|
|
3808
3820
|
|
|
@@ -3812,7 +3824,6 @@ function glInit()
|
|
|
3812
3824
|
// create the canvas and tile texture
|
|
3813
3825
|
glCanvas = document.createElement('canvas');
|
|
3814
3826
|
glContext = glCanvas.getContext('webgl', {antialias: false});
|
|
3815
|
-
glCanvas.style = styleCanvas;
|
|
3816
3827
|
glTileTexture = glCreateTexture(tileImage);
|
|
3817
3828
|
|
|
3818
3829
|
// some browsers are much faster without copying the gl buffer so we just overlay it instead
|
|
@@ -3824,27 +3835,25 @@ function glInit()
|
|
|
3824
3835
|
'uniform mat4 m;'+ // transform matrix
|
|
3825
3836
|
'attribute vec2 p,t;'+ // position, uv
|
|
3826
3837
|
'attribute vec4 c,a;'+ // color, additiveColor
|
|
3827
|
-
'varying
|
|
3828
|
-
'varying vec4 d,e;'+ // return color, additiveColor
|
|
3838
|
+
'varying vec4 v,d,e;'+ // return uv, color, additiveColor
|
|
3829
3839
|
'void main(){'+ // shader entry point
|
|
3830
3840
|
'gl_Position=m*vec4(p,1,1);'+ // transform position
|
|
3831
|
-
'v=t;d=c;e=a;'+
|
|
3841
|
+
'v=vec4(t,p);d=c;e=a;'+ // pass stuff to fragment shader
|
|
3832
3842
|
'}' // end of shader
|
|
3833
3843
|
,
|
|
3834
|
-
'precision highp float;'+
|
|
3835
|
-
'varying
|
|
3836
|
-
'
|
|
3837
|
-
'
|
|
3838
|
-
'
|
|
3839
|
-
'
|
|
3840
|
-
'}' // end of shader
|
|
3844
|
+
'precision highp float;'+ // use highp for better accuracy
|
|
3845
|
+
'varying vec4 v,d,e;'+ // uv, color, additiveColor
|
|
3846
|
+
'uniform sampler2D s;'+ // texture
|
|
3847
|
+
'void main(){'+ // shader entry point
|
|
3848
|
+
'gl_FragColor=texture2D(s,v.xy)*d+e;'+ // modulate texture by color plus additive
|
|
3849
|
+
'}' // end of shader
|
|
3841
3850
|
);
|
|
3842
3851
|
|
|
3843
3852
|
// init buffers
|
|
3844
|
-
|
|
3853
|
+
const vertexData = new ArrayBuffer(gl_VERTEX_BUFFER_SIZE);
|
|
3845
3854
|
glArrayBuffer = glContext.createBuffer();
|
|
3846
|
-
glPositionData = new Float32Array(
|
|
3847
|
-
glColorData = new Uint32Array(
|
|
3855
|
+
glPositionData = new Float32Array(vertexData);
|
|
3856
|
+
glColorData = new Uint32Array(vertexData);
|
|
3848
3857
|
glBatchCount = 0;
|
|
3849
3858
|
}
|
|
3850
3859
|
|
|
@@ -3919,18 +3928,19 @@ function glCreateTexture(image)
|
|
|
3919
3928
|
image && image.width && glContext.texImage2D(gl_TEXTURE_2D, 0, gl_RGBA, gl_RGBA, gl_UNSIGNED_BYTE, image);
|
|
3920
3929
|
|
|
3921
3930
|
// use point filtering for pixelated rendering
|
|
3922
|
-
|
|
3923
|
-
glContext.texParameteri(gl_TEXTURE_2D,
|
|
3931
|
+
const filter = cavasPixelated ? gl_NEAREST : gl_LINEAR;
|
|
3932
|
+
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, filter);
|
|
3933
|
+
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, filter);
|
|
3924
3934
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE);
|
|
3925
3935
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE);
|
|
3926
3936
|
return texture;
|
|
3927
3937
|
}
|
|
3928
3938
|
|
|
3929
3939
|
// called automatically by engine before render
|
|
3930
|
-
function glPreRender(
|
|
3940
|
+
function glPreRender()
|
|
3931
3941
|
{
|
|
3932
3942
|
// clear and set to same size as main canvas
|
|
3933
|
-
glContext.viewport(0, 0, glCanvas.width = width, glCanvas.height = height);
|
|
3943
|
+
glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
|
|
3934
3944
|
glContext.clear(gl_COLOR_BUFFER_BIT);
|
|
3935
3945
|
|
|
3936
3946
|
// set up the shader
|
|
@@ -3938,7 +3948,7 @@ function glPreRender(width, height, cameraX, cameraY, cameraScale)
|
|
|
3938
3948
|
glContext.activeTexture(gl_TEXTURE0);
|
|
3939
3949
|
glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = glTileTexture);
|
|
3940
3950
|
glContext.bindBuffer(gl_ARRAY_BUFFER, glArrayBuffer);
|
|
3941
|
-
glContext.bufferData(gl_ARRAY_BUFFER,
|
|
3951
|
+
glContext.bufferData(gl_ARRAY_BUFFER, gl_VERTEX_BUFFER_SIZE, gl_DYNAMIC_DRAW);
|
|
3942
3952
|
glSetBlendMode();
|
|
3943
3953
|
|
|
3944
3954
|
// set vertex attributes
|
|
@@ -3956,14 +3966,14 @@ function glPreRender(width, height, cameraX, cameraY, cameraScale)
|
|
|
3956
3966
|
initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
|
|
3957
3967
|
|
|
3958
3968
|
// build the transform matrix
|
|
3959
|
-
const sx = 2 * cameraScale / width;
|
|
3960
|
-
const sy = 2 * cameraScale / height;
|
|
3969
|
+
const sx = 2 * cameraScale / mainCanvas.width;
|
|
3970
|
+
const sy = 2 * cameraScale / mainCanvas.height;
|
|
3961
3971
|
glContext.uniformMatrix4fv(glContext.getUniformLocation(glShader, 'm'), 0,
|
|
3962
3972
|
new Float32Array([
|
|
3963
3973
|
sx, 0, 0, 0,
|
|
3964
3974
|
0, sy, 0, 0,
|
|
3965
3975
|
1, 1, -1, 1,
|
|
3966
|
-
-1-sx*
|
|
3976
|
+
-1-sx*cameraPos.x, -1-sy*cameraPos.y, 0, 0
|
|
3967
3977
|
])
|
|
3968
3978
|
);
|
|
3969
3979
|
}
|
|
@@ -4011,10 +4021,10 @@ function glCopyToContext(context, forceDraw)
|
|
|
4011
4021
|
* @param uv0Y
|
|
4012
4022
|
* @param uv1X
|
|
4013
4023
|
* @param uv1Y
|
|
4014
|
-
* @param
|
|
4024
|
+
* @param rgba
|
|
4015
4025
|
* @param [rgbaAdditive=0]
|
|
4016
4026
|
* @memberof WebGL */
|
|
4017
|
-
function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba
|
|
4027
|
+
function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdditive=0)
|
|
4018
4028
|
{
|
|
4019
4029
|
// flush if there is no room for more verts or if different blend mode
|
|
4020
4030
|
if (glBatchCount == gl_MAX_BATCH || glBatchAdditive != glAdditive)
|
|
@@ -4025,43 +4035,16 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba=0xffffff
|
|
|
4025
4035
|
const cx = c*sizeX, cy = c*sizeY, sx = s*sizeX, sy = s*sizeY;
|
|
4026
4036
|
|
|
4027
4037
|
// setup 2 triangles to form a quad
|
|
4028
|
-
let offset = glBatchCount++ * gl_VERTICES_PER_QUAD * gl_INDICIES_PER_VERT;
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
glPositionData[offset++] = y + cy - sx;
|
|
4039
|
-
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv0Y;
|
|
4040
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
4041
|
-
|
|
4042
|
-
// vertex 2
|
|
4043
|
-
glPositionData[offset++] = x - cx + sy;
|
|
4044
|
-
glPositionData[offset++] = y + cy + sx;
|
|
4045
|
-
glPositionData[offset++] = uv0X; glPositionData[offset++] = uv0Y;
|
|
4046
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
4047
|
-
|
|
4048
|
-
// vertex 0
|
|
4049
|
-
glPositionData[offset++] = x - cx - sy;
|
|
4050
|
-
glPositionData[offset++] = y - cy + sx;
|
|
4051
|
-
glPositionData[offset++] = uv0X; glPositionData[offset++] = uv1Y;
|
|
4052
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
4053
|
-
|
|
4054
|
-
// vertex 3
|
|
4055
|
-
glPositionData[offset++] = x + cx - sy;
|
|
4056
|
-
glPositionData[offset++] = y - cy - sx;
|
|
4057
|
-
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv1Y;
|
|
4058
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
4059
|
-
|
|
4060
|
-
// vertex 1
|
|
4061
|
-
glPositionData[offset++] = x + cx + sy;
|
|
4062
|
-
glPositionData[offset++] = y + cy - sx;
|
|
4063
|
-
glPositionData[offset++] = uv1X; glPositionData[offset++] = uv0Y;
|
|
4064
|
-
glColorData[offset++] = rgba; glColorData[offset++] = rgbaAdditive;
|
|
4038
|
+
for(let i=6, offset = glBatchCount++ * gl_VERTICES_PER_QUAD * gl_INDICIES_PER_VERT; i--;)
|
|
4039
|
+
{
|
|
4040
|
+
const a = i-4&&i>1, b = i-5&&i-2&&i-1;
|
|
4041
|
+
glPositionData[offset++] = x + (a?-cx:cx) + (b?sy:-sy);
|
|
4042
|
+
glPositionData[offset++] = y + (b?cy:-cy) + (a?sx:-sx);
|
|
4043
|
+
glPositionData[offset++] = a ? uv0X : uv1X;
|
|
4044
|
+
glPositionData[offset++] = b ? uv0Y : uv1Y;
|
|
4045
|
+
glColorData[offset++] = rgba;
|
|
4046
|
+
glColorData[offset++] = rgbaAdditive;
|
|
4047
|
+
}
|
|
4065
4048
|
}
|
|
4066
4049
|
|
|
4067
4050
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -4113,14 +4096,13 @@ function glRenderPostProcess()
|
|
|
4113
4096
|
return;
|
|
4114
4097
|
|
|
4115
4098
|
// prepare to render post process shader
|
|
4116
|
-
const width = mainCanvas.width, height = mainCanvas.height;
|
|
4117
4099
|
if (glEnable)
|
|
4118
4100
|
{
|
|
4119
4101
|
glFlush(); // clear out the buffer
|
|
4120
4102
|
mainContext.drawImage(glCanvas, 0, 0); // copy to the main canvas
|
|
4121
4103
|
}
|
|
4122
|
-
else
|
|
4123
|
-
glContext.viewport(0, 0, glCanvas.width = width, glCanvas.height = height);
|
|
4104
|
+
else // set viewport
|
|
4105
|
+
glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
|
|
4124
4106
|
|
|
4125
4107
|
// setup shader program to draw one triangle
|
|
4126
4108
|
glContext.useProgram(glPostShader);
|
|
@@ -4144,7 +4126,7 @@ function glRenderPostProcess()
|
|
|
4144
4126
|
const uniformLocation = (name)=>glContext.getUniformLocation(glPostShader, name);
|
|
4145
4127
|
glContext.uniform1i(uniformLocation('iChannel0'), 0);
|
|
4146
4128
|
glContext.uniform1f(uniformLocation('iTime'), time);
|
|
4147
|
-
glContext.uniform3f(uniformLocation('iResolution'), width, height, 1);
|
|
4129
|
+
glContext.uniform3f(uniformLocation('iResolution'), mainCanvas.width, mainCanvas.height, 1);
|
|
4148
4130
|
glContext.drawArrays(gl_TRIANGLES, 0, 3);
|
|
4149
4131
|
}
|
|
4150
4132
|
|
|
@@ -4184,7 +4166,8 @@ gl_UNPACK_FLIP_Y_WEBGL = 37440,
|
|
|
4184
4166
|
gl_VERTICES_PER_QUAD = 6,
|
|
4185
4167
|
gl_INDICIES_PER_VERT = 6,
|
|
4186
4168
|
gl_MAX_BATCH = 1<<16,
|
|
4187
|
-
gl_VERTEX_BYTE_STRIDE = (4 * 2) * 2 + (4) * 2
|
|
4169
|
+
gl_VERTEX_BYTE_STRIDE = (4 * 2) * 2 + (4) * 2, // vec2 * 2 + (char * 4) * 2
|
|
4170
|
+
gl_VERTEX_BUFFER_SIZE = gl_MAX_BATCH * gl_VERTICES_PER_QUAD * gl_VERTEX_BYTE_STRIDE;
|
|
4188
4171
|
/*
|
|
4189
4172
|
LittleJS - The Tiny JavaScript Game Engine That Can!
|
|
4190
4173
|
MIT License - Copyright 2021 Frank Force
|
|
@@ -4200,6 +4183,7 @@ gl_VERTEX_BYTE_STRIDE = (4 * 2) * 2 + (4) * 2; // vec2 * 2 + (char * 4) * 2
|
|
|
4200
4183
|
- Particle effect system
|
|
4201
4184
|
- Medal system tracks and displays achievements
|
|
4202
4185
|
- Debug tools and debug rendering system
|
|
4186
|
+
- Post processing effects
|
|
4203
4187
|
- Call engineInit() to start it up!
|
|
4204
4188
|
*/
|
|
4205
4189
|
|
|
@@ -4209,7 +4193,7 @@ gl_VERTEX_BYTE_STRIDE = (4 * 2) * 2 + (4) * 2; // vec2 * 2 + (char * 4) * 2
|
|
|
4209
4193
|
const engineName = 'LittleJS';
|
|
4210
4194
|
|
|
4211
4195
|
/** Version of engine */
|
|
4212
|
-
const engineVersion = '1.4.
|
|
4196
|
+
const engineVersion = '1.4.8';
|
|
4213
4197
|
|
|
4214
4198
|
/** Frames per second to update objects
|
|
4215
4199
|
* @default */
|
|
@@ -4234,18 +4218,13 @@ let time = 0;
|
|
|
4234
4218
|
/** Actual clock time since start in seconds (not affected by pause or frame rate clamping) */
|
|
4235
4219
|
let timeReal = 0;
|
|
4236
4220
|
|
|
4237
|
-
/** Is the game paused? Causes time and objects to not be updated
|
|
4221
|
+
/** Is the game paused? Causes time and objects to not be updated */
|
|
4238
4222
|
let paused = 0;
|
|
4239
4223
|
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
let averageFPS, drawCount;
|
|
4245
|
-
|
|
4246
|
-
// css text used for elements created by engine
|
|
4247
|
-
const styleBody = 'margin:0;overflow:hidden;background:#000';
|
|
4248
|
-
const styleCanvas = 'position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)';
|
|
4224
|
+
/** Set if game is paused
|
|
4225
|
+
* @param {Boolean} paused
|
|
4226
|
+
*/
|
|
4227
|
+
function setPaused(_paused) { paused = _paused; }
|
|
4249
4228
|
|
|
4250
4229
|
///////////////////////////////////////////////////////////////////////////////
|
|
4251
4230
|
|
|
@@ -4267,10 +4246,13 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4267
4246
|
debug && (tileImage.onload=()=>ASSERT(1)); // tile sheet can not reloaded
|
|
4268
4247
|
|
|
4269
4248
|
// setup html
|
|
4249
|
+
const styleBody = 'margin:0;overflow:hidden;background:#000' + // fill the window
|
|
4250
|
+
';touch-action:none' + // prevent mobile pinch to resize
|
|
4251
|
+
';user-select:none' + // prevent mobile hold to select
|
|
4252
|
+
';-webkit-user-select:none'; // compatibility for ios
|
|
4270
4253
|
document.body.style = styleBody;
|
|
4271
4254
|
document.body.appendChild(mainCanvas = document.createElement('canvas'));
|
|
4272
4255
|
mainContext = mainCanvas.getContext('2d');
|
|
4273
|
-
mainCanvas.style = styleCanvas;
|
|
4274
4256
|
|
|
4275
4257
|
// init stuff and start engine
|
|
4276
4258
|
debugInit();
|
|
@@ -4279,21 +4261,27 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4279
4261
|
// create overlay canvas for hud to appear above gl canvas
|
|
4280
4262
|
document.body.appendChild(overlayCanvas = document.createElement('canvas'));
|
|
4281
4263
|
overlayContext = overlayCanvas.getContext('2d');
|
|
4282
|
-
|
|
4264
|
+
|
|
4265
|
+
// set canvas style to fill the window
|
|
4266
|
+
const styleCanvas = 'position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)';
|
|
4267
|
+
(glCanvas||mainCanvas).style = mainCanvas.style = overlayCanvas.style = styleCanvas;
|
|
4283
4268
|
|
|
4284
4269
|
gameInit();
|
|
4285
4270
|
touchGamepadCreate();
|
|
4286
4271
|
engineUpdate();
|
|
4287
4272
|
};
|
|
4288
4273
|
|
|
4274
|
+
// frame time tracking
|
|
4275
|
+
let frameTimeLastMS = 0, frameTimeBufferMS, averageFPS;
|
|
4276
|
+
|
|
4289
4277
|
// main update loop
|
|
4290
|
-
|
|
4278
|
+
function engineUpdate(frameTimeMS=0)
|
|
4291
4279
|
{
|
|
4292
4280
|
// update time keeping
|
|
4293
4281
|
let frameTimeDeltaMS = frameTimeMS - frameTimeLastMS;
|
|
4294
4282
|
frameTimeLastMS = frameTimeMS;
|
|
4295
4283
|
if (debug || showWatermark)
|
|
4296
|
-
averageFPS = lerp(.05, averageFPS
|
|
4284
|
+
averageFPS = lerp(.05, averageFPS, 1e3/(frameTimeDeltaMS||1));
|
|
4297
4285
|
const debugSpeedUp = debug && keyIsDown(107); // +
|
|
4298
4286
|
const debugSpeedDown = debug && keyIsDown(109); // -
|
|
4299
4287
|
if (debug)
|
|
@@ -4305,24 +4293,19 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4305
4293
|
|
|
4306
4294
|
if (canvasFixedSize.x)
|
|
4307
4295
|
{
|
|
4308
|
-
// clear set fixed size
|
|
4296
|
+
// clear canvas and set fixed size
|
|
4309
4297
|
overlayCanvas.width = mainCanvas.width = canvasFixedSize.x;
|
|
4310
4298
|
overlayCanvas.height = mainCanvas.height = canvasFixedSize.y;
|
|
4311
4299
|
|
|
4312
4300
|
// fit to window by adding space on top or bottom if necessary
|
|
4313
4301
|
const aspect = innerWidth / innerHeight;
|
|
4314
4302
|
const fixedAspect = mainCanvas.width / mainCanvas.height;
|
|
4315
|
-
mainCanvas.style.width
|
|
4316
|
-
mainCanvas.style.height = overlayCanvas.style.height = aspect < fixedAspect ? '' : '100%';
|
|
4317
|
-
if (glCanvas)
|
|
4318
|
-
{
|
|
4319
|
-
glCanvas.style.width = mainCanvas.style.width;
|
|
4320
|
-
glCanvas.style.height = mainCanvas.style.height;
|
|
4321
|
-
}
|
|
4303
|
+
(glCanvas||mainCanvas).style.width = mainCanvas.style.width = overlayCanvas.style.width = aspect < fixedAspect ? '100%' : '';
|
|
4304
|
+
(glCanvas||mainCanvas).style.height = mainCanvas.style.height = overlayCanvas.style.height = aspect < fixedAspect ? '' : '100%';
|
|
4322
4305
|
}
|
|
4323
4306
|
else
|
|
4324
4307
|
{
|
|
4325
|
-
|
|
4308
|
+
// clear canvas and set size to same as window
|
|
4326
4309
|
overlayCanvas.width = mainCanvas.width = min(innerWidth, canvasMaxSize.x);
|
|
4327
4310
|
overlayCanvas.height = mainCanvas.height = min(innerHeight, canvasMaxSize.y);
|
|
4328
4311
|
}
|
|
@@ -4389,7 +4372,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4389
4372
|
overlayContext.fillStyle = '#000';
|
|
4390
4373
|
const text = engineName + ' ' + 'v' + engineVersion + ' / '
|
|
4391
4374
|
+ drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
|
|
4392
|
-
+
|
|
4375
|
+
+ (glEnable ? ' GL' : ' 2D') ;
|
|
4393
4376
|
overlayContext.fillText(text, mainCanvas.width-3, 3);
|
|
4394
4377
|
overlayContext.fillStyle = '#fff';
|
|
4395
4378
|
overlayContext.fillText(text, mainCanvas.width-2, 2);
|
|
@@ -4403,7 +4386,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4403
4386
|
tileImageSource ? tileImage.src = tileImageSource : tileImage.onload();
|
|
4404
4387
|
}
|
|
4405
4388
|
|
|
4406
|
-
//
|
|
4389
|
+
// Called automatically by engine to setup render system
|
|
4407
4390
|
function enginePreRender()
|
|
4408
4391
|
{
|
|
4409
4392
|
// save canvas size
|
|
@@ -4413,12 +4396,10 @@ function enginePreRender()
|
|
|
4413
4396
|
mainContext.imageSmoothingEnabled = !cavasPixelated;
|
|
4414
4397
|
|
|
4415
4398
|
// setup gl rendering if enabled
|
|
4416
|
-
glEnable && glPreRender(
|
|
4399
|
+
glEnable && glPreRender();
|
|
4417
4400
|
}
|
|
4418
4401
|
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
/** Calls update on each engine object (recursively if child), removes destroyed objects, and updated time */
|
|
4402
|
+
/** Update each engine object, remove destroyed objects, and update time */
|
|
4422
4403
|
function engineObjectsUpdate()
|
|
4423
4404
|
{
|
|
4424
4405
|
// get list of solid objects for physics optimzation
|
|
@@ -4482,14 +4463,15 @@ function engineObjectsCallback(pos, size, callbackFunction, objects=engineObject
|
|
|
4482
4463
|
* <br> - Export engine as a module with extra functions where necessary
|
|
4483
4464
|
*/
|
|
4484
4465
|
|
|
4485
|
-
//
|
|
4466
|
+
// Setters for all variables that devs will need to modify
|
|
4486
4467
|
const setCameraPos = (v)=> cameraPos = v;
|
|
4487
4468
|
const setCameraScale = (v)=> cameraScale = v;
|
|
4488
|
-
const setRandSeed = (v)=> randSeed = v;
|
|
4489
4469
|
const setCanvasMaxSize = (v)=> canvasMaxSize = v;
|
|
4490
4470
|
const setCanvasFixedSize = (v)=> canvasFixedSize = v;
|
|
4491
4471
|
const setCavasPixelated = (v)=> cavasPixelated = v;
|
|
4492
4472
|
const setFontDefault = (v)=> fontDefault = v;
|
|
4473
|
+
const setGlEnable = (v)=> glEnable = v;
|
|
4474
|
+
const setGlOverlay = (v)=> glOverlay = v;
|
|
4493
4475
|
const setTileSizeDefault = (v)=> tileSizeDefault = v;
|
|
4494
4476
|
const setTileFixBleedScale = (v)=> tileFixBleedScale = v;
|
|
4495
4477
|
const setObjectDefaultSize = (v)=> objectDefaultSize = v;
|
|
@@ -4502,8 +4484,6 @@ const setObjectDefaultFriction = (v)=> objectDefaultFriction = v;
|
|
|
4502
4484
|
const setObjectMaxSpeed = (v)=> objectMaxSpeed = v;
|
|
4503
4485
|
const setGravity = (v)=> gravity = v;
|
|
4504
4486
|
const setParticleEmitRateScale = (v)=> particleEmitRateScale = v;
|
|
4505
|
-
const setGlEnable = (v)=> glEnable = v;
|
|
4506
|
-
const setGlOverlay = (v)=> glOverlay = v;
|
|
4507
4487
|
const setGamepadsEnable = (v)=> gamepadsEnable = v;
|
|
4508
4488
|
const setGamepadDirectionEmulateStick = (v)=> gamepadDirectionEmulateStick = v;
|
|
4509
4489
|
const setInputWASDEmulateDirection = (v)=> inputWASDEmulateDirection = v;
|
|
@@ -4522,18 +4502,17 @@ const setMedalDisplayWidth = (v)=> medalDisplayWidth = v;
|
|
|
4522
4502
|
const setMedalDisplayHeight = (v)=> medalDisplayHeight = v;
|
|
4523
4503
|
const setMedalDisplayIconSize = (v)=> medalDisplayIconSize = v;
|
|
4524
4504
|
const setMedalsPreventUnlock = (v)=> medalsPreventUnlock = v;
|
|
4525
|
-
const setShowWatermark = (v)=> showWatermark = v;
|
|
4526
|
-
const setGodMode = (v)=> godMode = v;
|
|
4527
4505
|
|
|
4528
4506
|
export {
|
|
4529
|
-
//
|
|
4507
|
+
// Setters for global variables
|
|
4530
4508
|
setCameraPos,
|
|
4531
4509
|
setCameraScale,
|
|
4532
|
-
setRandSeed,
|
|
4533
4510
|
setCanvasMaxSize,
|
|
4534
4511
|
setCanvasFixedSize,
|
|
4535
4512
|
setCavasPixelated,
|
|
4536
4513
|
setFontDefault,
|
|
4514
|
+
setGlEnable,
|
|
4515
|
+
setGlOverlay,
|
|
4537
4516
|
setTileSizeDefault,
|
|
4538
4517
|
setTileFixBleedScale,
|
|
4539
4518
|
setObjectDefaultSize,
|
|
@@ -4546,8 +4525,6 @@ export {
|
|
|
4546
4525
|
setObjectMaxSpeed,
|
|
4547
4526
|
setGravity,
|
|
4548
4527
|
setParticleEmitRateScale,
|
|
4549
|
-
setGlEnable,
|
|
4550
|
-
setGlOverlay,
|
|
4551
4528
|
setGamepadsEnable,
|
|
4552
4529
|
setGamepadDirectionEmulateStick,
|
|
4553
4530
|
setInputWASDEmulateDirection,
|
|
@@ -4566,8 +4543,6 @@ export {
|
|
|
4566
4543
|
setMedalDisplayHeight,
|
|
4567
4544
|
setMedalDisplayIconSize,
|
|
4568
4545
|
setMedalsPreventUnlock,
|
|
4569
|
-
setShowWatermark,
|
|
4570
|
-
setGodMode,
|
|
4571
4546
|
|
|
4572
4547
|
// Settings
|
|
4573
4548
|
canvasMaxSize,
|
|
@@ -4659,6 +4634,7 @@ export {
|
|
|
4659
4634
|
randVector,
|
|
4660
4635
|
randColor,
|
|
4661
4636
|
randSeed,
|
|
4637
|
+
setRandSeed,
|
|
4662
4638
|
randSeeded,
|
|
4663
4639
|
|
|
4664
4640
|
// Utility Classes
|
|
@@ -4723,15 +4699,12 @@ export {
|
|
|
4723
4699
|
// onmousemove,
|
|
4724
4700
|
// onwheel,
|
|
4725
4701
|
// oncontextmenu,
|
|
4726
|
-
mouseToScreen,
|
|
4727
4702
|
//stickData,
|
|
4703
|
+
mouseToScreen,
|
|
4728
4704
|
gamepadsUpdate,
|
|
4729
4705
|
vibrate,
|
|
4730
4706
|
vibrateStop,
|
|
4731
4707
|
isTouchDevice,
|
|
4732
|
-
//touchGamepadTimer,
|
|
4733
|
-
touchGamepadCreate,
|
|
4734
|
-
touchGamepadRender,
|
|
4735
4708
|
|
|
4736
4709
|
// Audio
|
|
4737
4710
|
Sound,
|
|
@@ -4799,14 +4772,9 @@ export {
|
|
|
4799
4772
|
time,
|
|
4800
4773
|
timeReal,
|
|
4801
4774
|
paused,
|
|
4802
|
-
|
|
4803
|
-
//averageFPS,
|
|
4804
|
-
//drawCount,
|
|
4805
|
-
//styleBody,
|
|
4806
|
-
//styleCanvas,
|
|
4775
|
+
setPaused,
|
|
4807
4776
|
engineInit,
|
|
4808
|
-
|
|
4809
|
-
//engineObjectsUpdate,
|
|
4777
|
+
engineObjectsUpdate,
|
|
4810
4778
|
engineObjectsDestroy,
|
|
4811
4779
|
engineObjectsCallback,
|
|
4812
4780
|
};
|