littlejsengine 1.7.13 → 1.8.1
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 +27 -55
- package/build/littlejs.d.ts +253 -76
- package/build/littlejs.esm.js +644 -523
- package/build/littlejs.esm.min.js +1 -1
- package/build/littlejs.js +640 -332
- package/build/littlejs.min.js +1 -1
- package/build/littlejs.release.js +640 -332
- package/examples/breakout/game.js +17 -14
- package/examples/breakout/gameObjects.js +29 -8
- package/examples/breakout/index.html +3 -3
- package/examples/breakoutTutorial/README.md +2 -2
- package/examples/breakoutTutorial/game.js +4 -4
- package/examples/breakoutTutorial/index.html +2 -2
- package/examples/electron/build.js +2 -0
- package/examples/electron/game.js +3 -2
- package/examples/electron/index.html +2 -2
- package/examples/empty/game.js +1 -1
- package/examples/favicon.png +0 -0
- package/examples/js13k/build.js +2 -0
- package/examples/js13k/game.js +20 -15
- package/examples/js13k/index.html +14 -14
- package/examples/module/game.js +4 -3
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +19 -22
- package/examples/platformer/game.js +3 -3
- package/examples/platformer/gameEffects.js +21 -19
- package/examples/platformer/gameLevel.js +6 -6
- package/examples/platformer/gameObjects.js +18 -18
- package/examples/platformer/gamePlayer.js +4 -3
- package/examples/platformer/index.html +6 -6
- package/examples/platformer/tiles.png +0 -0
- package/examples/platformer/tilesLevel.png +0 -0
- package/examples/puzzle/game.js +10 -8
- package/examples/puzzle/index.html +2 -2
- package/examples/screenshot.jpg +0 -0
- package/examples/starter/build.js +2 -0
- package/examples/starter/game.js +32 -21
- package/examples/starter/index.html +13 -13
- package/examples/starter/tiles.png +0 -0
- package/examples/stress/index.html +2 -2
- package/examples/typescript/build.js +2 -0
- package/examples/typescript/game.js +4 -3
- package/examples/typescript/game.ts +4 -3
- package/examples/typescript/index.html +1 -1
- package/package.json +1 -1
- package/src/engine.js +59 -49
- package/src/engineAudio.js +67 -41
- package/src/engineBuild.js +23 -7
- package/src/engineDraw.js +139 -40
- package/src/engineExport.js +4 -191
- package/src/engineInput.js +22 -10
- package/src/engineMedals.js +13 -45
- package/src/engineObject.js +12 -13
- package/src/engineParticles.js +17 -17
- package/src/engineSettings.js +195 -2
- package/src/engineTileLayer.js +23 -22
- package/src/engineUtilities.js +6 -6
- package/src/engineWebGL.js +73 -74
package/build/littlejs.esm.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// LittleJS - MIT License - Copyright 2021 Frank Force
|
|
2
2
|
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* LittleJS Debug System
|
|
5
7
|
* - Press Esc to show debug overlay with mouse pick
|
|
@@ -10,7 +12,7 @@
|
|
|
10
12
|
* @namespace Debug
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
|
|
14
16
|
|
|
15
17
|
/** True if debug is enabled
|
|
16
18
|
* @type {Boolean}
|
|
@@ -418,7 +420,7 @@ function debugRender()
|
|
|
418
420
|
* @namespace Utilities
|
|
419
421
|
*/
|
|
420
422
|
|
|
421
|
-
|
|
423
|
+
|
|
422
424
|
|
|
423
425
|
/** A shortcut to get Math.PI
|
|
424
426
|
* @type {Number}
|
|
@@ -615,10 +617,10 @@ function randColor(colorA=new Color, colorB=new Color(0,0,0,1), linear)
|
|
|
615
617
|
* - Can be used to create a deterministic random number sequence
|
|
616
618
|
* @example
|
|
617
619
|
* let r = new RandomGenerator(123); // random number generator with seed 123
|
|
618
|
-
* let a = r.
|
|
619
|
-
* let b = r.
|
|
620
|
+
* let a = r.float(); // random value between 0 and 1
|
|
621
|
+
* let b = r.int(10); // random integer between 0 and 9
|
|
620
622
|
* r.seed = 123; // reset the seed
|
|
621
|
-
* let c = r.
|
|
623
|
+
* let c = r.float(); // the same value as a
|
|
622
624
|
*/
|
|
623
625
|
class RandomGenerator
|
|
624
626
|
{
|
|
@@ -647,18 +649,18 @@ class RandomGenerator
|
|
|
647
649
|
* @param {Number} valueA
|
|
648
650
|
* @param {Number} [valueB=0]
|
|
649
651
|
* @return {Number} */
|
|
650
|
-
int(valueA, valueB=0) { return Math.floor(this.
|
|
652
|
+
int(valueA, valueB=0) { return Math.floor(this.float(valueA, valueB)); }
|
|
651
653
|
|
|
652
654
|
/** Randomly returns either -1 or 1 deterministically
|
|
653
655
|
* @return {Number} */
|
|
654
|
-
sign() { return this.
|
|
656
|
+
sign() { return this.int(2) * 2 - 1; }
|
|
655
657
|
}
|
|
656
658
|
|
|
657
659
|
///////////////////////////////////////////////////////////////////////////////
|
|
658
660
|
|
|
659
661
|
/**
|
|
660
662
|
* Create a 2d vector, can take another Vector2 to copy, 2 scalars, or 1 scalar
|
|
661
|
-
* @param {Number} [x=0]
|
|
663
|
+
* @param {(Number|Vector2)} [x=0]
|
|
662
664
|
* @param {Number} [y=0]
|
|
663
665
|
* @return {Vector2}
|
|
664
666
|
* @example
|
|
@@ -1073,7 +1075,7 @@ class Timer
|
|
|
1073
1075
|
* @namespace Settings
|
|
1074
1076
|
*/
|
|
1075
1077
|
|
|
1076
|
-
|
|
1078
|
+
|
|
1077
1079
|
|
|
1078
1080
|
///////////////////////////////////////////////////////////////////////////////
|
|
1079
1081
|
// Camera settings
|
|
@@ -1142,7 +1144,7 @@ let glOverlay = 1;
|
|
|
1142
1144
|
* @memberof Settings */
|
|
1143
1145
|
let tileSizeDefault = vec2(16);
|
|
1144
1146
|
|
|
1145
|
-
/**
|
|
1147
|
+
/** How many pixels smaller to draw tiles to prevent bleeding from neighbors
|
|
1146
1148
|
* @type {Number}
|
|
1147
1149
|
* @default
|
|
1148
1150
|
* @memberof Settings */
|
|
@@ -1316,12 +1318,205 @@ let medalDisplayIconSize = 50;
|
|
|
1316
1318
|
* @type {Boolean}
|
|
1317
1319
|
* @default 0
|
|
1318
1320
|
* @memberof Settings */
|
|
1319
|
-
let medalsPreventUnlock;
|
|
1321
|
+
let medalsPreventUnlock;
|
|
1322
|
+
|
|
1323
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
1324
|
+
// Setters for global variables
|
|
1325
|
+
|
|
1326
|
+
/** Set position of camera in world space
|
|
1327
|
+
* @param {Vector2} pos
|
|
1328
|
+
* @memberof Settings */
|
|
1329
|
+
function setCameraPos(pos) { cameraPos = pos; }
|
|
1330
|
+
|
|
1331
|
+
/** Set scale of camera in world space
|
|
1332
|
+
* @param {Number} scale
|
|
1333
|
+
* @memberof Settings */
|
|
1334
|
+
function setCameraScale(scale) { cameraScale = scale; }
|
|
1335
|
+
|
|
1336
|
+
/** Set max size of the canvas
|
|
1337
|
+
* @param {Vector2} size
|
|
1338
|
+
* @memberof Settings */
|
|
1339
|
+
function setCanvasMaxSize(size) { canvasMaxSize = size; }
|
|
1340
|
+
|
|
1341
|
+
/** Set fixed size of the canvas
|
|
1342
|
+
* @param {Vector2} size
|
|
1343
|
+
* @memberof Settings */
|
|
1344
|
+
function setCanvasFixedSize(size) { canvasFixedSize = size; }
|
|
1345
|
+
|
|
1346
|
+
/** Disables anti aliasing for pixel art if true
|
|
1347
|
+
* @param {Boolean} pixelated
|
|
1348
|
+
* @memberof Settings */
|
|
1349
|
+
function setCanvasPixelated(pixelated) { canvasPixelated = pixelated; }
|
|
1350
|
+
|
|
1351
|
+
/** Set default font used for text rendering
|
|
1352
|
+
* @param {String} font
|
|
1353
|
+
* @memberof Settings */
|
|
1354
|
+
function setFontDefault(font) { fontDefault = font; }
|
|
1355
|
+
|
|
1356
|
+
/** Set if webgl rendering is enabled
|
|
1357
|
+
* @param {Boolean} enable
|
|
1358
|
+
* @memberof Settings */
|
|
1359
|
+
function setGlEnable(enable) { glEnable = enable; }
|
|
1360
|
+
|
|
1361
|
+
/** Set to not composite the WebGL canvas
|
|
1362
|
+
* @param {Boolean} overlay
|
|
1363
|
+
* @memberof Settings */
|
|
1364
|
+
function setGlOverlay(overlay) { glOverlay = overlay; }
|
|
1365
|
+
|
|
1366
|
+
/** Set default size of tiles in pixels
|
|
1367
|
+
* @param {Vector2} size
|
|
1368
|
+
* @memberof Settings */
|
|
1369
|
+
function setTileSizeDefault(size) { tileSizeDefault = size; }
|
|
1370
|
+
|
|
1371
|
+
/** Set to prevent tile bleeding from neighbors in pixels
|
|
1372
|
+
* @param {Number} scale
|
|
1373
|
+
* @memberof Settings */
|
|
1374
|
+
function setTileFixBleedScale(scale) { tileFixBleedScale = scale; }
|
|
1375
|
+
|
|
1376
|
+
/** Set if collisions between objects are enabled
|
|
1377
|
+
* @param {Boolean} enable
|
|
1378
|
+
* @memberof Settings */
|
|
1379
|
+
function setEnablePhysicsSolver(enable) { enablePhysicsSolver = enable; }
|
|
1380
|
+
|
|
1381
|
+
/** Set default object mass for collison calcuations
|
|
1382
|
+
* @param {Number} mass
|
|
1383
|
+
* @memberof Settings */
|
|
1384
|
+
function setObjectDefaultMass(mass) { objectDefaultMass = mass; }
|
|
1385
|
+
|
|
1386
|
+
/** Set how much to slow velocity by each frame
|
|
1387
|
+
* @param {Number} damping
|
|
1388
|
+
* @memberof Settings */
|
|
1389
|
+
function setObjectDefaultDamping(damp) { objectDefaultDamping = damp; }
|
|
1390
|
+
|
|
1391
|
+
/** Set how much to slow angular velocity each frame
|
|
1392
|
+
* @param {Number} damping
|
|
1393
|
+
* @memberof Settings */
|
|
1394
|
+
function setObjectDefaultAngleDamping(damp) { objectDefaultAngleDamping = damp; }
|
|
1395
|
+
|
|
1396
|
+
/** Set how much to bounce when a collision occur
|
|
1397
|
+
* @param {Number} elasticity
|
|
1398
|
+
* @memberof Settings */
|
|
1399
|
+
function setObjectDefaultElasticity(elasticity) { objectDefaultElasticity = elasticity; }
|
|
1400
|
+
|
|
1401
|
+
/** Set how much to slow when touching
|
|
1402
|
+
* @param {Number} friction
|
|
1403
|
+
* @memberof Settings */
|
|
1404
|
+
function setObjectDefaultFriction(friction) { objectDefaultFriction = friction; }
|
|
1405
|
+
|
|
1406
|
+
/** Set max speed to avoid fast objects missing collisions
|
|
1407
|
+
* @param {Number} speed
|
|
1408
|
+
* @memberof Settings */
|
|
1409
|
+
function setObjectMaxSpeed(speed) { objectMaxSpeed = speed; }
|
|
1410
|
+
|
|
1411
|
+
/** Set how much gravity to apply to objects along the Y axis
|
|
1412
|
+
* @param {Number} gravity
|
|
1413
|
+
* @memberof Settings */
|
|
1414
|
+
function setGravity(g) { gravity = g; }
|
|
1415
|
+
|
|
1416
|
+
/** Set to scales emit rate of particles
|
|
1417
|
+
* @param {Number} scale
|
|
1418
|
+
* @memberof Settings */
|
|
1419
|
+
function setParticleEmitRateScale(scale) { particleEmitRateScale = scale; }
|
|
1420
|
+
|
|
1421
|
+
/** Set if gamepads are enabled
|
|
1422
|
+
* @param {Boolean} enable
|
|
1423
|
+
* @memberof Settings */
|
|
1424
|
+
function setGamepadsEnable(enable) { gamepadsEnable = enable; }
|
|
1425
|
+
|
|
1426
|
+
/** Set if the dpad input is also routed to the left analog stick
|
|
1427
|
+
* @param {Boolean} enable
|
|
1428
|
+
* @memberof Settings */
|
|
1429
|
+
function setGamepadDirectionEmulateStick(enable) { gamepadDirectionEmulateStick = enable; }
|
|
1430
|
+
|
|
1431
|
+
/** Set if true the WASD keys are also routed to the direction keys
|
|
1432
|
+
* @param {Boolean} enable
|
|
1433
|
+
* @memberof Settings */
|
|
1434
|
+
function setInputWASDEmulateDirection(enable) { inputWASDEmulateDirection = enable; }
|
|
1435
|
+
|
|
1436
|
+
/** Set if touch gamepad should appear on mobile devices
|
|
1437
|
+
* @param {Boolean} enable
|
|
1438
|
+
* @memberof Settings */
|
|
1439
|
+
function setTouchGamepadEnable(enable) { touchGamepadEnable = enable; }
|
|
1440
|
+
|
|
1441
|
+
/** Set if touch gamepad should be analog stick or 8 way dpad
|
|
1442
|
+
* @param {Boolean} analog
|
|
1443
|
+
* @memberof Settings */
|
|
1444
|
+
function setTouchGamepadAnalog(analog) { touchGamepadAnalog = analog; }
|
|
1445
|
+
|
|
1446
|
+
/** Set size of virutal gamepad for touch devices in pixels
|
|
1447
|
+
* @param {Number} size
|
|
1448
|
+
* @memberof Settings */
|
|
1449
|
+
function setTouchGamepadSize(size) { touchGamepadSize = size; }
|
|
1450
|
+
|
|
1451
|
+
/** Set transparency of touch gamepad overlay
|
|
1452
|
+
* @param {Number} alpha
|
|
1453
|
+
* @memberof Settings */
|
|
1454
|
+
function setTouchGamepadAlpha(alpha) { touchGamepadAlpha = alpha; }
|
|
1455
|
+
|
|
1456
|
+
/** Set to allow vibration hardware if it exists
|
|
1457
|
+
* @param {Boolean} enable
|
|
1458
|
+
* @memberof Settings */
|
|
1459
|
+
function setVibrateEnable(enable) { vibrateEnable = enable; }
|
|
1460
|
+
|
|
1461
|
+
/** Set to disable all audio code
|
|
1462
|
+
* @param {Boolean} enable
|
|
1463
|
+
* @memberof Settings */
|
|
1464
|
+
function setSoundEnable(enable) { soundEnable = enable; }
|
|
1465
|
+
|
|
1466
|
+
/** Set volume scale to apply to all sound, music and speech
|
|
1467
|
+
* @param {Number} volume
|
|
1468
|
+
* @memberof Settings */
|
|
1469
|
+
function setSoundVolume(volume) { soundVolume = volume; }
|
|
1470
|
+
|
|
1471
|
+
/** Set default range where sound no longer plays
|
|
1472
|
+
* @param {Number} range
|
|
1473
|
+
* @memberof Settings */
|
|
1474
|
+
function setSoundDefaultRange(range) { soundDefaultRange = range; }
|
|
1475
|
+
|
|
1476
|
+
/** Set default range percent to start tapering off sound
|
|
1477
|
+
* @param {Number} taper
|
|
1478
|
+
* @memberof Settings */
|
|
1479
|
+
function setSoundDefaultTaper(taper) { soundDefaultTaper = taper; }
|
|
1480
|
+
|
|
1481
|
+
/** Set how long to show medals for in seconds
|
|
1482
|
+
* @param {Number} time
|
|
1483
|
+
* @memberof Settings */
|
|
1484
|
+
function setMedalDisplayTime(time) { medalDisplayTime = time; }
|
|
1485
|
+
|
|
1486
|
+
/** Set how quickly to slide on/off medals in seconds
|
|
1487
|
+
* @param {Number} time
|
|
1488
|
+
* @memberof Settings */
|
|
1489
|
+
function setMedalDisplaySlideTime(time) { medalDisplaySlideTime = time; }
|
|
1490
|
+
|
|
1491
|
+
/** Set size of medal display
|
|
1492
|
+
* @param {Vector2} size
|
|
1493
|
+
* @memberof Settings */
|
|
1494
|
+
function setMedalDisplaySize(size) { medalDisplaySize = size; }
|
|
1495
|
+
|
|
1496
|
+
/** Set size of icon in medal display
|
|
1497
|
+
* @param {Number} size
|
|
1498
|
+
* @memberof Settings */
|
|
1499
|
+
function setMedalDisplayIconSize(size) { medalDisplayIconSize = size; }
|
|
1500
|
+
|
|
1501
|
+
/** Set to stop medals from being unlockable
|
|
1502
|
+
* @param {Boolean} preventUnlock
|
|
1503
|
+
* @memberof Settings */
|
|
1504
|
+
function setMedalsPreventUnlock(preventUnlock) { medalsPreventUnlock = preventUnlock; }
|
|
1505
|
+
|
|
1506
|
+
/** Set if watermark with FPS should be shown
|
|
1507
|
+
* @param {Boolean} show
|
|
1508
|
+
* @memberof Debug */
|
|
1509
|
+
function setShowWatermark(show) { showWatermark = show; }
|
|
1510
|
+
|
|
1511
|
+
/** Set key code used to toggle debug mode, Esc by default
|
|
1512
|
+
* @param {Number} key
|
|
1513
|
+
* @memberof Debug */
|
|
1514
|
+
function setDebugKey(key) { debugKey = key; }
|
|
1320
1515
|
/**
|
|
1321
1516
|
* LittleJS Object System
|
|
1322
1517
|
*/
|
|
1323
1518
|
|
|
1324
|
-
|
|
1519
|
+
|
|
1325
1520
|
|
|
1326
1521
|
/**
|
|
1327
1522
|
* LittleJS Object Base Object Class
|
|
@@ -1351,18 +1546,19 @@ let medalsPreventUnlock;
|
|
|
1351
1546
|
class EngineObject
|
|
1352
1547
|
{
|
|
1353
1548
|
/** Create an engine object and adds it to the list of objects
|
|
1354
|
-
* @param {Vector2} [
|
|
1355
|
-
* @param {Vector2} [size=Vector2(1,1)]
|
|
1356
|
-
* @param {
|
|
1357
|
-
* @param {
|
|
1358
|
-
* @param {
|
|
1359
|
-
* @param {
|
|
1360
|
-
* @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
|
|
1549
|
+
* @param {Vector2} [pos=Vector2()] - World space position of the object
|
|
1550
|
+
* @param {Vector2} [size=Vector2(1,1)] - World space size of the object
|
|
1551
|
+
* @param {TileInfo} [tileInfo] - Tile info to render object (undefined is untextured)
|
|
1552
|
+
* @param {Number} [angle=0] - Angle the object is rotated by
|
|
1553
|
+
* @param {Color} [color=Color()] - Color to apply to tile when rendered
|
|
1554
|
+
* @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
|
|
1361
1555
|
*/
|
|
1362
|
-
constructor(pos=vec2(), size=vec2(1),
|
|
1556
|
+
constructor(pos=vec2(), size=vec2(1), tileInfo, angle=0, color, renderOrder=0)
|
|
1363
1557
|
{
|
|
1364
1558
|
// set passed in params
|
|
1365
1559
|
ASSERT(isVector2(pos) && isVector2(size)); // ensure pos and size are vec2s
|
|
1560
|
+
ASSERT(typeof tileInfo !== 'number' || !tileInfo); // prevent old style calls
|
|
1561
|
+
// to fix old calls, replace with tile(tileIndex, tileSize)
|
|
1366
1562
|
|
|
1367
1563
|
/** @property {Vector2} - World space position of the object */
|
|
1368
1564
|
this.pos = pos.copy();
|
|
@@ -1370,10 +1566,8 @@ class EngineObject
|
|
|
1370
1566
|
this.size = size;
|
|
1371
1567
|
/** @property {Vector2} - Size of object used for drawing, uses size if not set */
|
|
1372
1568
|
this.drawSize;
|
|
1373
|
-
/** @property {
|
|
1374
|
-
this.
|
|
1375
|
-
/** @property {Vector2} - Size of tile in source pixels */
|
|
1376
|
-
this.tileSize = tileSize;
|
|
1569
|
+
/** @property {TileInfo} - Tile info to render object (undefined is untextured) */
|
|
1570
|
+
this.tileInfo = tileInfo;
|
|
1377
1571
|
/** @property {Number} - Angle to rotate the object */
|
|
1378
1572
|
this.angle = angle;
|
|
1379
1573
|
/** @property {Color} - Color to apply when rendered */
|
|
@@ -1589,7 +1783,7 @@ class EngineObject
|
|
|
1589
1783
|
render()
|
|
1590
1784
|
{
|
|
1591
1785
|
// default object render
|
|
1592
|
-
drawTile(this.pos, this.drawSize || this.size, this.
|
|
1786
|
+
drawTile(this.pos, this.drawSize || this.size, this.tileInfo, this.color, this.angle, this.mirror, this.additiveColor);
|
|
1593
1787
|
}
|
|
1594
1788
|
|
|
1595
1789
|
/** Destroy this object, destroy it's children, detach it's parent, and mark it for removal */
|
|
@@ -1717,7 +1911,7 @@ class EngineObject
|
|
|
1717
1911
|
* @namespace Draw
|
|
1718
1912
|
*/
|
|
1719
1913
|
|
|
1720
|
-
|
|
1914
|
+
|
|
1721
1915
|
|
|
1722
1916
|
/** The primary 2D canvas visible to the user
|
|
1723
1917
|
* @type {HTMLCanvasElement}
|
|
@@ -1744,13 +1938,109 @@ let overlayContext;
|
|
|
1744
1938
|
* @memberof Draw */
|
|
1745
1939
|
let mainCanvasSize = vec2();
|
|
1746
1940
|
|
|
1747
|
-
/**
|
|
1748
|
-
* @type {
|
|
1941
|
+
/** Array containing texture info for batch rendering system
|
|
1942
|
+
* @type {Array}
|
|
1749
1943
|
* @memberof Draw */
|
|
1750
|
-
|
|
1944
|
+
let textureInfos = [];
|
|
1751
1945
|
|
|
1752
1946
|
// Engine internal variables not exposed to documentation
|
|
1753
|
-
let
|
|
1947
|
+
let drawCount;
|
|
1948
|
+
|
|
1949
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
1950
|
+
|
|
1951
|
+
/**
|
|
1952
|
+
* Create a tile info object
|
|
1953
|
+
* - This can take vecs or floats for easier use and conversion
|
|
1954
|
+
* - If an index is passed in, the tile size and index will determine the position
|
|
1955
|
+
* @param {(Number|Vector2)} [pos=Vector2()] - Top left corner of tile in pixels or index
|
|
1956
|
+
* @param {(Number|Vector2)} [size=tileSizeDefault] - Size of tile in pixels
|
|
1957
|
+
* @param {Number} [textureIndex=0] - Texture index to use
|
|
1958
|
+
* @return {TileInfo}
|
|
1959
|
+
* @example
|
|
1960
|
+
* tile(2) // a tile at index 2 using the default tile size of 16
|
|
1961
|
+
* tile(5, 8) // a tile at index 5 using a tile size of 8
|
|
1962
|
+
* tile(1, 16, 3) // a tile at index 1 of size 16 on texture 3
|
|
1963
|
+
* tile(vec2(4,8), vec2(30,10)) // a tile at pixel location (4,8) with a size of (30,10)
|
|
1964
|
+
* @memberof Draw
|
|
1965
|
+
*/
|
|
1966
|
+
function tile(pos=vec2(), size=tileSizeDefault, textureIndex=0)
|
|
1967
|
+
{
|
|
1968
|
+
// if size is a number, make it a vector
|
|
1969
|
+
if (size.x == undefined)
|
|
1970
|
+
{
|
|
1971
|
+
ASSERT(size > 0);
|
|
1972
|
+
size = vec2(size);
|
|
1973
|
+
}
|
|
1974
|
+
|
|
1975
|
+
// if pos is a number, use it as a tile index
|
|
1976
|
+
if (pos.x == undefined)
|
|
1977
|
+
{
|
|
1978
|
+
const textureInfo = textureInfos[textureIndex];
|
|
1979
|
+
if (textureInfo)
|
|
1980
|
+
{
|
|
1981
|
+
const cols = textureInfo.size.x / size.x |0;
|
|
1982
|
+
pos = vec2((pos%cols)*size.x, (pos/cols|0)*size.y);
|
|
1983
|
+
}
|
|
1984
|
+
else
|
|
1985
|
+
pos = vec2();
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
// return a tile info object
|
|
1989
|
+
return new TileInfo(pos, size, textureIndex);
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
/**
|
|
1993
|
+
* Tile Info - Stores info about how to draw a tile
|
|
1994
|
+
*/
|
|
1995
|
+
class TileInfo
|
|
1996
|
+
{
|
|
1997
|
+
/** Create a tile info object
|
|
1998
|
+
* @param {Vector2} [pos=Vector2()] - Top left corner of tile in pixels
|
|
1999
|
+
* @param {Vector2} [size=tileSizeDefault] - Size of tile in pixels
|
|
2000
|
+
* @param {Number} [textureIndex=0] - Texture index to use
|
|
2001
|
+
*/
|
|
2002
|
+
constructor(pos=vec2(), size=tileSizeDefault, textureIndex=0)
|
|
2003
|
+
{
|
|
2004
|
+
/** @property {Vector2} - Top left corner of tile in pixels */
|
|
2005
|
+
this.pos = pos;
|
|
2006
|
+
/** @property {Vector2} - Size of tile in pixels */
|
|
2007
|
+
this.size = size;
|
|
2008
|
+
/** @property {Number} - Texture index to use */
|
|
2009
|
+
this.textureIndex = textureIndex;
|
|
2010
|
+
}
|
|
2011
|
+
|
|
2012
|
+
/** Returns an offset copy of this tile, useful for animation
|
|
2013
|
+
* @param {Vector2} offset - Offset to apply in pixels
|
|
2014
|
+
* @return {TileInfo}
|
|
2015
|
+
*/
|
|
2016
|
+
offset(offset)
|
|
2017
|
+
{ return new TileInfo(this.pos.add(offset), this.size, this.textureIndex); }
|
|
2018
|
+
|
|
2019
|
+
/** Returns the texture info for this tile
|
|
2020
|
+
* @return {TextureInfo}
|
|
2021
|
+
*/
|
|
2022
|
+
getTextureInfo()
|
|
2023
|
+
{ return textureInfos[this.textureIndex]; }
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
/** Texture Info - Stores info about each texture */
|
|
2027
|
+
class TextureInfo
|
|
2028
|
+
{
|
|
2029
|
+
// create a TextureInfo, called automatically by the engine
|
|
2030
|
+
constructor(image)
|
|
2031
|
+
{
|
|
2032
|
+
/** @property {CanvasImageSource} - image source */
|
|
2033
|
+
this.image = image;
|
|
2034
|
+
/** @property {Vector2} - size of the image */
|
|
2035
|
+
this.size = vec2(image.width, image.height);
|
|
2036
|
+
/** @property {WebGLTexture} - webgl texture */
|
|
2037
|
+
this.glTexture = glEnable && glCreateTexture(image);
|
|
2038
|
+
/** @property {Vector2} - size to adjust tile to fix bleeding */
|
|
2039
|
+
this.fixBleedSize = vec2(tileFixBleedScale).divide(this.size);
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
|
|
2043
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
1754
2044
|
|
|
1755
2045
|
/** Convert from screen to world space coordinates
|
|
1756
2046
|
* @param {Vector2} screenPos
|
|
@@ -1781,7 +2071,7 @@ function worldToScreen(worldPos)
|
|
|
1781
2071
|
/** Draw textured tile centered in world space, with color applied if using WebGL
|
|
1782
2072
|
* @param {Vector2} pos - Center of the tile in world space
|
|
1783
2073
|
* @param {Vector2} [size=Vector2(1,1)] - Size of the tile in world space
|
|
1784
|
-
* @param {
|
|
2074
|
+
* @param {TileInfo}[tileInfo] - Tile info to use, untextured if undefined
|
|
1785
2075
|
* @param {Vector2} [tileSize=tileSizeDefault] - Tile size in source pixels
|
|
1786
2076
|
* @param {Color} [color=Color()] - Color to modulate with
|
|
1787
2077
|
* @param {Number} [angle=0] - Angle to rotate by
|
|
@@ -1790,11 +2080,14 @@ function worldToScreen(worldPos)
|
|
|
1790
2080
|
* @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
|
|
1791
2081
|
* @param {Boolean} [screenSpace=0] - If true the pos and size are in screen space
|
|
1792
2082
|
* @memberof Draw */
|
|
1793
|
-
function drawTile(pos, size=vec2(1),
|
|
2083
|
+
function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
|
|
1794
2084
|
angle=0, mirror, additiveColor=new Color(0,0,0,0), useWebGL=glEnable, screenSpace)
|
|
1795
2085
|
{
|
|
2086
|
+
ASSERT(typeof tileInfo !== 'number' || !tileInfo); // prevent old style calls
|
|
2087
|
+
// to fix old calls, replace with tile(tileIndex, tileSize)
|
|
2088
|
+
|
|
1796
2089
|
showWatermark && ++drawCount;
|
|
1797
|
-
|
|
2090
|
+
const textureInfo = tileInfo && tileInfo.getTextureInfo();
|
|
1798
2091
|
if (glEnable && useWebGL)
|
|
1799
2092
|
{
|
|
1800
2093
|
if (screenSpace)
|
|
@@ -1803,46 +2096,48 @@ function drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, col
|
|
|
1803
2096
|
pos = screenToWorld(pos);
|
|
1804
2097
|
size = size.scale(1/cameraScale);
|
|
1805
2098
|
}
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
// if negative tile index or image not found, force untextured
|
|
1809
|
-
glDraw(pos.x, pos.y, size.x, size.y, angle, 0, 0, 0, 0, 0, color.rgbaInt());
|
|
1810
|
-
}
|
|
1811
|
-
else
|
|
2099
|
+
|
|
2100
|
+
if (textureInfo)
|
|
1812
2101
|
{
|
|
1813
2102
|
// calculate uvs and render
|
|
1814
|
-
const
|
|
1815
|
-
const
|
|
1816
|
-
const
|
|
1817
|
-
const
|
|
1818
|
-
|
|
2103
|
+
const x = tileInfo.pos.x / textureInfo.size.x;
|
|
2104
|
+
const y = tileInfo.pos.y / textureInfo.size.y;
|
|
2105
|
+
const w = tileInfo.size.x / textureInfo.size.x;
|
|
2106
|
+
const h = tileInfo.size.y / textureInfo.size.y;
|
|
2107
|
+
const tileImageFixBleed = textureInfo.fixBleedSize;
|
|
2108
|
+
glSetTexture(textureInfo.glTexture);
|
|
1819
2109
|
glDraw(pos.x, pos.y, mirror ? -size.x : size.x, size.y, angle,
|
|
1820
|
-
|
|
1821
|
-
|
|
2110
|
+
x + tileImageFixBleed.x, y + tileImageFixBleed.y,
|
|
2111
|
+
x - tileImageFixBleed.x + w, y - tileImageFixBleed.y + h,
|
|
1822
2112
|
color.rgbaInt(), additiveColor.rgbaInt());
|
|
1823
2113
|
}
|
|
2114
|
+
else
|
|
2115
|
+
{
|
|
2116
|
+
// if no tile info, force untextured
|
|
2117
|
+
glDraw(pos.x, pos.y, size.x, size.y, angle, 0, 0, 0, 0, 0, color.rgbaInt());
|
|
2118
|
+
}
|
|
1824
2119
|
}
|
|
1825
2120
|
else
|
|
1826
2121
|
{
|
|
1827
2122
|
// normal canvas 2D rendering method (slower)
|
|
1828
2123
|
drawCanvas2D(pos, size, angle, mirror, (context)=>
|
|
1829
2124
|
{
|
|
1830
|
-
if (
|
|
2125
|
+
if (textureInfo)
|
|
1831
2126
|
{
|
|
1832
|
-
//
|
|
1833
|
-
|
|
1834
|
-
|
|
2127
|
+
// calculate uvs and render
|
|
2128
|
+
const x = tileInfo.pos.x + tileFixBleedScale;
|
|
2129
|
+
const y = tileInfo.pos.y + tileFixBleedScale;
|
|
2130
|
+
const w = tileInfo.size.x - 2*tileFixBleedScale;
|
|
2131
|
+
const h = tileInfo.size.y - 2*tileFixBleedScale;
|
|
2132
|
+
context.globalAlpha = color.a; // only alpha is supported
|
|
2133
|
+
context.drawImage(textureInfo.image, x, y, w, h, -.5, -.5, 1, 1);
|
|
2134
|
+
context.globalAlpha = 1; // set back to full alpha
|
|
1835
2135
|
}
|
|
1836
2136
|
else
|
|
1837
2137
|
{
|
|
1838
|
-
//
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
const sY = (tileIndex/cols|0)*tileSize.y + tileFixBleedScale;
|
|
1842
|
-
const sWidth = tileSize.x - 2*tileFixBleedScale;
|
|
1843
|
-
const sHeight = tileSize.y - 2*tileFixBleedScale;
|
|
1844
|
-
context.globalAlpha = color.a; // only alpha is supported
|
|
1845
|
-
context.drawImage(tileImage, sX, sY, sWidth, sHeight, -.5, -.5, 1, 1);
|
|
2138
|
+
// if no tile info, force untextured
|
|
2139
|
+
context.fillStyle = color;
|
|
2140
|
+
context.fillRect(-.5, -.5, 1, 1);
|
|
1846
2141
|
}
|
|
1847
2142
|
}, undefined, screenSpace);
|
|
1848
2143
|
}
|
|
@@ -1857,7 +2152,7 @@ function drawTile(pos, size=vec2(1), tileIndex=-1, tileSize=tileSizeDefault, col
|
|
|
1857
2152
|
* @param {Boolean} [screenSpace=0]
|
|
1858
2153
|
* @memberof Draw */
|
|
1859
2154
|
function drawRect(pos, size, color, angle, useWebGL, screenSpace)
|
|
1860
|
-
{ drawTile(pos, size,
|
|
2155
|
+
{ drawTile(pos, size, undefined, color, angle, 0, undefined, useWebGL, screenSpace); }
|
|
1861
2156
|
|
|
1862
2157
|
/** Draw colored polygon using passed in points
|
|
1863
2158
|
* @param {Array} points - Array of Vector2 points
|
|
@@ -1908,12 +2203,12 @@ function drawCanvas2D(pos, size, angle, mirror, drawFunction, context = mainCont
|
|
|
1908
2203
|
{
|
|
1909
2204
|
if (!screenSpace)
|
|
1910
2205
|
{
|
|
1911
|
-
//
|
|
2206
|
+
// transform from world space to screen space
|
|
1912
2207
|
pos = worldToScreen(pos);
|
|
1913
2208
|
size = size.scale(cameraScale);
|
|
1914
2209
|
}
|
|
1915
2210
|
context.save();
|
|
1916
|
-
context.translate(pos.x+.5
|
|
2211
|
+
context.translate(pos.x+.5, pos.y+.5);
|
|
1917
2212
|
context.rotate(angle);
|
|
1918
2213
|
context.scale(mirror ? -size.x : size.x, size.y);
|
|
1919
2214
|
drawFunction(context);
|
|
@@ -2002,10 +2297,9 @@ class FontImage
|
|
|
2002
2297
|
* @param {HTMLImageElement} [image] - Image for the font, if undefined default font is used
|
|
2003
2298
|
* @param {Vector2} [tileSize=vec2(8)] - Size of the font source tiles
|
|
2004
2299
|
* @param {Vector2} [paddingSize=vec2(0,1)] - How much extra space to add between characters
|
|
2005
|
-
* @param {Number} [startTileIndex=0] - Tile index in image where font starts
|
|
2006
2300
|
* @param {CanvasRenderingContext2D} [context=overlayContext] - context to draw to
|
|
2007
2301
|
*/
|
|
2008
|
-
constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1),
|
|
2302
|
+
constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1), context=overlayContext)
|
|
2009
2303
|
{
|
|
2010
2304
|
// load default font image
|
|
2011
2305
|
if (!engineFontImage)
|
|
@@ -2014,7 +2308,6 @@ class FontImage
|
|
|
2014
2308
|
this.image = image || engineFontImage;
|
|
2015
2309
|
this.tileSize = tileSize;
|
|
2016
2310
|
this.paddingSize = paddingSize;
|
|
2017
|
-
this.startTileIndex = startTileIndex;
|
|
2018
2311
|
this.context = context;
|
|
2019
2312
|
}
|
|
2020
2313
|
|
|
@@ -2055,7 +2348,7 @@ class FontImage
|
|
|
2055
2348
|
charCode = 127; // unknown character
|
|
2056
2349
|
|
|
2057
2350
|
// get the character source location and draw it
|
|
2058
|
-
const tile =
|
|
2351
|
+
const tile = charCode - 32;
|
|
2059
2352
|
const x = tile % cols;
|
|
2060
2353
|
const y = tile / cols |0;
|
|
2061
2354
|
const drawPos = pos.add(vec2(j,i).multiply(drawSize));
|
|
@@ -2087,8 +2380,7 @@ function toggleFullscreen()
|
|
|
2087
2380
|
}
|
|
2088
2381
|
else if (document.body.requestFullscreen)
|
|
2089
2382
|
document.body.requestFullscreen();
|
|
2090
|
-
}
|
|
2091
|
-
|
|
2383
|
+
}
|
|
2092
2384
|
/**
|
|
2093
2385
|
* LittleJS Input System
|
|
2094
2386
|
* - Tracks keyboard down, pressed, and released
|
|
@@ -2098,7 +2390,7 @@ function toggleFullscreen()
|
|
|
2098
2390
|
* @namespace Input
|
|
2099
2391
|
*/
|
|
2100
2392
|
|
|
2101
|
-
|
|
2393
|
+
|
|
2102
2394
|
|
|
2103
2395
|
/** Returns true if device key is down
|
|
2104
2396
|
* @param {Number} key
|
|
@@ -2282,18 +2574,26 @@ function mouseToScreen(mousePos)
|
|
|
2282
2574
|
const stickData = [];
|
|
2283
2575
|
function gamepadsUpdate()
|
|
2284
2576
|
{
|
|
2285
|
-
|
|
2577
|
+
// update touch gamepad if enabled
|
|
2578
|
+
if (touchGamepadEnable && isTouchDevice)
|
|
2286
2579
|
{
|
|
2287
|
-
//
|
|
2288
|
-
|
|
2289
|
-
|
|
2580
|
+
// create the touch gamepad if it doesn't exist
|
|
2581
|
+
if (!touchGamepadButtons)
|
|
2582
|
+
createTouchGamepad();
|
|
2290
2583
|
|
|
2291
|
-
|
|
2292
|
-
const data = inputData[1] || (inputData[1] = []);
|
|
2293
|
-
for (let i=10; i--;)
|
|
2584
|
+
if (touchGamepadTimer.isSet())
|
|
2294
2585
|
{
|
|
2295
|
-
|
|
2296
|
-
|
|
2586
|
+
// read virtual analog stick
|
|
2587
|
+
const sticks = stickData[0] || (stickData[0] = []);
|
|
2588
|
+
sticks[0] = vec2(touchGamepadStick.x, -touchGamepadStick.y); // flip vertical
|
|
2589
|
+
|
|
2590
|
+
// read virtual gamepad buttons
|
|
2591
|
+
const data = inputData[1] || (inputData[1] = []);
|
|
2592
|
+
for (let i=10; i--;)
|
|
2593
|
+
{
|
|
2594
|
+
const j = i == 3 ? 2 : i == 2 ? 3 : i; // fix button locations
|
|
2595
|
+
data[j] = touchGamepadButtons[i] ? 1 + 2*!gamepadIsDown(j,0) : 4*gamepadIsDown(j,0);
|
|
2596
|
+
}
|
|
2297
2597
|
}
|
|
2298
2598
|
}
|
|
2299
2599
|
|
|
@@ -2390,6 +2690,10 @@ if (isTouchDevice)
|
|
|
2390
2690
|
// set was touching
|
|
2391
2691
|
wasTouching = touching;
|
|
2392
2692
|
|
|
2693
|
+
// prevent default handling like copy and magnifier lens
|
|
2694
|
+
if (document.hasFocus()) // allow document to get focus
|
|
2695
|
+
e.preventDefault();
|
|
2696
|
+
|
|
2393
2697
|
// must return true so the document will get focus
|
|
2394
2698
|
return true;
|
|
2395
2699
|
}
|
|
@@ -2402,7 +2706,7 @@ if (isTouchDevice)
|
|
|
2402
2706
|
let touchGamepadTimer = new Timer, touchGamepadButtons, touchGamepadStick;
|
|
2403
2707
|
|
|
2404
2708
|
// create the touch gamepad, called automatically by the engine
|
|
2405
|
-
|
|
2709
|
+
function createTouchGamepad()
|
|
2406
2710
|
{
|
|
2407
2711
|
// touch input internal variables
|
|
2408
2712
|
touchGamepadButtons = [];
|
|
@@ -2536,7 +2840,7 @@ function touchGamepadRender()
|
|
|
2536
2840
|
* @namespace Audio
|
|
2537
2841
|
*/
|
|
2538
2842
|
|
|
2539
|
-
|
|
2843
|
+
|
|
2540
2844
|
|
|
2541
2845
|
/**
|
|
2542
2846
|
* Sound Object - Stores a zzfx sound for later use and can be played positionally
|
|
@@ -2572,8 +2876,9 @@ class Sound
|
|
|
2572
2876
|
if (zzfxSound)
|
|
2573
2877
|
{
|
|
2574
2878
|
// generate zzfx sound now for fast playback
|
|
2575
|
-
this.randomness = zzfxSound[1] || (zzfxSound[1] = 0);
|
|
2576
|
-
this.
|
|
2879
|
+
this.randomness = zzfxSound[1] || (zzfxSound[1] = 0);
|
|
2880
|
+
this.sampleChannels = [zzfxG(...zzfxSound)];
|
|
2881
|
+
this.sampleRate = zzfxR;
|
|
2577
2882
|
}
|
|
2578
2883
|
}
|
|
2579
2884
|
|
|
@@ -2582,11 +2887,12 @@ class Sound
|
|
|
2582
2887
|
* @param {Number} [volume=1] - How much to scale volume by (in addition to range fade)
|
|
2583
2888
|
* @param {Number} [pitch=1] - How much to scale pitch by (also adjusted by this.randomness)
|
|
2584
2889
|
* @param {Number} [randomnessScale=1] - How much to scale randomness
|
|
2585
|
-
* @
|
|
2890
|
+
* @param {Boolean} [loop=0] - Should the sound loop
|
|
2891
|
+
* @return {AudioBufferSourceNode} - The audio source node
|
|
2586
2892
|
*/
|
|
2587
|
-
play(pos, volume=1, pitch=1, randomnessScale=1)
|
|
2893
|
+
play(pos, volume=1, pitch=1, randomnessScale=1, loop=0)
|
|
2588
2894
|
{
|
|
2589
|
-
if (!soundEnable || !this.
|
|
2895
|
+
if (!soundEnable || !this.sampleChannels) return;
|
|
2590
2896
|
|
|
2591
2897
|
let pan;
|
|
2592
2898
|
if (pos)
|
|
@@ -2609,43 +2915,80 @@ class Sound
|
|
|
2609
2915
|
|
|
2610
2916
|
// play the sound
|
|
2611
2917
|
const playbackRate = pitch + pitch * this.randomness*randomnessScale*rand(-1,1);
|
|
2612
|
-
return playSamples(
|
|
2918
|
+
return this.source = playSamples(this.sampleChannels, volume, playbackRate, pan, loop, this.sampleRate);
|
|
2919
|
+
}
|
|
2920
|
+
|
|
2921
|
+
/** Stop the last instance of this sound that was played */
|
|
2922
|
+
stop()
|
|
2923
|
+
{
|
|
2924
|
+
if (this.source)
|
|
2925
|
+
this.source.stop();
|
|
2926
|
+
this.source = 0;
|
|
2613
2927
|
}
|
|
2614
2928
|
|
|
2615
2929
|
/** Play the sound as a note with a semitone offset
|
|
2616
2930
|
* @param {Number} semitoneOffset - How many semitones to offset pitch
|
|
2617
2931
|
* @param {Vector2} [pos] - World space position to play the sound, sound is not attenuated if null
|
|
2618
2932
|
* @param {Number} [volume=1] - How much to scale volume by (in addition to range fade)
|
|
2619
|
-
* @return {AudioBufferSourceNode} - The audio
|
|
2933
|
+
* @return {AudioBufferSourceNode} - The audio source node
|
|
2620
2934
|
*/
|
|
2621
2935
|
playNote(semitoneOffset, pos, volume)
|
|
2622
2936
|
{ return this.play(pos, volume, 2**(semitoneOffset/12), 0); }
|
|
2937
|
+
|
|
2938
|
+
/** Get how long this sound is in seconds
|
|
2939
|
+
* @return {Number} - How long the sound is in seconds (undefined if loading)
|
|
2940
|
+
*/
|
|
2941
|
+
getDuration()
|
|
2942
|
+
{ return this.sampleChannels && this.sampleChannels[0].length / this.sampleRate; }
|
|
2943
|
+
|
|
2944
|
+
/** Check if the last instance of this sound is playing
|
|
2945
|
+
* @return {Boolean} - True if the sound is playing
|
|
2946
|
+
*/
|
|
2947
|
+
isPlaying() { return this.source && !this.source.ended; }
|
|
2948
|
+
|
|
2949
|
+
/** Check if sound is loading, for sounds fetched from a url
|
|
2950
|
+
* @return {Boolean} - True if sound is loading and not ready to play
|
|
2951
|
+
*/
|
|
2952
|
+
isLoading() { return !this.sampleChannels; }
|
|
2623
2953
|
}
|
|
2624
2954
|
|
|
2625
2955
|
/**
|
|
2626
2956
|
* Sound Wave Object - Stores a wave sound for later use and can be played positionally
|
|
2957
|
+
* - this can be used to play wave, mp3, and ogg files
|
|
2958
|
+
* @example
|
|
2959
|
+
* // create a sound
|
|
2960
|
+
* const sound_example = new SoundWave('sound.mp3');
|
|
2961
|
+
*
|
|
2962
|
+
* // play the sound
|
|
2963
|
+
* sound_example.play();
|
|
2627
2964
|
*/
|
|
2628
2965
|
class SoundWave extends Sound
|
|
2629
2966
|
{
|
|
2630
2967
|
/** Create a sound object and cache the wave file for later use
|
|
2631
|
-
* @param {String}
|
|
2632
|
-
* @param {Number} [randomness
|
|
2968
|
+
* @param {String} filename - Filename of audio file to load
|
|
2969
|
+
* @param {Number} [randomness=0] - How much to randomize frequency each time sound plays
|
|
2633
2970
|
* @param {Number} [range=soundDefaultRange] - World space max range of sound, will not play if camera is farther away
|
|
2634
2971
|
* @param {Number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering off
|
|
2635
2972
|
*/
|
|
2636
|
-
constructor(
|
|
2973
|
+
constructor(filename, randomness=0, range, taper)
|
|
2637
2974
|
{
|
|
2638
2975
|
super(0, range, taper);
|
|
2639
2976
|
this.randomness = randomness;
|
|
2640
2977
|
|
|
2641
2978
|
if (!soundEnable) return;
|
|
2642
|
-
if (!
|
|
2979
|
+
if (!soundDecoderContext)
|
|
2643
2980
|
soundDecoderContext = new AudioContext;
|
|
2644
2981
|
|
|
2645
|
-
fetch(
|
|
2982
|
+
fetch(filename)
|
|
2646
2983
|
.then(response => response.arrayBuffer())
|
|
2647
|
-
.then(arrayBuffer =>
|
|
2648
|
-
.then(audioBuffer =>
|
|
2984
|
+
.then(arrayBuffer => soundDecoderContext.decodeAudioData(arrayBuffer))
|
|
2985
|
+
.then(audioBuffer =>
|
|
2986
|
+
{
|
|
2987
|
+
this.sampleChannels = [];
|
|
2988
|
+
for (let i = audioBuffer.numberOfChannels; i--;)
|
|
2989
|
+
this.sampleChannels[i] = audioBuffer.getChannelData(i);
|
|
2990
|
+
this.sampleRate = audioBuffer.sampleRate;
|
|
2991
|
+
});
|
|
2649
2992
|
}
|
|
2650
2993
|
}
|
|
2651
2994
|
let soundDecoderContext; // audio context used only to decode audio files
|
|
@@ -2680,48 +3023,34 @@ let soundDecoderContext; // audio context used only to decode audio files
|
|
|
2680
3023
|
* // play the music
|
|
2681
3024
|
* music_example.play();
|
|
2682
3025
|
*/
|
|
2683
|
-
class Music
|
|
3026
|
+
class Music extends Sound
|
|
2684
3027
|
{
|
|
2685
3028
|
/** Create a music object and cache the zzfx music samples for later use
|
|
2686
3029
|
* @param {Array} zzfxMusic - Array of zzfx music parameters
|
|
2687
3030
|
*/
|
|
2688
3031
|
constructor(zzfxMusic)
|
|
2689
3032
|
{
|
|
2690
|
-
|
|
3033
|
+
super();
|
|
2691
3034
|
|
|
2692
|
-
|
|
3035
|
+
if (!soundEnable) return;
|
|
3036
|
+
this.randomness = 0;
|
|
3037
|
+
this.sampleChannels = zzfxM(...zzfxMusic);
|
|
3038
|
+
this.sampleRate = zzfxR;
|
|
2693
3039
|
}
|
|
2694
3040
|
|
|
2695
3041
|
/** Play the music
|
|
2696
3042
|
* @param {Number} [volume=1] - How much to scale volume by
|
|
2697
|
-
* @param {Boolean} [loop=1] - True if the music should loop
|
|
2698
|
-
* @return {AudioBufferSourceNode} - The audio node
|
|
3043
|
+
* @param {Boolean} [loop=1] - True if the music should loop
|
|
3044
|
+
* @return {AudioBufferSourceNode} - The audio source node
|
|
2699
3045
|
*/
|
|
2700
3046
|
play(volume, loop = 1)
|
|
2701
|
-
{
|
|
2702
|
-
if (!soundEnable) return;
|
|
2703
|
-
|
|
2704
|
-
return this.source = playSamples(this.cachedSamples, volume, 1, 0, loop);
|
|
2705
|
-
}
|
|
2706
|
-
|
|
2707
|
-
/** Stop the music */
|
|
2708
|
-
stop()
|
|
2709
|
-
{
|
|
2710
|
-
if (this.source)
|
|
2711
|
-
this.source.stop();
|
|
2712
|
-
this.source = 0;
|
|
2713
|
-
}
|
|
2714
|
-
|
|
2715
|
-
/** Check if music is playing
|
|
2716
|
-
* @return {Boolean}
|
|
2717
|
-
*/
|
|
2718
|
-
isPlaying() { return this.source; }
|
|
3047
|
+
{ return super.play(0, volume, 1, 1, loop); }
|
|
2719
3048
|
}
|
|
2720
3049
|
|
|
2721
|
-
/** Play an mp3 or wav audio from a local file or url
|
|
3050
|
+
/** Play an mp3, ogg, or wav audio from a local file or url
|
|
2722
3051
|
* @param {String} url - Location of sound file to play
|
|
2723
3052
|
* @param {Number} [volume=1] - How much to scale volume by
|
|
2724
|
-
* @param {Boolean} [loop=1] - True if the music should loop
|
|
3053
|
+
* @param {Boolean} [loop=1] - True if the music should loop
|
|
2725
3054
|
* @return {HTMLAudioElement} - The audio element for this sound
|
|
2726
3055
|
* @memberof Audio */
|
|
2727
3056
|
function playAudioFile(url, volume=1, loop=1)
|
|
@@ -2785,9 +3114,10 @@ let audioContext;
|
|
|
2785
3114
|
* @param {Number} [rate=1] - The playback rate to use
|
|
2786
3115
|
* @param {Number} [pan=0] - How much to apply stereo panning
|
|
2787
3116
|
* @param {Boolean} [loop=0] - True if the sound should loop when it reaches the end
|
|
3117
|
+
* @param {Number} [sampleRate=44100] - Sample rate for the sound
|
|
2788
3118
|
* @return {AudioBufferSourceNode} - The audio node of the sound played
|
|
2789
3119
|
* @memberof Audio */
|
|
2790
|
-
function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0)
|
|
3120
|
+
function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0, sampleRate=zzfxR)
|
|
2791
3121
|
{
|
|
2792
3122
|
if (!soundEnable) return;
|
|
2793
3123
|
|
|
@@ -2804,7 +3134,7 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0)
|
|
|
2804
3134
|
}
|
|
2805
3135
|
|
|
2806
3136
|
// create buffer and source
|
|
2807
|
-
const buffer = audioContext.createBuffer(sampleChannels.length, sampleChannels[0].length,
|
|
3137
|
+
const buffer = audioContext.createBuffer(sampleChannels.length, sampleChannels[0].length, sampleRate),
|
|
2808
3138
|
source = audioContext.createBufferSource();
|
|
2809
3139
|
|
|
2810
3140
|
// copy samples to buffer and setup source
|
|
@@ -3063,7 +3393,7 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
|
3063
3393
|
* @namespace TileCollision
|
|
3064
3394
|
*/
|
|
3065
3395
|
|
|
3066
|
-
|
|
3396
|
+
|
|
3067
3397
|
|
|
3068
3398
|
/** The tile collision layer array, use setTileCollisionData and getTileCollisionData to access
|
|
3069
3399
|
* @type {Array}
|
|
@@ -3208,7 +3538,7 @@ class TileLayerData
|
|
|
3208
3538
|
}
|
|
3209
3539
|
|
|
3210
3540
|
/**
|
|
3211
|
-
* Tile
|
|
3541
|
+
* Tile Layer - cached rendering system for tile layers
|
|
3212
3542
|
* - Each Tile layer is rendered to an off screen canvas
|
|
3213
3543
|
* - To allow dynamic modifications, layers are rendered using canvas 2d
|
|
3214
3544
|
* - Some devices like mobile phones are limited to 4k texture resolution
|
|
@@ -3224,13 +3554,13 @@ class TileLayer extends EngineObject
|
|
|
3224
3554
|
/** Create a tile layer object
|
|
3225
3555
|
* @param {Vector2} [position=Vector2()] - World space position
|
|
3226
3556
|
* @param {Vector2} [size=tileCollisionSize] - World space size
|
|
3227
|
-
* @param {
|
|
3557
|
+
* @param {TileInfo} [tileInfo] - Tile info for layer
|
|
3228
3558
|
* @param {Vector2} [scale=Vector2(1,1)] - How much to scale this layer when rendered
|
|
3229
3559
|
* @param {Number} [renderOrder=0] - Objects sorted by renderOrder before being rendered
|
|
3230
3560
|
*/
|
|
3231
|
-
constructor(pos, size=tileCollisionSize,
|
|
3561
|
+
constructor(pos, size=tileCollisionSize, tileInfo=tile(), scale=vec2(1), renderOrder=0)
|
|
3232
3562
|
{
|
|
3233
|
-
super(pos, size,
|
|
3563
|
+
super(pos, size, tileInfo, 0, undefined, renderOrder);
|
|
3234
3564
|
|
|
3235
3565
|
/** @property {HTMLCanvasElement} - The canvas used by this tile layer */
|
|
3236
3566
|
this.canvas = document.createElement('canvas');
|
|
@@ -3307,13 +3637,13 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
|
|
|
3307
3637
|
mainCanvas = this.canvas;
|
|
3308
3638
|
mainContext = this.context;
|
|
3309
3639
|
cameraPos = this.size.scale(.5);
|
|
3310
|
-
cameraScale = this.
|
|
3640
|
+
cameraScale = this.tileInfo.size.x;
|
|
3311
3641
|
|
|
3312
3642
|
if (clear)
|
|
3313
3643
|
{
|
|
3314
3644
|
// clear and set size
|
|
3315
|
-
mainCanvas.width = this.size.x * this.
|
|
3316
|
-
mainCanvas.height = this.size.y * this.
|
|
3645
|
+
mainCanvas.width = this.size.x * this.tileInfo.size.x;
|
|
3646
|
+
mainCanvas.height = this.size.y * this.tileInfo.size.y;
|
|
3317
3647
|
}
|
|
3318
3648
|
|
|
3319
3649
|
// begin a new render for the tile canvas
|
|
@@ -3344,7 +3674,8 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
|
|
|
3344
3674
|
if (d.tile != undefined)
|
|
3345
3675
|
{
|
|
3346
3676
|
ASSERT(mainContext == this.context); // must call redrawStart() before drawing tiles
|
|
3347
|
-
|
|
3677
|
+
const tileInfo = tile(d.tile, this.tileInfo.size, this.tileInfo.textureIndex);
|
|
3678
|
+
drawTile(pos, vec2(1), tileInfo, d.color, d.direction*PI/2, d.mirror);
|
|
3348
3679
|
}
|
|
3349
3680
|
}
|
|
3350
3681
|
|
|
@@ -3366,8 +3697,8 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
|
|
|
3366
3697
|
{
|
|
3367
3698
|
const context = this.context;
|
|
3368
3699
|
context.save();
|
|
3369
|
-
pos = pos.subtract(this.pos).multiply(this.
|
|
3370
|
-
size = size.multiply(this.
|
|
3700
|
+
pos = pos.subtract(this.pos).multiply(this.tileInfo.size);
|
|
3701
|
+
size = size.multiply(this.tileInfo.size);
|
|
3371
3702
|
context.translate(pos.x, this.canvas.height - pos.y);
|
|
3372
3703
|
context.rotate(angle);
|
|
3373
3704
|
context.scale(mirror ? -size.x : size.x, size.y);
|
|
@@ -3378,28 +3709,28 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
|
|
|
3378
3709
|
/** Draw a tile directly onto the layer canvas
|
|
3379
3710
|
* @param {Vector2} pos
|
|
3380
3711
|
* @param {Vector2} [size=Vector2(1,1)]
|
|
3381
|
-
* @param {
|
|
3382
|
-
* @param {Vector2} [tileSize=tileSizeDefault]
|
|
3712
|
+
* @param {TileInfo} [tileInfo]
|
|
3383
3713
|
* @param {Color} [color=Color()]
|
|
3384
3714
|
* @param {Number} [angle=0]
|
|
3385
3715
|
* @param {Boolean} [mirror=0] */
|
|
3386
|
-
drawTile(pos, size=vec2(1),
|
|
3716
|
+
drawTile(pos, size=vec2(1), tileInfo, color=new Color, angle, mirror)
|
|
3387
3717
|
{
|
|
3388
3718
|
this.drawCanvas2D(pos, size, angle, mirror, (context)=>
|
|
3389
3719
|
{
|
|
3390
|
-
|
|
3720
|
+
const textureInfo = tileInfo && tileInfo.getTextureInfo();
|
|
3721
|
+
if (textureInfo)
|
|
3391
3722
|
{
|
|
3392
|
-
//
|
|
3393
|
-
context.
|
|
3394
|
-
|
|
3723
|
+
context.globalAlpha = color.a; // only alpha is supported
|
|
3724
|
+
context.drawImage(textureInfo.image,
|
|
3725
|
+
tileInfo.pos.x, tileInfo.pos.y,
|
|
3726
|
+
tileInfo.size.x, tileInfo.size.y, -.5, -.5, 1, 1);
|
|
3727
|
+
context.globalAlpha = 1;
|
|
3395
3728
|
}
|
|
3396
3729
|
else
|
|
3397
3730
|
{
|
|
3398
|
-
|
|
3399
|
-
context.
|
|
3400
|
-
context.
|
|
3401
|
-
(tileIndex%cols)*tileSize.x, (tileIndex/cols|0)*tileSize.y,
|
|
3402
|
-
tileSize.x, tileSize.y, -.5, -.5, 1, 1);
|
|
3731
|
+
// untextured
|
|
3732
|
+
context.fillStyle = color;
|
|
3733
|
+
context.fillRect(-.5, -.5, 1, 1);
|
|
3403
3734
|
}
|
|
3404
3735
|
});
|
|
3405
3736
|
}
|
|
@@ -3416,7 +3747,7 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
|
|
|
3416
3747
|
* LittleJS Particle System
|
|
3417
3748
|
*/
|
|
3418
3749
|
|
|
3419
|
-
|
|
3750
|
+
|
|
3420
3751
|
|
|
3421
3752
|
/**
|
|
3422
3753
|
* Particle Emitter - Spawns particles with the given settings
|
|
@@ -3427,7 +3758,7 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
|
|
|
3427
3758
|
* let particleEmiter = new ParticleEmitter
|
|
3428
3759
|
* (
|
|
3429
3760
|
* pos, 0, 1, 0, 500, PI, // pos, angle, emitSize, emitTime, emitRate, emiteCone
|
|
3430
|
-
* 0,
|
|
3761
|
+
* tile(0, 16), // tileInfo
|
|
3431
3762
|
* new Color(1,1,1), new Color(0,0,0), // colorStartA, colorStartB
|
|
3432
3763
|
* new Color(1,1,1,0), new Color(0,0,0,0), // colorEndA, colorEndB
|
|
3433
3764
|
* 2, .2, .2, .1, .05, // particleTime, sizeStart, sizeEnd, particleSpeed, particleAngleSpeed
|
|
@@ -3444,8 +3775,7 @@ class ParticleEmitter extends EngineObject
|
|
|
3444
3775
|
* @param {Number} [emitTime=0] - How long to stay alive (0 is forever)
|
|
3445
3776
|
* @param {Number} [emitRate=100] - How many particles per second to spawn, does not emit if 0
|
|
3446
3777
|
* @param {Number} [emitConeAngle=PI] - Local angle to apply velocity to particles from emitter
|
|
3447
|
-
* @param {
|
|
3448
|
-
* @param {Vector2} [tileSize=tileSizeDefault] - Tile size for particles
|
|
3778
|
+
* @param {TileInfo} [tileInfo] - Tile info to render particles (undefined is untextured)
|
|
3449
3779
|
* @param {Color} [colorStartA=Color()] - Color at start of life 1, randomized between start colors
|
|
3450
3780
|
* @param {Color} [colorStartB=Color()] - Color at start of life 2, randomized between start colors
|
|
3451
3781
|
* @param {Color} [colorEndA=Color(1,1,1,0)] - Color at end of life 1, randomized between end colors
|
|
@@ -3475,8 +3805,7 @@ class ParticleEmitter extends EngineObject
|
|
|
3475
3805
|
emitTime = 0,
|
|
3476
3806
|
emitRate = 100,
|
|
3477
3807
|
emitConeAngle = PI,
|
|
3478
|
-
|
|
3479
|
-
tileSize = tileSizeDefault,
|
|
3808
|
+
tileInfo,
|
|
3480
3809
|
colorStartA = new Color,
|
|
3481
3810
|
colorStartB = new Color,
|
|
3482
3811
|
colorEndA = new Color(1,1,1,0),
|
|
@@ -3499,7 +3828,7 @@ class ParticleEmitter extends EngineObject
|
|
|
3499
3828
|
localSpace
|
|
3500
3829
|
)
|
|
3501
3830
|
{
|
|
3502
|
-
super(pos, vec2(),
|
|
3831
|
+
super(pos, vec2(), tileInfo, angle, undefined, renderOrder);
|
|
3503
3832
|
|
|
3504
3833
|
// emitter settings
|
|
3505
3834
|
/** @property {Number} - World space size of the emitter (float for circle diameter, vec2 for rect) */
|
|
@@ -3598,7 +3927,7 @@ class ParticleEmitter extends EngineObject
|
|
|
3598
3927
|
angle += this.angle;
|
|
3599
3928
|
}
|
|
3600
3929
|
|
|
3601
|
-
const particle = new Particle(pos, this.
|
|
3930
|
+
const particle = new Particle(pos, this.tileInfo, this.tileSize, angle);
|
|
3602
3931
|
|
|
3603
3932
|
// randomness scales each paremeter by a percentage
|
|
3604
3933
|
const randomness = this.randomness;
|
|
@@ -3658,12 +3987,11 @@ class Particle extends EngineObject
|
|
|
3658
3987
|
/**
|
|
3659
3988
|
* Create a particle with the given settings
|
|
3660
3989
|
* @param {Vector2} position - World space position of the particle
|
|
3661
|
-
* @param {
|
|
3662
|
-
* @param {Vector2} [tileSize=tileSizeDefault] - Size of tile in source pixels
|
|
3990
|
+
* @param {TileInfo} [tileInfo] - Tile info to render particles (undefined is untextured)
|
|
3663
3991
|
* @param {Number} [angle=0] - Angle to rotate the particle
|
|
3664
3992
|
*/
|
|
3665
|
-
constructor(pos,
|
|
3666
|
-
{ super(pos, vec2(),
|
|
3993
|
+
constructor(pos, tileInfo, angle)
|
|
3994
|
+
{ super(pos, vec2(), tileInfo, angle); }
|
|
3667
3995
|
|
|
3668
3996
|
/** Render the particle, automatically called each frame, sorted by renderOrder */
|
|
3669
3997
|
render()
|
|
@@ -3697,14 +4025,17 @@ class Particle extends EngineObject
|
|
|
3697
4025
|
if (this.localSpaceEmitter)
|
|
3698
4026
|
velocity = velocity.rotate(-this.localSpaceEmitter.angle);
|
|
3699
4027
|
const speed = velocity.length();
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
4028
|
+
if (speed)
|
|
4029
|
+
{
|
|
4030
|
+
const direction = velocity.scale(1/speed);
|
|
4031
|
+
const trailLength = speed * this.trailScale;
|
|
4032
|
+
size.y = max(size.x, trailLength);
|
|
4033
|
+
angle = direction.angle();
|
|
4034
|
+
drawTile(pos.add(direction.multiply(vec2(0,-trailLength/2))), size, this.tileInfo, color, angle, this.mirror);
|
|
4035
|
+
}
|
|
3705
4036
|
}
|
|
3706
4037
|
else
|
|
3707
|
-
drawTile(pos, size, this.
|
|
4038
|
+
drawTile(pos, size, this.tileInfo, color, angle, this.mirror);
|
|
3708
4039
|
this.additive && setBlendMode();
|
|
3709
4040
|
debugParticles && debugRect(pos, size, '#f005', 0, angle);
|
|
3710
4041
|
|
|
@@ -3726,7 +4057,7 @@ class Particle extends EngineObject
|
|
|
3726
4057
|
* @namespace Medals
|
|
3727
4058
|
*/
|
|
3728
4059
|
|
|
3729
|
-
|
|
4060
|
+
|
|
3730
4061
|
|
|
3731
4062
|
/** List of all medals
|
|
3732
4063
|
* @type {Array}
|
|
@@ -3751,7 +4082,7 @@ function medalsInit(saveName)
|
|
|
3751
4082
|
}
|
|
3752
4083
|
|
|
3753
4084
|
/**
|
|
3754
|
-
* Medal
|
|
4085
|
+
* Medal - Tracks an unlockable medal
|
|
3755
4086
|
* @example
|
|
3756
4087
|
* // create a medal
|
|
3757
4088
|
* const medal_example = new Medal(0, 'Example Medal', 'More info about the medal goes here.', '🎖️');
|
|
@@ -3764,7 +4095,7 @@ function medalsInit(saveName)
|
|
|
3764
4095
|
*/
|
|
3765
4096
|
class Medal
|
|
3766
4097
|
{
|
|
3767
|
-
/** Create
|
|
4098
|
+
/** Create a medal object and adds it to the list of medals
|
|
3768
4099
|
* @param {Number} id - The unique identifier of the medal
|
|
3769
4100
|
* @param {String} name - Name of the medal
|
|
3770
4101
|
* @param {String} [description] - Description of the medal
|
|
@@ -3876,33 +4207,33 @@ let newgrounds;
|
|
|
3876
4207
|
/** This can used to enable Newgrounds functionality
|
|
3877
4208
|
* @param {Number} app_id - The newgrounds App ID
|
|
3878
4209
|
* @param {String} [cipher] - The encryption Key (AES-128/Base64)
|
|
4210
|
+
* @param {Object} [cryptoJS] - An instance of CryptoJS, if there is a cipher
|
|
3879
4211
|
* @memberof Medals */
|
|
3880
|
-
function newgroundsInit(app_id, cipher
|
|
4212
|
+
function newgroundsInit(app_id, cipher, cryptoJS)
|
|
4213
|
+
{ newgrounds = new Newgrounds(app_id, cipher, cryptoJS); }
|
|
3881
4214
|
|
|
3882
4215
|
/**
|
|
3883
4216
|
* Newgrounds API wrapper object
|
|
3884
4217
|
* @example
|
|
3885
|
-
* // create a newgrounds object, replace the app id
|
|
4218
|
+
* // create a newgrounds object, replace the app id with your own
|
|
3886
4219
|
* const app_id = '53123:1ZuSTQ9l';
|
|
3887
|
-
*
|
|
3888
|
-
* newgrounds = new Newgrounds(app_id, cipher);
|
|
4220
|
+
* newgrounds = new Newgrounds(app_id);
|
|
3889
4221
|
*/
|
|
3890
4222
|
class Newgrounds
|
|
3891
4223
|
{
|
|
3892
4224
|
/** Create a newgrounds object
|
|
3893
4225
|
* @param {Number} app_id - The newgrounds App ID
|
|
3894
|
-
* @param {String} [cipher] - The encryption Key (AES-128/Base64)
|
|
3895
|
-
|
|
4226
|
+
* @param {String} [cipher] - The encryption Key (AES-128/Base64)
|
|
4227
|
+
* @param {Object} [cryptoJS] - An instance of CryptoJS, if there is a cipher */
|
|
4228
|
+
constructor(app_id, cipher, cryptoJS)
|
|
3896
4229
|
{
|
|
3897
|
-
ASSERT(!newgrounds && app_id);
|
|
4230
|
+
ASSERT(!newgrounds && app_id); // can only be one newgrounds object
|
|
4231
|
+
ASSERT(!cipher || cryptoJS); // must provide cryptojs if there is a cipher
|
|
3898
4232
|
|
|
3899
4233
|
this.app_id = app_id;
|
|
3900
4234
|
this.cipher = cipher;
|
|
4235
|
+
this.cryptoJS = cryptoJS;
|
|
3901
4236
|
this.host = location ? location.hostname : '';
|
|
3902
|
-
|
|
3903
|
-
// create an instance of CryptoJS for encrypted calls
|
|
3904
|
-
if (cipher)
|
|
3905
|
-
this.cryptoJS = this.CryptoJS();
|
|
3906
4237
|
|
|
3907
4238
|
// get session id from url search params
|
|
3908
4239
|
const url = new URL(location.href);
|
|
@@ -4006,38 +4337,6 @@ class Newgrounds
|
|
|
4006
4337
|
debugMedals && console.log(xmlHttp.responseText);
|
|
4007
4338
|
return xmlHttp.responseText && JSON.parse(xmlHttp.responseText);
|
|
4008
4339
|
}
|
|
4009
|
-
|
|
4010
|
-
CryptoJS()
|
|
4011
|
-
{
|
|
4012
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
4013
|
-
// Crypto-JS - https://github.com/brix/crypto-js - MIT License
|
|
4014
|
-
//
|
|
4015
|
-
// [The MIT License (MIT)](http://opensource.org/licenses/MIT)
|
|
4016
|
-
//
|
|
4017
|
-
// Copyright (c) 2009-2013 Jeff Mott
|
|
4018
|
-
// Copyright (c) 2013-2016 Evan Vosberg
|
|
4019
|
-
//
|
|
4020
|
-
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4021
|
-
// of this software and associated documentation files (the "Software"), to deal
|
|
4022
|
-
// in the Software without restriction, including without limitation the rights
|
|
4023
|
-
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
4024
|
-
// copies of the Software, and to permit persons to whom the Software is
|
|
4025
|
-
// furnished to do so, subject to the following conditions:
|
|
4026
|
-
//
|
|
4027
|
-
// The above copyright notice and this permission notice shall be included in
|
|
4028
|
-
// all copies or substantial portions of the Software.
|
|
4029
|
-
//
|
|
4030
|
-
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
4031
|
-
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
4032
|
-
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
4033
|
-
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
4034
|
-
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
4035
|
-
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
4036
|
-
// THE SOFTWARE.
|
|
4037
|
-
return 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));
|
|
4038
|
-
// end of Crypto-JS
|
|
4039
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
4040
|
-
}
|
|
4041
4340
|
}
|
|
4042
4341
|
/**
|
|
4043
4342
|
* LittleJS WebGL Interface
|
|
@@ -4047,10 +4346,11 @@ class Newgrounds
|
|
|
4047
4346
|
* - Can be disabled with glEnable to revert to 2D canvas rendering
|
|
4048
4347
|
* - Batches sprite rendering on GPU for incredibly fast performance
|
|
4049
4348
|
* - Sprite transform math is done in the shader where possible
|
|
4349
|
+
* - Supports shadertoy style post processing shaders
|
|
4050
4350
|
* @namespace WebGL
|
|
4051
4351
|
*/
|
|
4052
4352
|
|
|
4053
|
-
|
|
4353
|
+
|
|
4054
4354
|
|
|
4055
4355
|
/** The WebGL canvas which appears above the main canvas and below the overlay canvas
|
|
4056
4356
|
* @type {HTMLCanvasElement}
|
|
@@ -4062,45 +4362,42 @@ let glCanvas;
|
|
|
4062
4362
|
* @memberof WebGL */
|
|
4063
4363
|
let glContext;
|
|
4064
4364
|
|
|
4065
|
-
/** Main tile sheet texture automatically loaded by engine
|
|
4066
|
-
* @type {WebGLTexture}
|
|
4067
|
-
* @memberof WebGL */
|
|
4068
|
-
let glTileTexture;
|
|
4069
|
-
|
|
4070
4365
|
// WebGL internal variables not exposed to documentation
|
|
4071
4366
|
let glActiveTexture, glShader, glArrayBuffer, glPositionData, glColorData, glBatchCount, glBatchAdditive, glAdditive;
|
|
4072
4367
|
|
|
4073
4368
|
///////////////////////////////////////////////////////////////////////////////
|
|
4074
4369
|
|
|
4075
|
-
//
|
|
4370
|
+
// Initalize WebGL, called automatically by the engine
|
|
4076
4371
|
function glInit()
|
|
4077
4372
|
{
|
|
4078
|
-
// create the canvas and
|
|
4373
|
+
// create the canvas and textures
|
|
4079
4374
|
glCanvas = document.createElement('canvas');
|
|
4080
|
-
glContext = glCanvas.getContext('
|
|
4081
|
-
glTileTexture = glCreateTexture(tileImage);
|
|
4375
|
+
glContext = glCanvas.getContext('webgl2');
|
|
4082
4376
|
|
|
4083
4377
|
// some browsers are much faster without copying the gl buffer so we just overlay it instead
|
|
4084
4378
|
glOverlay && document.body.appendChild(glCanvas);
|
|
4085
4379
|
|
|
4086
4380
|
// setup vertex and fragment shaders
|
|
4087
4381
|
glShader = glCreateProgram(
|
|
4382
|
+
'#version 300 es\n' + // specify GLSL ES version
|
|
4088
4383
|
'precision highp float;'+ // use highp for better accuracy
|
|
4089
4384
|
'uniform mat4 m;'+ // transform matrix
|
|
4090
|
-
'
|
|
4091
|
-
'
|
|
4092
|
-
'
|
|
4385
|
+
'in vec2 p,t;'+ // position, uv
|
|
4386
|
+
'in vec4 c,a;'+ // color, additiveColor
|
|
4387
|
+
'out vec4 v,d,e;'+ // return uv, color, additiveColor
|
|
4093
4388
|
'void main(){'+ // shader entry point
|
|
4094
4389
|
'gl_Position=m*vec4(p,1,1);'+ // transform position
|
|
4095
4390
|
'v=vec4(t,p);d=c;e=a;'+ // pass stuff to fragment shader
|
|
4096
4391
|
'}' // end of shader
|
|
4097
4392
|
,
|
|
4098
|
-
'
|
|
4099
|
-
'
|
|
4100
|
-
'
|
|
4101
|
-
'
|
|
4102
|
-
'
|
|
4103
|
-
'
|
|
4393
|
+
'#version 300 es\n' + // specify GLSL ES version
|
|
4394
|
+
'precision highp float;'+ // use highp for better accuracy
|
|
4395
|
+
'in vec4 v,d,e;'+ // uv, color, additiveColor
|
|
4396
|
+
'uniform sampler2D s;'+ // texture
|
|
4397
|
+
'out vec4 c;'+ // out color
|
|
4398
|
+
'void main(){'+ // shader entry point
|
|
4399
|
+
'c=texture(s,v.xy)*d+e;'+ // modulate texture by color plus additive
|
|
4400
|
+
'}' // end of shader
|
|
4104
4401
|
);
|
|
4105
4402
|
|
|
4106
4403
|
// init buffers
|
|
@@ -4111,25 +4408,68 @@ function glInit()
|
|
|
4111
4408
|
glBatchCount = 0;
|
|
4112
4409
|
}
|
|
4113
4410
|
|
|
4411
|
+
// Setup render each frame, called automatically by engine
|
|
4412
|
+
function glPreRender()
|
|
4413
|
+
{
|
|
4414
|
+
// clear and set to same size as main canvas
|
|
4415
|
+
glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
|
|
4416
|
+
glContext.clear(gl_COLOR_BUFFER_BIT);
|
|
4417
|
+
|
|
4418
|
+
// set up the shader
|
|
4419
|
+
glContext.useProgram(glShader);
|
|
4420
|
+
glContext.activeTexture(gl_TEXTURE0);
|
|
4421
|
+
glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = textureInfos[0].glTexture);
|
|
4422
|
+
glContext.bindBuffer(gl_ARRAY_BUFFER, glArrayBuffer);
|
|
4423
|
+
glContext.bufferData(gl_ARRAY_BUFFER, gl_VERTEX_BUFFER_SIZE, gl_DYNAMIC_DRAW);
|
|
4424
|
+
glSetBlendMode();
|
|
4425
|
+
|
|
4426
|
+
// set vertex attributes
|
|
4427
|
+
let offset = 0;
|
|
4428
|
+
const initVertexAttribArray = (name, type, typeSize, size, normalize=0)=>
|
|
4429
|
+
{
|
|
4430
|
+
const location = glContext.getAttribLocation(glShader, name);
|
|
4431
|
+
glContext.enableVertexAttribArray(location);
|
|
4432
|
+
glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
|
|
4433
|
+
offset += size*typeSize;
|
|
4434
|
+
}
|
|
4435
|
+
initVertexAttribArray('p', gl_FLOAT, 4, 2); // position
|
|
4436
|
+
initVertexAttribArray('t', gl_FLOAT, 4, 2); // texture coords
|
|
4437
|
+
initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
|
|
4438
|
+
initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
|
|
4439
|
+
|
|
4440
|
+
// build the transform matrix
|
|
4441
|
+
const sx = 2 * cameraScale / mainCanvas.width;
|
|
4442
|
+
const sy = 2 * cameraScale / mainCanvas.height;
|
|
4443
|
+
glContext.uniformMatrix4fv(glContext.getUniformLocation(glShader, 'm'), 0,
|
|
4444
|
+
new Float32Array([
|
|
4445
|
+
sx, 0, 0, 0,
|
|
4446
|
+
0, sy, 0, 0,
|
|
4447
|
+
1, 1, -1, 1,
|
|
4448
|
+
-1-sx*cameraPos.x, -1-sy*cameraPos.y, 0, 0
|
|
4449
|
+
])
|
|
4450
|
+
);
|
|
4451
|
+
}
|
|
4452
|
+
|
|
4114
4453
|
/** Set the WebGl blend mode, normally you should call setBlendMode instead
|
|
4115
4454
|
* @param {Boolean} [additive=0]
|
|
4116
4455
|
* @memberof WebGL */
|
|
4117
|
-
function glSetBlendMode(additive)
|
|
4456
|
+
function glSetBlendMode(additive=0)
|
|
4118
4457
|
{
|
|
4119
4458
|
// setup blending
|
|
4120
4459
|
glAdditive = additive;
|
|
4121
4460
|
}
|
|
4122
4461
|
|
|
4123
|
-
/** Set the WebGl texture,
|
|
4462
|
+
/** Set the WebGl texture, called automatically if using multiple textures
|
|
4124
4463
|
* - This may also flush the gl buffer resulting in more draw calls and worse performance
|
|
4125
|
-
* @param {WebGLTexture}
|
|
4464
|
+
* @param {WebGLTexture} texture
|
|
4126
4465
|
* @memberof WebGL */
|
|
4127
|
-
function glSetTexture(texture
|
|
4466
|
+
function glSetTexture(texture)
|
|
4128
4467
|
{
|
|
4129
4468
|
// must flush cache with the old texture to set a new one
|
|
4130
|
-
if (texture
|
|
4131
|
-
|
|
4469
|
+
if (texture == glActiveTexture)
|
|
4470
|
+
return;
|
|
4132
4471
|
|
|
4472
|
+
glFlush();
|
|
4133
4473
|
glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = texture);
|
|
4134
4474
|
}
|
|
4135
4475
|
|
|
@@ -4190,48 +4530,6 @@ function glCreateTexture(image)
|
|
|
4190
4530
|
return texture;
|
|
4191
4531
|
}
|
|
4192
4532
|
|
|
4193
|
-
// called automatically by engine before render
|
|
4194
|
-
function glPreRender()
|
|
4195
|
-
{
|
|
4196
|
-
// clear and set to same size as main canvas
|
|
4197
|
-
glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
|
|
4198
|
-
glContext.clear(gl_COLOR_BUFFER_BIT);
|
|
4199
|
-
|
|
4200
|
-
// set up the shader
|
|
4201
|
-
glContext.useProgram(glShader);
|
|
4202
|
-
glContext.activeTexture(gl_TEXTURE0);
|
|
4203
|
-
glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = glTileTexture);
|
|
4204
|
-
glContext.bindBuffer(gl_ARRAY_BUFFER, glArrayBuffer);
|
|
4205
|
-
glContext.bufferData(gl_ARRAY_BUFFER, gl_VERTEX_BUFFER_SIZE, gl_DYNAMIC_DRAW);
|
|
4206
|
-
glSetBlendMode();
|
|
4207
|
-
|
|
4208
|
-
// set vertex attributes
|
|
4209
|
-
let offset = 0;
|
|
4210
|
-
const initVertexAttribArray = (name, type, typeSize, size, normalize=0)=>
|
|
4211
|
-
{
|
|
4212
|
-
const location = glContext.getAttribLocation(glShader, name);
|
|
4213
|
-
glContext.enableVertexAttribArray(location);
|
|
4214
|
-
glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
|
|
4215
|
-
offset += size*typeSize;
|
|
4216
|
-
}
|
|
4217
|
-
initVertexAttribArray('p', gl_FLOAT, 4, 2); // position
|
|
4218
|
-
initVertexAttribArray('t', gl_FLOAT, 4, 2); // texture coords
|
|
4219
|
-
initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
|
|
4220
|
-
initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
|
|
4221
|
-
|
|
4222
|
-
// build the transform matrix
|
|
4223
|
-
const sx = 2 * cameraScale / mainCanvas.width;
|
|
4224
|
-
const sy = 2 * cameraScale / mainCanvas.height;
|
|
4225
|
-
glContext.uniformMatrix4fv(glContext.getUniformLocation(glShader, 'm'), 0,
|
|
4226
|
-
new Float32Array([
|
|
4227
|
-
sx, 0, 0, 0,
|
|
4228
|
-
0, sy, 0, 0,
|
|
4229
|
-
1, 1, -1, 1,
|
|
4230
|
-
-1-sx*cameraPos.x, -1-sy*cameraPos.y, 0, 0
|
|
4231
|
-
])
|
|
4232
|
-
);
|
|
4233
|
-
}
|
|
4234
|
-
|
|
4235
4533
|
/** Draw all sprites and clear out the buffer, called automatically by the system whenever necessary
|
|
4236
4534
|
* @memberof WebGL */
|
|
4237
4535
|
function glFlush()
|
|
@@ -4350,25 +4648,28 @@ function glInitPostProcess(shaderCode, includeOverlay)
|
|
|
4350
4648
|
{
|
|
4351
4649
|
ASSERT(!glPostShader); // can only have 1 post effects shader
|
|
4352
4650
|
|
|
4353
|
-
if (!shaderCode) // default shader
|
|
4354
|
-
shaderCode = 'void mainImage(out vec4 c,vec2 p){c=
|
|
4651
|
+
if (!shaderCode) // default shader pass through
|
|
4652
|
+
shaderCode = 'void mainImage(out vec4 c,vec2 p){c=texture(iChannel0,p/iResolution.xy);}';
|
|
4355
4653
|
|
|
4356
4654
|
// create the shader
|
|
4357
4655
|
glPostShader = glCreateProgram(
|
|
4656
|
+
'#version 300 es\n' + // specify GLSL ES version
|
|
4358
4657
|
'precision highp float;'+ // use highp for better accuracy
|
|
4359
|
-
'
|
|
4658
|
+
'in vec2 p;'+ // position
|
|
4360
4659
|
'void main(){'+ // shader entry point
|
|
4361
4660
|
'gl_Position=vec4(p,1,1);'+ // set position
|
|
4362
4661
|
'}' // end of shader
|
|
4363
4662
|
,
|
|
4663
|
+
'#version 300 es\n' + // specify GLSL ES version
|
|
4364
4664
|
'precision highp float;'+ // use highp for better accuracy
|
|
4365
4665
|
'uniform sampler2D iChannel0;'+ // input texture
|
|
4366
4666
|
'uniform vec3 iResolution;'+ // size of output texture
|
|
4367
4667
|
'uniform float iTime;'+ // time passed
|
|
4668
|
+
'out vec4 c;'+ // out color
|
|
4368
4669
|
'\n' + shaderCode + '\n'+ // insert custom shader code
|
|
4369
4670
|
'void main(){'+ // shader entry point
|
|
4370
|
-
'mainImage(
|
|
4371
|
-
'
|
|
4671
|
+
'mainImage(c,gl_FragCoord.xy);'+ // call post process function
|
|
4672
|
+
'c.a=1.;'+ // always use full alpha
|
|
4372
4673
|
'}' // end of shader
|
|
4373
4674
|
);
|
|
4374
4675
|
|
|
@@ -4441,7 +4742,6 @@ gl_ONE_MINUS_SRC_ALPHA = 771,
|
|
|
4441
4742
|
gl_BLEND = 3042,
|
|
4442
4743
|
gl_TEXTURE_2D = 3553,
|
|
4443
4744
|
gl_UNSIGNED_BYTE = 5121,
|
|
4444
|
-
gl_BYTE = 5120,
|
|
4445
4745
|
gl_FLOAT = 5126,
|
|
4446
4746
|
gl_RGBA = 6408,
|
|
4447
4747
|
gl_NEAREST = 9728,
|
|
@@ -4453,7 +4753,6 @@ gl_TEXTURE_WRAP_T = 10243,
|
|
|
4453
4753
|
gl_COLOR_BUFFER_BIT = 16384,
|
|
4454
4754
|
gl_CLAMP_TO_EDGE = 33071,
|
|
4455
4755
|
gl_TEXTURE0 = 33984,
|
|
4456
|
-
gl_TEXTURE1 = 33985,
|
|
4457
4756
|
gl_ARRAY_BUFFER = 34962,
|
|
4458
4757
|
gl_STATIC_DRAW = 35044,
|
|
4459
4758
|
gl_DYNAMIC_DRAW = 35048,
|
|
@@ -4464,7 +4763,6 @@ gl_LINK_STATUS = 35714,
|
|
|
4464
4763
|
gl_UNPACK_FLIP_Y_WEBGL = 37440,
|
|
4465
4764
|
|
|
4466
4765
|
// constants for batch rendering
|
|
4467
|
-
gl_VERTICES_PER_QUAD = 6,
|
|
4468
4766
|
gl_INDICIES_PER_VERT = 6,
|
|
4469
4767
|
gl_MAX_BATCH = 1e5,
|
|
4470
4768
|
gl_VERTEX_BYTE_STRIDE = (4 * 2) * 2 + (4) * 2, // vec2 * 2 + (char * 4) * 2
|
|
@@ -4489,7 +4787,7 @@ gl_VERTEX_BUFFER_SIZE = gl_MAX_BATCH * gl_VERTEX_BYTE_STRIDE;
|
|
|
4489
4787
|
* @namespace Engine
|
|
4490
4788
|
*/
|
|
4491
4789
|
|
|
4492
|
-
|
|
4790
|
+
|
|
4493
4791
|
|
|
4494
4792
|
/** Name of engine
|
|
4495
4793
|
* @type {String}
|
|
@@ -4501,7 +4799,7 @@ const engineName = 'LittleJS';
|
|
|
4501
4799
|
* @type {String}
|
|
4502
4800
|
* @default
|
|
4503
4801
|
* @memberof Engine */
|
|
4504
|
-
const engineVersion = '1.
|
|
4802
|
+
const engineVersion = '1.8.1';
|
|
4505
4803
|
|
|
4506
4804
|
/** Frames per second to update objects
|
|
4507
4805
|
* @type {Number}
|
|
@@ -4551,6 +4849,9 @@ let paused = 0;
|
|
|
4551
4849
|
* @memberof Engine */
|
|
4552
4850
|
function setPaused(_paused) { paused = _paused; }
|
|
4553
4851
|
|
|
4852
|
+
// Frame time tracking
|
|
4853
|
+
let frameTimeLastMS = 0, frameTimeBufferMS = 0, averageFPS = 0;
|
|
4854
|
+
|
|
4554
4855
|
///////////////////////////////////////////////////////////////////////////////
|
|
4555
4856
|
|
|
4556
4857
|
/** Start up LittleJS engine with your callback functions
|
|
@@ -4559,49 +4860,13 @@ function setPaused(_paused) { paused = _paused; }
|
|
|
4559
4860
|
* @param {Function} gameUpdatePost - Called after physics and objects are updated, setup camera and prepare for render
|
|
4560
4861
|
* @param {Function} gameRender - Called before objects are rendered, draw any background effects that appear behind objects
|
|
4561
4862
|
* @param {Function} gameRenderPost - Called after objects are rendered, draw effects or hud that appear above all objects
|
|
4562
|
-
* @param {String} [
|
|
4863
|
+
* @param {String} [imageSources='tiles.png'] - Image to load
|
|
4563
4864
|
* @memberof Engine */
|
|
4564
|
-
function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost,
|
|
4865
|
+
function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=['tiles.png'])
|
|
4565
4866
|
{
|
|
4566
|
-
//
|
|
4567
|
-
tileImage.onerror = tileImage.onload = ()=>
|
|
4568
|
-
{
|
|
4569
|
-
// save tile image info
|
|
4570
|
-
tileImageFixBleed = vec2(tileFixBleedScale).divide(tileImageSize = vec2(tileImage.width, tileImage.height));
|
|
4571
|
-
debug && (tileImage.onload=()=>ASSERT(1)); // tile sheet can not reloaded
|
|
4572
|
-
|
|
4573
|
-
// setup html
|
|
4574
|
-
const styleBody = 'margin:0;overflow:hidden;' + // fill the window
|
|
4575
|
-
'background:#000;' + // set background color
|
|
4576
|
-
'touch-action:none;' + // prevent mobile pinch to resize
|
|
4577
|
-
'user-select:none;' + // prevent mobile hold to select
|
|
4578
|
-
'-webkit-user-select:none'; // compatibility for ios
|
|
4579
|
-
document.body.style = styleBody;
|
|
4580
|
-
document.body.appendChild(mainCanvas = document.createElement('canvas'));
|
|
4581
|
-
mainContext = mainCanvas.getContext('2d');
|
|
4582
|
-
|
|
4583
|
-
// init stuff and start engine
|
|
4584
|
-
debugInit();
|
|
4585
|
-
glEnable && glInit();
|
|
4586
|
-
|
|
4587
|
-
// create overlay canvas for hud to appear above gl canvas
|
|
4588
|
-
document.body.appendChild(overlayCanvas = document.createElement('canvas'));
|
|
4589
|
-
overlayContext = overlayCanvas.getContext('2d');
|
|
4590
|
-
|
|
4591
|
-
// set canvas style
|
|
4592
|
-
const styleCanvas = 'position:absolute;' +
|
|
4593
|
-
'top:50%;left:50%;transform:translate(-50%,-50%);' + // center the canvas
|
|
4594
|
-
(canvasPixelated?'image-rendering:pixelated':''); // set pixelated rendering
|
|
4595
|
-
(glCanvas||mainCanvas).style = mainCanvas.style = overlayCanvas.style = styleCanvas;
|
|
4596
|
-
|
|
4597
|
-
gameInit();
|
|
4598
|
-
engineUpdate();
|
|
4599
|
-
};
|
|
4867
|
+
ASSERT(Array.isArray(imageSources)); // pass in images as array
|
|
4600
4868
|
|
|
4601
|
-
//
|
|
4602
|
-
let frameTimeLastMS = 0, frameTimeBufferMS = 0, averageFPS = 0;
|
|
4603
|
-
|
|
4604
|
-
// main update loop
|
|
4869
|
+
// internal update loop for engine
|
|
4605
4870
|
function engineUpdate(frameTimeMS=0)
|
|
4606
4871
|
{
|
|
4607
4872
|
// update time keeping
|
|
@@ -4632,9 +4897,9 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4632
4897
|
}
|
|
4633
4898
|
else
|
|
4634
4899
|
{
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4900
|
+
// clear canvas and set size to same as window
|
|
4901
|
+
mainCanvas.width = min(innerWidth, canvasMaxSize.x);
|
|
4902
|
+
mainCanvas.height = min(innerHeight, canvasMaxSize.y);
|
|
4638
4903
|
}
|
|
4639
4904
|
|
|
4640
4905
|
// clear overlay canvas and set size
|
|
@@ -4666,6 +4931,9 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4666
4931
|
// update multiple frames if necessary in case of slow framerate
|
|
4667
4932
|
for (;frameTimeBufferMS >= 0; frameTimeBufferMS -= 1e3 / frameRate)
|
|
4668
4933
|
{
|
|
4934
|
+
// increment frame and update time
|
|
4935
|
+
time = frame++ / frameRate;
|
|
4936
|
+
|
|
4669
4937
|
// update game and objects
|
|
4670
4938
|
inputUpdate();
|
|
4671
4939
|
gameUpdate();
|
|
@@ -4713,8 +4981,51 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4713
4981
|
requestAnimationFrame(engineUpdate);
|
|
4714
4982
|
}
|
|
4715
4983
|
|
|
4716
|
-
//
|
|
4717
|
-
|
|
4984
|
+
// setup html
|
|
4985
|
+
const styleBody =
|
|
4986
|
+
'margin:0;overflow:hidden;' + // fill the window
|
|
4987
|
+
'background:#000;' + // set background color
|
|
4988
|
+
'touch-action:none;' + // prevent mobile pinch to resize
|
|
4989
|
+
'user-select:none;' + // prevent mobile hold to select
|
|
4990
|
+
'-webkit-user-select:none;' + // compatibility for ios
|
|
4991
|
+
'-webkit-touch-callout:none'; // compatibility for ios
|
|
4992
|
+
document.body.style = styleBody;
|
|
4993
|
+
document.body.appendChild(mainCanvas = document.createElement('canvas'));
|
|
4994
|
+
mainContext = mainCanvas.getContext('2d');
|
|
4995
|
+
|
|
4996
|
+
// init stuff and start engine
|
|
4997
|
+
debugInit();
|
|
4998
|
+
glEnable && glInit();
|
|
4999
|
+
|
|
5000
|
+
// create overlay canvas for hud to appear above gl canvas
|
|
5001
|
+
document.body.appendChild(overlayCanvas = document.createElement('canvas'));
|
|
5002
|
+
overlayContext = overlayCanvas.getContext('2d');
|
|
5003
|
+
|
|
5004
|
+
// set canvas style
|
|
5005
|
+
const styleCanvas =
|
|
5006
|
+
'position:absolute;' + // position
|
|
5007
|
+
'top:50%;left:50%;transform:translate(-50%,-50%);' + // center
|
|
5008
|
+
(canvasPixelated?'image-rendering:pixelated':''); // pixelated rendering
|
|
5009
|
+
(glCanvas||mainCanvas).style = mainCanvas.style = overlayCanvas.style = styleCanvas;
|
|
5010
|
+
|
|
5011
|
+
// load all of the images
|
|
5012
|
+
Promise.all(imageSources.map((src, textureIndex)=>
|
|
5013
|
+
new Promise((resolve, reject)=>
|
|
5014
|
+
{
|
|
5015
|
+
const image = new Image;
|
|
5016
|
+
image.onerror = image.onload = ()=>
|
|
5017
|
+
{
|
|
5018
|
+
textureInfos[textureIndex] = new TextureInfo(image);
|
|
5019
|
+
resolve();
|
|
5020
|
+
}
|
|
5021
|
+
image.src = src;
|
|
5022
|
+
})
|
|
5023
|
+
)).then(()=>
|
|
5024
|
+
{
|
|
5025
|
+
// start the engine
|
|
5026
|
+
gameInit();
|
|
5027
|
+
engineUpdate();
|
|
5028
|
+
});
|
|
4718
5029
|
}
|
|
4719
5030
|
|
|
4720
5031
|
// Called automatically by engine to setup render system
|
|
@@ -4752,9 +5063,6 @@ function engineObjectsUpdate()
|
|
|
4752
5063
|
|
|
4753
5064
|
// remove destroyed objects
|
|
4754
5065
|
engineObjects = engineObjects.filter(o=>!o.destroyed);
|
|
4755
|
-
|
|
4756
|
-
// increment frame and update time
|
|
4757
|
-
time = ++frame / frameRate;
|
|
4758
5066
|
}
|
|
4759
5067
|
|
|
4760
5068
|
/** Destroy and remove all objects
|
|
@@ -4797,196 +5105,6 @@ function engineObjectsCallback(pos, size, callbackFunction, objects=engineObject
|
|
|
4797
5105
|
* - Export engine as a module with functions where necessary
|
|
4798
5106
|
*/
|
|
4799
5107
|
|
|
4800
|
-
/** Set position of camera in world space
|
|
4801
|
-
* @param {Vector2} pos
|
|
4802
|
-
* @memberof Settings */
|
|
4803
|
-
function setCameraPos(pos) { cameraPos = pos; }
|
|
4804
|
-
|
|
4805
|
-
/** Set scale of camera in world space
|
|
4806
|
-
* @param {Number} scale
|
|
4807
|
-
* @memberof Settings */
|
|
4808
|
-
function setCameraScale(scale) { cameraScale = scale; }
|
|
4809
|
-
|
|
4810
|
-
/** Set max size of the canvas
|
|
4811
|
-
* @param {Vector2} size
|
|
4812
|
-
* @memberof Settings */
|
|
4813
|
-
function setCanvasMaxSize(size) { canvasMaxSize = size; }
|
|
4814
|
-
|
|
4815
|
-
/** Set fixed size of the canvas
|
|
4816
|
-
* @param {Vector2} size
|
|
4817
|
-
* @memberof Settings */
|
|
4818
|
-
function setCanvasFixedSize(size) { canvasFixedSize = size; }
|
|
4819
|
-
|
|
4820
|
-
/** Disables anti aliasing for pixel art if true
|
|
4821
|
-
* @param {Boolean} pixelated
|
|
4822
|
-
* @memberof Settings */
|
|
4823
|
-
function setCanvasPixelated(pixelated) { canvasPixelated = pixelated; }
|
|
4824
|
-
|
|
4825
|
-
/** Set default font used for text rendering
|
|
4826
|
-
* @param {String} font
|
|
4827
|
-
* @memberof Settings */
|
|
4828
|
-
function setFontDefault(font) { fontDefault = font; }
|
|
4829
|
-
|
|
4830
|
-
/** Set if webgl rendering is enabled
|
|
4831
|
-
* @param {Boolean} enable
|
|
4832
|
-
* @memberof Settings */
|
|
4833
|
-
function setGlEnable(enable) { glEnable = enable; }
|
|
4834
|
-
|
|
4835
|
-
/** Set to not composite the WebGL canvas
|
|
4836
|
-
* @param {Boolean} overlay
|
|
4837
|
-
* @memberof Settings */
|
|
4838
|
-
function setGlOverlay(overlay) { glOverlay = overlay; }
|
|
4839
|
-
|
|
4840
|
-
/** Set default size of tiles in pixels
|
|
4841
|
-
* @param {Vector2} size
|
|
4842
|
-
* @memberof Settings */
|
|
4843
|
-
function setTileSizeDefault(size) { tileSizeDefault = size; }
|
|
4844
|
-
|
|
4845
|
-
/** Set to prevent tile bleeding from neighbors in pixels
|
|
4846
|
-
* @param {Number} scale
|
|
4847
|
-
* @memberof Settings */
|
|
4848
|
-
function setTileFixBleedScale(scale) { tileFixBleedScale = scale; }
|
|
4849
|
-
|
|
4850
|
-
/** Set if collisions between objects are enabled
|
|
4851
|
-
* @param {Boolean} enable
|
|
4852
|
-
* @memberof Settings */
|
|
4853
|
-
function setEnablePhysicsSolver(enable) { enablePhysicsSolver = enable; }
|
|
4854
|
-
|
|
4855
|
-
/** Set default object mass for collison calcuations
|
|
4856
|
-
* @param {Number} mass
|
|
4857
|
-
* @memberof Settings */
|
|
4858
|
-
function setObjectDefaultMass(mass) { objectDefaultMass = mass; }
|
|
4859
|
-
|
|
4860
|
-
/** Set how much to slow velocity by each frame
|
|
4861
|
-
* @param {Number} damping
|
|
4862
|
-
* @memberof Settings */
|
|
4863
|
-
function setObjectDefaultDamping(damp) { objectDefaultDamping = damp; }
|
|
4864
|
-
|
|
4865
|
-
/** Set how much to slow angular velocity each frame
|
|
4866
|
-
* @param {Number} damping
|
|
4867
|
-
* @memberof Settings */
|
|
4868
|
-
function setObjectDefaultAngleDamping(damp) { objectDefaultAngleDamping = damp; }
|
|
4869
|
-
|
|
4870
|
-
/** Set how much to bounce when a collision occur
|
|
4871
|
-
* @param {Number} elasticity
|
|
4872
|
-
* @memberof Settings */
|
|
4873
|
-
function setObjectDefaultElasticity(elasticity) { objectDefaultElasticity = elasticity; }
|
|
4874
|
-
|
|
4875
|
-
/** Set how much to slow when touching
|
|
4876
|
-
* @param {Number} friction
|
|
4877
|
-
* @memberof Settings */
|
|
4878
|
-
function setObjectDefaultFriction(friction) { objectDefaultFriction = friction; }
|
|
4879
|
-
|
|
4880
|
-
/** Set max speed to avoid fast objects missing collisions
|
|
4881
|
-
* @param {Number} speed
|
|
4882
|
-
* @memberof Settings */
|
|
4883
|
-
function setObjectMaxSpeed(speed) { objectMaxSpeed = speed; }
|
|
4884
|
-
|
|
4885
|
-
/** Set how much gravity to apply to objects along the Y axis
|
|
4886
|
-
* @param {Number} gravity
|
|
4887
|
-
* @memberof Settings */
|
|
4888
|
-
function setGravity(g) { gravity = g; }
|
|
4889
|
-
|
|
4890
|
-
/** Set to scales emit rate of particles
|
|
4891
|
-
* @param {Number} scale
|
|
4892
|
-
* @memberof Settings */
|
|
4893
|
-
function setParticleEmitRateScale(scale) { particleEmitRateScale = scale; }
|
|
4894
|
-
|
|
4895
|
-
/** Set if gamepads are enabled
|
|
4896
|
-
* @param {Boolean} enable
|
|
4897
|
-
* @memberof Settings */
|
|
4898
|
-
function setGamepadsEnable(enable) { gamepadsEnable = enable; }
|
|
4899
|
-
|
|
4900
|
-
/** Set if the dpad input is also routed to the left analog stick
|
|
4901
|
-
* @param {Boolean} enable
|
|
4902
|
-
* @memberof Settings */
|
|
4903
|
-
function setGamepadDirectionEmulateStick(enable) { gamepadDirectionEmulateStick = enable; }
|
|
4904
|
-
|
|
4905
|
-
/** Set if true the WASD keys are also routed to the direction keys
|
|
4906
|
-
* @param {Boolean} enable
|
|
4907
|
-
* @memberof Settings */
|
|
4908
|
-
function setInputWASDEmulateDirection(enable) { inputWASDEmulateDirection = enable; }
|
|
4909
|
-
|
|
4910
|
-
/** Set if touch gamepad should appear on mobile devices
|
|
4911
|
-
* @param {Boolean} enable
|
|
4912
|
-
* @memberof Settings */
|
|
4913
|
-
function setTouchGamepadEnable(enable) { touchGamepadEnable = enable; }
|
|
4914
|
-
|
|
4915
|
-
/** Set if touch gamepad should be analog stick or 8 way dpad
|
|
4916
|
-
* @param {Boolean} analog
|
|
4917
|
-
* @memberof Settings */
|
|
4918
|
-
function setTouchGamepadAnalog(analog) { touchGamepadAnalog = analog; }
|
|
4919
|
-
|
|
4920
|
-
/** Set size of virutal gamepad for touch devices in pixels
|
|
4921
|
-
* @param {Number} size
|
|
4922
|
-
* @memberof Settings */
|
|
4923
|
-
function setTouchGamepadSize(size) { touchGamepadSize = size; }
|
|
4924
|
-
|
|
4925
|
-
/** Set transparency of touch gamepad overlay
|
|
4926
|
-
* @param {Number} alpha
|
|
4927
|
-
* @memberof Settings */
|
|
4928
|
-
function setTouchGamepadAlpha(alpha) { touchGamepadAlpha = alpha; }
|
|
4929
|
-
|
|
4930
|
-
/** Set to allow vibration hardware if it exists
|
|
4931
|
-
* @param {Boolean} enable
|
|
4932
|
-
* @memberof Settings */
|
|
4933
|
-
function setVibrateEnable(enable) { vibrateEnable = enable; }
|
|
4934
|
-
|
|
4935
|
-
/** Set to disable all audio code
|
|
4936
|
-
* @param {Boolean} enable
|
|
4937
|
-
* @memberof Settings */
|
|
4938
|
-
function setSoundEnable(enable) { soundEnable = enable; }
|
|
4939
|
-
|
|
4940
|
-
/** Set volume scale to apply to all sound, music and speech
|
|
4941
|
-
* @param {Number} volume
|
|
4942
|
-
* @memberof Settings */
|
|
4943
|
-
function setSoundVolume(volume) { soundVolume = volume; }
|
|
4944
|
-
|
|
4945
|
-
/** Set default range where sound no longer plays
|
|
4946
|
-
* @param {Number} range
|
|
4947
|
-
* @memberof Settings */
|
|
4948
|
-
function setSoundDefaultRange(range) { soundDefaultRange = range; }
|
|
4949
|
-
|
|
4950
|
-
/** Set default range percent to start tapering off sound
|
|
4951
|
-
* @param {Number} taper
|
|
4952
|
-
* @memberof Settings */
|
|
4953
|
-
function setSoundDefaultTaper(taper) { soundDefaultTaper = taper; }
|
|
4954
|
-
|
|
4955
|
-
/** Set how long to show medals for in seconds
|
|
4956
|
-
* @param {Number} time
|
|
4957
|
-
* @memberof Settings */
|
|
4958
|
-
function setMedalDisplayTime(time) { medalDisplayTime = time; }
|
|
4959
|
-
|
|
4960
|
-
/** Set how quickly to slide on/off medals in seconds
|
|
4961
|
-
* @param {Number} time
|
|
4962
|
-
* @memberof Settings */
|
|
4963
|
-
function setMedalDisplaySlideTime(time) { medalDisplaySlideTime = time; }
|
|
4964
|
-
|
|
4965
|
-
/** Set size of medal display
|
|
4966
|
-
* @param {Vector2} size
|
|
4967
|
-
* @memberof Settings */
|
|
4968
|
-
function setMedalDisplaySize(size) { medalDisplaySize = size; }
|
|
4969
|
-
|
|
4970
|
-
/** Set size of icon in medal display
|
|
4971
|
-
* @param {Number} size
|
|
4972
|
-
* @memberof Settings */
|
|
4973
|
-
function setMedalDisplayIconSize(size) { medalDisplayIconSize = size; }
|
|
4974
|
-
|
|
4975
|
-
/** Set to stop medals from being unlockable
|
|
4976
|
-
* @param {Boolean} preventUnlock
|
|
4977
|
-
* @memberof Settings */
|
|
4978
|
-
function setMedalsPreventUnlock(preventUnlock) { medalsPreventUnlock = preventUnlock; }
|
|
4979
|
-
|
|
4980
|
-
/** Set if watermark with FPS should be shown
|
|
4981
|
-
* @param {Boolean} show
|
|
4982
|
-
* @memberof Debug */
|
|
4983
|
-
function setShowWatermark(show) { showWatermark = show; }
|
|
4984
|
-
|
|
4985
|
-
/** Set key code used to toggle debug mode, Esc by default
|
|
4986
|
-
* @param {Number} key
|
|
4987
|
-
* @memberof Debug */
|
|
4988
|
-
function setDebugKey(key) { debugKey = key; }
|
|
4989
|
-
|
|
4990
5108
|
export {
|
|
4991
5109
|
// Setters for global variables
|
|
4992
5110
|
setCameraPos,
|
|
@@ -5121,7 +5239,10 @@ export {
|
|
|
5121
5239
|
EngineObject,
|
|
5122
5240
|
|
|
5123
5241
|
// Draw
|
|
5124
|
-
|
|
5242
|
+
textureInfos,
|
|
5243
|
+
tile,
|
|
5244
|
+
TileInfo,
|
|
5245
|
+
TextureInfo,
|
|
5125
5246
|
mainCanvas,
|
|
5126
5247
|
mainContext,
|
|
5127
5248
|
overlayCanvas,
|