littlejsengine 1.18.12 → 1.18.17
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/FAQ.md +197 -15
- package/README.md +31 -10
- package/dist/littlejs.d.ts +301 -92
- package/dist/littlejs.esm.js +1578 -518
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +1554 -517
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +1525 -494
- package/package.json +4 -1
- package/plugins/box2d.js +26 -19
- package/plugins/drawUtilities.js +63 -0
- package/plugins/lightSystem.js +330 -0
- package/plugins/medalSystem.js +36 -5
- package/plugins/newgrounds.js +15 -3
- package/plugins/pathFinder.js +5 -3
- package/plugins/pluginExport.js +12 -3
- package/plugins/postProcess.js +8 -1
- package/plugins/tweenSystem.js +25 -20
- package/plugins/uiSystem.js +21 -3
- package/src/engine.js +14 -3
- package/src/engineAudio.js +48 -16
- package/src/engineBuild.mjs +2 -1
- package/src/engineDebug.js +30 -23
- package/src/engineDraw.js +80 -46
- package/src/engineExport.js +16 -2
- package/src/engineInput.js +534 -190
- package/src/engineLogo.js +1 -1
- package/src/engineMath.js +21 -7
- package/src/engineObject.js +24 -13
- package/src/engineParticles.js +45 -42
- package/src/engineRelease.js +1 -0
- package/src/engineSettings.js +112 -10
- package/src/engineTileLayer.js +67 -43
- package/src/engineUtilities.js +24 -11
- package/src/engineWebGL.js +23 -55
package/src/engineLogo.js
CHANGED
|
@@ -65,7 +65,7 @@ function drawEngineLogo(t)
|
|
|
65
65
|
x.closePath();
|
|
66
66
|
gradient(0, Y, 0, Y+H,C);
|
|
67
67
|
}
|
|
68
|
-
const color = (c,l)=> l?`hsl(${[.95,.56,.13][c%3]*360} 99%${[0,50,75][l]}
|
|
68
|
+
const color = (c,l)=> l?`hsl(${[.95,.56,.13][c%3]*360} 99%${[0,50,75][l]}%)`:'#000';
|
|
69
69
|
|
|
70
70
|
// center and fit to screen
|
|
71
71
|
const alpha = oscillate(1,1,t);
|
package/src/engineMath.js
CHANGED
|
@@ -62,19 +62,19 @@ const max = Math.max;
|
|
|
62
62
|
* @param {number} x
|
|
63
63
|
* @return {number}
|
|
64
64
|
* @memberof Math */
|
|
65
|
-
const sign = Math.sign;
|
|
65
|
+
const sign = (x) => Math.sign(x);
|
|
66
66
|
|
|
67
67
|
/** Returns hypotenuse of values passed in
|
|
68
68
|
* @param {...number} values
|
|
69
69
|
* @return {number}
|
|
70
70
|
* @memberof Math */
|
|
71
|
-
const hypot = Math.hypot;
|
|
71
|
+
const hypot = (...values) => Math.hypot(...values);
|
|
72
72
|
|
|
73
73
|
/** Returns log2 of value passed in
|
|
74
74
|
* @param {number} x
|
|
75
75
|
* @return {number}
|
|
76
76
|
* @memberof Math */
|
|
77
|
-
const log2 = Math.log2;
|
|
77
|
+
const log2 = (x) => Math.log2(x);
|
|
78
78
|
|
|
79
79
|
/** Returns sin of value passed in
|
|
80
80
|
* @param {number} x
|
|
@@ -216,7 +216,8 @@ function isOverlapping(posA, sizeA, posB, sizeB=vec2())
|
|
|
216
216
|
const dy = (posA.y - posB.y)*2;
|
|
217
217
|
const sx = sizeA.x + sizeB.x;
|
|
218
218
|
const sy = sizeA.y + sizeB.y;
|
|
219
|
-
|
|
219
|
+
// symmetric so isOverlapping(A,B) === isOverlapping(B,A) at touching edges
|
|
220
|
+
return abs(dx) < sx && abs(dy) < sy;
|
|
220
221
|
}
|
|
221
222
|
|
|
222
223
|
/** Returns true if a line segment is intersecting an axis aligned box
|
|
@@ -305,7 +306,7 @@ function isStringLike(s) { return s != null && typeof s?.toString() === 'string'
|
|
|
305
306
|
/**
|
|
306
307
|
* Check if object is an array
|
|
307
308
|
* @param {any} a
|
|
308
|
-
* @return {
|
|
309
|
+
* @return {a is Array<any>}
|
|
309
310
|
* @memberof Math */
|
|
310
311
|
function isArray(a) { return Array.isArray(a); }
|
|
311
312
|
|
|
@@ -443,7 +444,13 @@ function randVec2(length=1) { return new Vector2().setAngle(rand(2*PI), length);
|
|
|
443
444
|
* @return {Vector2}
|
|
444
445
|
* @memberof Random */
|
|
445
446
|
function randInCircle(radius=1, minRadius=0)
|
|
446
|
-
{
|
|
447
|
+
{
|
|
448
|
+
// r is uniform in area ⇒ r² uniform in [minRadius², radius²]
|
|
449
|
+
// (the squared inner bound is what makes minRadius the actual exclusion edge)
|
|
450
|
+
if (radius <= 0) return new Vector2;
|
|
451
|
+
const ratio = clamp(minRadius / radius);
|
|
452
|
+
return randVec2(radius * rand(ratio*ratio, 1)**.5);
|
|
453
|
+
}
|
|
447
454
|
|
|
448
455
|
/** Returns a random color between the two passed in colors, combine components if linear
|
|
449
456
|
* @param {Color} [colorA=WHITE]
|
|
@@ -513,7 +520,14 @@ class RandomGenerator
|
|
|
513
520
|
* @param {number} [valueA]
|
|
514
521
|
* @param {number} [valueB]
|
|
515
522
|
* @return {number} */
|
|
516
|
-
floatSign(valueA=1, valueB=0)
|
|
523
|
+
floatSign(valueA=1, valueB=0)
|
|
524
|
+
{
|
|
525
|
+
const lo = min(valueA, valueB);
|
|
526
|
+
const hi = max(valueA, valueB);
|
|
527
|
+
const d = hi - lo;
|
|
528
|
+
const e = this.float(d*2);
|
|
529
|
+
return e < d ? lo + e : d - lo - e;
|
|
530
|
+
}
|
|
517
531
|
|
|
518
532
|
/** Returns a random angle between -PI and PI
|
|
519
533
|
* @return {number} */
|
package/src/engineObject.js
CHANGED
|
@@ -71,7 +71,7 @@ class EngineObject
|
|
|
71
71
|
this.color = color.copy();
|
|
72
72
|
/** @property {Color} - Additive color to apply when rendered */
|
|
73
73
|
this.additiveColor = undefined;
|
|
74
|
-
/** @property {boolean} - Should
|
|
74
|
+
/** @property {boolean} - Should the rendered tile flip along the y axis. Affects rendering and the local→world transform of attached children (a mirrored parent flips its children's localPos.x and localAngle). Does not affect this object's own physics, collision, or localToWorld/worldToLocal. */
|
|
75
75
|
this.mirror = false;
|
|
76
76
|
/** @property {boolean} - Has object been destroyed? */
|
|
77
77
|
this.destroyed = false;
|
|
@@ -139,10 +139,10 @@ class EngineObject
|
|
|
139
139
|
if (pa)
|
|
140
140
|
{
|
|
141
141
|
const c = cos(-pa), s = sin(-pa);
|
|
142
|
-
this.pos
|
|
142
|
+
this.pos.set(lx*c - ly*s + pp.x, lx*s + ly*c + pp.y);
|
|
143
143
|
}
|
|
144
144
|
else
|
|
145
|
-
this.pos
|
|
145
|
+
this.pos.set(lx + pp.x, ly + pp.y);
|
|
146
146
|
this.angle = mirror*this.localAngle + pa;
|
|
147
147
|
}
|
|
148
148
|
|
|
@@ -157,6 +157,9 @@ class EngineObject
|
|
|
157
157
|
// child objects do not have physics
|
|
158
158
|
ASSERT(!this.parent);
|
|
159
159
|
|
|
160
|
+
// bail if a collision callback destroyed us mid-frame
|
|
161
|
+
if (this.destroyed) return;
|
|
162
|
+
|
|
160
163
|
if (this.clampSpeed)
|
|
161
164
|
{
|
|
162
165
|
// limit max speed to prevent missing collisions
|
|
@@ -212,6 +215,8 @@ class EngineObject
|
|
|
212
215
|
|
|
213
216
|
// notify objects of collision and check if should be resolved
|
|
214
217
|
const collide1 = this.collideWithObject(o);
|
|
218
|
+
// callback may have destroyed us; stop resolving against more objects
|
|
219
|
+
if (this.destroyed) return;
|
|
215
220
|
const collide2 = o.collideWithObject(this);
|
|
216
221
|
if (!collide1 || !collide2) continue;
|
|
217
222
|
|
|
@@ -307,13 +312,17 @@ class EngineObject
|
|
|
307
312
|
const restitution = max(this.restitution, hitLayer.restitution);
|
|
308
313
|
if (isBlockedX)
|
|
309
314
|
{
|
|
310
|
-
// try to
|
|
315
|
+
// try to step over a 1-tile bump (direction follows gravity sign
|
|
316
|
+
// so inverted gravity steps down off a ceiling bump instead of up;
|
|
317
|
+
// zero gravity defaults to the normal-gravity step-up direction)
|
|
311
318
|
const epsilon = 1e-3;
|
|
312
|
-
const
|
|
313
|
-
const
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
319
|
+
const maxMove = .1;
|
|
320
|
+
const gravitySign = gravity.y > 0 ? -1 : 1;
|
|
321
|
+
const y = gravitySign > 0 ?
|
|
322
|
+
floor(oldPos.y-this.size.y/2+1) + this.size.y/2 + epsilon :
|
|
323
|
+
ceil( oldPos.y+this.size.y/2-1) - this.size.y/2 - epsilon;
|
|
324
|
+
const delta = abs(y - this.pos.y);
|
|
325
|
+
if (delta < maxMove)
|
|
317
326
|
if (!tileCollisionTest(vec2(this.pos.x, y), this.size, this))
|
|
318
327
|
{
|
|
319
328
|
this.pos.y = y;
|
|
@@ -365,6 +374,9 @@ class EngineObject
|
|
|
365
374
|
drawTile(this.pos, this.drawSize || this.size, this.tileInfo, this.color, this.angle, this.mirror, this.additiveColor);
|
|
366
375
|
}
|
|
367
376
|
|
|
377
|
+
/** Optional hook called during the light system plugin's lightmap pass to draw this object's lightmap contribution. Does nothing by default. */
|
|
378
|
+
renderLight() {}
|
|
379
|
+
|
|
368
380
|
/** Destroy this object, destroy its children, detach its parent, and mark it for removal
|
|
369
381
|
* @param {boolean} [immediate] - should attached effects be allowed to die off? */
|
|
370
382
|
destroy(immediate=false)
|
|
@@ -453,6 +465,8 @@ class EngineObject
|
|
|
453
465
|
* @return {EngineObject} The child object added */
|
|
454
466
|
addChild(child, localPos=vec2(), localAngle=0)
|
|
455
467
|
{
|
|
468
|
+
ASSERT(!this.destroyed, 'cannot add child to destroyed object');
|
|
469
|
+
if (this.destroyed) return child;
|
|
456
470
|
ASSERT(!child.parent && !this.children.includes(child));
|
|
457
471
|
ASSERT(child instanceof EngineObject, 'child must be an EngineObject');
|
|
458
472
|
ASSERT(child !== this, 'cannot add self as child');
|
|
@@ -469,10 +483,7 @@ class EngineObject
|
|
|
469
483
|
removeChild(child)
|
|
470
484
|
{
|
|
471
485
|
ASSERT(child.parent === this && this.children.includes(child));
|
|
472
|
-
|
|
473
|
-
const index = this.children.indexOf(child);
|
|
474
|
-
ASSERT(index >= 0, 'child not found in children array');
|
|
475
|
-
index >= 0 && this.children.splice(index, 1);
|
|
486
|
+
this.children.splice(this.children.indexOf(child), 1);
|
|
476
487
|
child.parent = undefined;
|
|
477
488
|
}
|
|
478
489
|
|
package/src/engineParticles.js
CHANGED
|
@@ -62,13 +62,13 @@ class ParticleEmitter extends EngineObject
|
|
|
62
62
|
* @param {number} [particleTime] - How long particles live
|
|
63
63
|
* @param {number} [sizeStart] - How big are particles at start
|
|
64
64
|
* @param {number} [sizeEnd] - How big are particles at end
|
|
65
|
-
* @param {number} [speed] - How fast are particles when spawned
|
|
66
|
-
* @param {number} [angleSpeed] - How fast are particles rotating
|
|
67
|
-
* @param {number} [damping] - How much to dampen particle speed
|
|
68
|
-
* @param {number} [angleDamping] - How much to dampen particle angular speed
|
|
65
|
+
* @param {number} [speed] - How fast are particles when spawned, in world units per frame (at 60fps, so multiply units/sec by 1/60)
|
|
66
|
+
* @param {number} [angleSpeed] - How fast are particles rotating, in radians per frame (at 60fps)
|
|
67
|
+
* @param {number} [damping] - How much to dampen particle speed, per-frame velocity multiplier (1 = no damping, .9 = lose 10% speed each frame)
|
|
68
|
+
* @param {number} [angleDamping] - How much to dampen particle angular speed, per-frame multiplier (1 = no damping)
|
|
69
69
|
* @param {number} [gravityScale] - How much gravity effect particles
|
|
70
70
|
* @param {number} [particleConeAngle] - Cone for start particle angle
|
|
71
|
-
* @param {number} [fadeRate] -
|
|
71
|
+
* @param {number} [fadeRate] - Fraction of life spent fading: half at fade-in (start), half at fade-out (end). e.g. .2 = 10% fade-in, 80% full opacity, 10% fade-out
|
|
72
72
|
* @param {number} [randomness] - Apply extra randomness percent
|
|
73
73
|
* @param {boolean} [collideTiles] - Do particles collide against tiles
|
|
74
74
|
* @param {boolean} [additive] - Should particles use additive blend
|
|
@@ -140,19 +140,19 @@ class ParticleEmitter extends EngineObject
|
|
|
140
140
|
this.sizeStart = sizeStart;
|
|
141
141
|
/** @property {number} - How big are particles at end */
|
|
142
142
|
this.sizeEnd = sizeEnd;
|
|
143
|
-
/** @property {number} -
|
|
143
|
+
/** @property {number} - Particle speed when spawned, in world units per frame (at 60fps) */
|
|
144
144
|
this.speed = speed;
|
|
145
|
-
/** @property {number} -
|
|
145
|
+
/** @property {number} - Particle angular speed when spawned, in radians per frame (at 60fps) */
|
|
146
146
|
this.angleSpeed = angleSpeed;
|
|
147
|
-
/** @property {number} -
|
|
147
|
+
/** @property {number} - Per-frame velocity multiplier (1 = no damping, .9 = lose 10% speed each frame) */
|
|
148
148
|
this.damping = damping;
|
|
149
|
-
/** @property {number} -
|
|
149
|
+
/** @property {number} - Per-frame angular velocity multiplier (1 = no damping) */
|
|
150
150
|
this.angleDamping = angleDamping;
|
|
151
151
|
/** @property {number} - How much gravity affects particles */
|
|
152
152
|
this.gravityScale = gravityScale;
|
|
153
153
|
/** @property {number} - Cone for start particle angle */
|
|
154
154
|
this.particleConeAngle = particleConeAngle;
|
|
155
|
-
/** @property {number} -
|
|
155
|
+
/** @property {number} - Fraction of life spent fading, split half at start and half at end (e.g. .2 = 10% fade-in + 10% fade-out) */
|
|
156
156
|
this.fadeRate = fadeRate;
|
|
157
157
|
/** @property {number} - Apply extra randomness percent */
|
|
158
158
|
this.randomness = randomness;
|
|
@@ -215,12 +215,16 @@ class ParticleEmitter extends EngineObject
|
|
|
215
215
|
else if (this.particles.length === 0)
|
|
216
216
|
this.destroy(true);
|
|
217
217
|
|
|
218
|
-
// update and remove destroyed particles
|
|
219
|
-
|
|
218
|
+
// update and remove destroyed particles in place to avoid per-frame array allocation
|
|
219
|
+
const particles = this.particles;
|
|
220
|
+
let alive = 0;
|
|
221
|
+
for (let i = 0; i < particles.length; ++i)
|
|
220
222
|
{
|
|
223
|
+
const p = particles[i];
|
|
221
224
|
p.update();
|
|
222
|
-
|
|
223
|
-
}
|
|
225
|
+
if (!p.destroyed) particles[alive++] = p;
|
|
226
|
+
}
|
|
227
|
+
particles.length = alive;
|
|
224
228
|
|
|
225
229
|
if (debugParticles)
|
|
226
230
|
{
|
|
@@ -430,33 +434,32 @@ class Particle
|
|
|
430
434
|
const hitLayer = tileCollisionTest(this.pos);
|
|
431
435
|
if (!testCollision(oldPos))
|
|
432
436
|
{
|
|
433
|
-
|
|
437
|
+
// testCollision already invoked collideCallback with the
|
|
438
|
+
// correct (this, data, pos) args; no need to re-check here.
|
|
439
|
+
// test which side we bounced off (or both if a corner)
|
|
440
|
+
const isBlockedX = testCollision(vec2(this.pos.x, oldPos.y));
|
|
441
|
+
const isBlockedY = testCollision(vec2(oldPos.x, this.pos.y));
|
|
442
|
+
const hitRestitution = max(restitution, hitLayer.restitution);
|
|
443
|
+
const hitFriction = max(friction, hitLayer.friction);
|
|
444
|
+
if (isBlockedX)
|
|
445
|
+
{
|
|
446
|
+
// move to previous X position and bounce
|
|
447
|
+
this.pos.x = oldPos.x;
|
|
448
|
+
this.velocity.x *= -hitRestitution;
|
|
449
|
+
this.velocity.y *= hitFriction;
|
|
450
|
+
}
|
|
451
|
+
if (isBlockedY || !isBlockedX)
|
|
434
452
|
{
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
this.pos.x = oldPos.x;
|
|
444
|
-
this.velocity.x *= -hitRestitution;
|
|
445
|
-
this.velocity.y *= hitFriction;
|
|
446
|
-
}
|
|
447
|
-
if (isBlockedY || !isBlockedX)
|
|
448
|
-
{
|
|
449
|
-
const wasFalling = this.velocity.y < 0 && gravity.y < 0 || this.velocity.y > 0 && gravity.y > 0;
|
|
450
|
-
if (wasFalling)
|
|
451
|
-
this.groundObject = hitLayer;
|
|
452
|
-
|
|
453
|
-
// move to previous Y position and bounce
|
|
454
|
-
this.pos.y = oldPos.y;
|
|
455
|
-
this.velocity.y *= -hitRestitution;
|
|
456
|
-
this.velocity.x *= hitFriction;
|
|
457
|
-
}
|
|
458
|
-
debugPhysics && debugRect(this.pos, this.size, '#f00');
|
|
453
|
+
const wasFalling = this.velocity.y < 0 && gravity.y < 0 || this.velocity.y > 0 && gravity.y > 0;
|
|
454
|
+
if (wasFalling)
|
|
455
|
+
this.groundObject = hitLayer;
|
|
456
|
+
|
|
457
|
+
// move to previous Y position and bounce
|
|
458
|
+
this.pos.y = oldPos.y;
|
|
459
|
+
this.velocity.y *= -hitRestitution;
|
|
460
|
+
this.velocity.x *= hitFriction;
|
|
459
461
|
}
|
|
462
|
+
debugPhysics && debugRect(this.pos, this.size, '#f00');
|
|
460
463
|
}
|
|
461
464
|
}
|
|
462
465
|
}
|
|
@@ -503,7 +506,7 @@ class Particle
|
|
|
503
506
|
{
|
|
504
507
|
// in local space of emitter
|
|
505
508
|
const a = emitter.angle;
|
|
506
|
-
const c = cos(a), s = sin(a);
|
|
509
|
+
const c = cos(-a), s = sin(-a);
|
|
507
510
|
pos.set(emitter.pos.x + pos.x*c - pos.y*s,
|
|
508
511
|
emitter.pos.y + pos.x*s + pos.y*c);
|
|
509
512
|
angle += a;
|
|
@@ -511,8 +514,8 @@ class Particle
|
|
|
511
514
|
if (trailScale)
|
|
512
515
|
{
|
|
513
516
|
// trail style particles
|
|
514
|
-
const velocity = localSpace ?
|
|
515
|
-
this.velocity.rotate(
|
|
517
|
+
const velocity = localSpace ?
|
|
518
|
+
this.velocity.rotate(emitter.angle) : this.velocity;
|
|
516
519
|
const speed = velocity.length();
|
|
517
520
|
if (speed)
|
|
518
521
|
{
|
package/src/engineRelease.js
CHANGED
package/src/engineSettings.js
CHANGED
|
@@ -51,7 +51,7 @@ let canvasColorTiles = true;
|
|
|
51
51
|
|
|
52
52
|
/** Color to clear the canvas to before render, does not clear if alpha is 0
|
|
53
53
|
* @type {Color}
|
|
54
|
-
* @memberof
|
|
54
|
+
* @memberof Settings */
|
|
55
55
|
let canvasClearColor = CLEAR_BLACK;
|
|
56
56
|
|
|
57
57
|
/** The max size of the canvas, centered if window is larger
|
|
@@ -244,34 +244,78 @@ let touchInputEnable = true;
|
|
|
244
244
|
* - Supports left analog stick, 4 face buttons and start button (button 9)
|
|
245
245
|
* - setTouchGamepadButtonCount(1) to use face buttons as right analog stick
|
|
246
246
|
* - Analog stick buttons 10 and 11 are also activated when virtual sticks are touched
|
|
247
|
-
|
|
247
|
+
* - Rendered as a full-viewport HTML/SVG overlay, so controls may sit outside the game canvas
|
|
248
248
|
* @type {boolean}
|
|
249
249
|
* @default
|
|
250
250
|
* @memberof Settings */
|
|
251
251
|
let touchGamepadEnable = false;
|
|
252
252
|
|
|
253
|
-
/** True if
|
|
254
|
-
* -
|
|
253
|
+
/** True if touches outside the gamepad controls should still drive mouse/touch input
|
|
254
|
+
* - When false (the default), enabling the touch gamepad suppresses touch-to-mouse input entirely
|
|
255
|
+
* - Set true to also pass touches outside the controls through to the game as mouse/touch input
|
|
256
|
+
* - Touches on the gamepad controls never drive the mouse regardless of this setting
|
|
257
|
+
* @type {boolean}
|
|
258
|
+
* @default
|
|
259
|
+
* @memberof Settings */
|
|
260
|
+
let touchGamepadPassthrough = false;
|
|
261
|
+
|
|
262
|
+
/** Size of center button if touch gamepad should have start button in the center
|
|
263
|
+
* - Prevents activating when pressed near virtual stick or face buttons
|
|
255
264
|
* - When the game is paused, any touch will press the button
|
|
256
|
-
* -
|
|
265
|
+
* - Measured in viewport CSS pixels
|
|
257
266
|
* @type {number}
|
|
258
267
|
* @default
|
|
259
268
|
* @memberof Settings */
|
|
260
|
-
let touchGamepadCenterButtonSize =
|
|
269
|
+
let touchGamepadCenterButtonSize = 0;
|
|
261
270
|
|
|
262
|
-
/** Number of buttons on touch gamepad (0-4),
|
|
271
|
+
/** Number of buttons on the right side of the touch gamepad (0-4), using gamepad buttons 0-3
|
|
272
|
+
* - A count of 1 is a single large button (the size of a stick)
|
|
273
|
+
* - Ignored when touchGamepadRightStick is set (the right side is a stick instead)
|
|
263
274
|
* @type {number}
|
|
264
275
|
* @default
|
|
265
276
|
* @memberof Settings */
|
|
266
277
|
let touchGamepadButtonCount = 4;
|
|
267
278
|
|
|
279
|
+
/** True if the touch gamepad should have a left analog stick (or dpad)
|
|
280
|
+
* - When false, the left side is face buttons (touchGamepadLeftButtonCount) or nothing
|
|
281
|
+
* @type {boolean}
|
|
282
|
+
* @default
|
|
283
|
+
* @memberof Settings */
|
|
284
|
+
let touchGamepadLeftStick = true;
|
|
285
|
+
|
|
286
|
+
/** Number of buttons on the left side of the touch gamepad (0-4), using gamepad buttons 4-7
|
|
287
|
+
* - Only used when touchGamepadLeftStick is false (otherwise the left side is a stick)
|
|
288
|
+
* - A count of 1 is a single large button (the size of a stick)
|
|
289
|
+
* @type {number}
|
|
290
|
+
* @default
|
|
291
|
+
* @memberof Settings */
|
|
292
|
+
let touchGamepadLeftButtonCount = 0;
|
|
293
|
+
|
|
294
|
+
/** True if the touch gamepad right side should be an analog stick (or dpad) instead of face buttons
|
|
295
|
+
* - When set, touchGamepadButtonCount is ignored and the right side is a stick
|
|
296
|
+
* - Uses an analog stick when touchGamepadAnalog is true, otherwise an 8 way dpad
|
|
297
|
+
* @type {boolean}
|
|
298
|
+
* @default
|
|
299
|
+
* @memberof Settings */
|
|
300
|
+
let touchGamepadRightStick = false;
|
|
301
|
+
|
|
268
302
|
/** True if touch gamepad should be analog stick or false to use if 8 way dpad
|
|
269
303
|
* @type {boolean}
|
|
270
304
|
* @default
|
|
271
305
|
* @memberof Settings */
|
|
272
306
|
let touchGamepadAnalog = true;
|
|
273
307
|
|
|
274
|
-
/**
|
|
308
|
+
/** True if touch gamepad directional controls should float to where you press
|
|
309
|
+
* - Only affects analog sticks and dpads, not face buttons
|
|
310
|
+
* - Directional controls re-anchor to where you press within the bottom ~60% of their screen half; the top ~40% passes through to the game
|
|
311
|
+
* - The right side floats only when it acts as the right analog stick (touchGamepadRightStick is set)
|
|
312
|
+
* - A center button (touchGamepadCenterButtonSize) still works since it ignores touches near the sticks
|
|
313
|
+
* @type {boolean}
|
|
314
|
+
* @default
|
|
315
|
+
* @memberof Settings */
|
|
316
|
+
let touchGamepadFloating = false;
|
|
317
|
+
|
|
318
|
+
/** Size of virtual gamepad for touch devices in viewport CSS pixels
|
|
275
319
|
* @type {number}
|
|
276
320
|
* @default
|
|
277
321
|
* @memberof Settings */
|
|
@@ -289,6 +333,13 @@ let touchGamepadAlpha = .3;
|
|
|
289
333
|
* @memberof Settings */
|
|
290
334
|
let touchGamepadDisplayTime = 3;
|
|
291
335
|
|
|
336
|
+
/** Duration in ms to vibrate when a touch gamepad face button or start button is pressed
|
|
337
|
+
* - Set to 0 to disable, also requires vibrateEnable and hardware support (ignored on iOS)
|
|
338
|
+
* @type {number}
|
|
339
|
+
* @default
|
|
340
|
+
* @memberof Settings */
|
|
341
|
+
let touchGamepadVibration = 0;
|
|
342
|
+
|
|
292
343
|
/** Allow vibration hardware if it exists
|
|
293
344
|
* @type {boolean}
|
|
294
345
|
* @default
|
|
@@ -521,6 +572,11 @@ function setTouchInputEnable(enable) { touchInputEnable = enable; }
|
|
|
521
572
|
* @memberof Settings */
|
|
522
573
|
function setTouchGamepadEnable(enable) { touchGamepadEnable = enable; }
|
|
523
574
|
|
|
575
|
+
/** Set if touches outside the gamepad controls should still drive mouse/touch input
|
|
576
|
+
* @param {boolean} passthrough
|
|
577
|
+
* @memberof Settings */
|
|
578
|
+
function setTouchGamepadPassthrough(passthrough) { touchGamepadPassthrough = passthrough; }
|
|
579
|
+
|
|
524
580
|
/** Set if touch gamepad should have start button in the center
|
|
525
581
|
* - Set size to enable the center button
|
|
526
582
|
* - When the game is paused, any touch will press the button
|
|
@@ -528,16 +584,57 @@ function setTouchGamepadEnable(enable) { touchGamepadEnable = enable; }
|
|
|
528
584
|
* @memberof Settings */
|
|
529
585
|
function setTouchGamepadCenterButtonSize(size) { touchGamepadCenterButtonSize = size; }
|
|
530
586
|
|
|
531
|
-
/** Set number of buttons on touch gamepad (0-4
|
|
587
|
+
/** Set number of buttons on the right side of the touch gamepad (0-4, gamepad buttons 0-3)
|
|
588
|
+
* @param {number} count
|
|
589
|
+
* @memberof Settings */
|
|
590
|
+
function setTouchGamepadButtonCount(count)
|
|
591
|
+
{
|
|
592
|
+
touchGamepadButtonCount = count;
|
|
593
|
+
if (count > 0)
|
|
594
|
+
touchGamepadRightStick = false;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/** Set if the touch gamepad should have a left analog stick (or dpad)
|
|
598
|
+
* @param {boolean} enable
|
|
599
|
+
* @memberof Settings */
|
|
600
|
+
function setTouchGamepadLeftStick(enable)
|
|
601
|
+
{
|
|
602
|
+
touchGamepadLeftStick = enable;
|
|
603
|
+
if (enable)
|
|
604
|
+
touchGamepadLeftButtonCount = 0;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/** Set number of buttons on the left side of the touch gamepad (0-4, gamepad buttons 4-7)
|
|
608
|
+
* - Only used when touchGamepadLeftStick is false
|
|
532
609
|
* @param {number} count
|
|
533
610
|
* @memberof Settings */
|
|
534
|
-
function
|
|
611
|
+
function setTouchGamepadLeftButtonCount(count)
|
|
612
|
+
{
|
|
613
|
+
touchGamepadLeftButtonCount = count;
|
|
614
|
+
if (count > 0)
|
|
615
|
+
touchGamepadLeftStick = false;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/** Set if the touch gamepad right side is an analog stick (or dpad) instead of face buttons
|
|
619
|
+
* @param {boolean} rightStick
|
|
620
|
+
* @memberof Settings */
|
|
621
|
+
function setTouchGamepadRightStick(rightStick)
|
|
622
|
+
{
|
|
623
|
+
touchGamepadRightStick = rightStick;
|
|
624
|
+
if (rightStick)
|
|
625
|
+
touchGamepadButtonCount = 0;
|
|
626
|
+
}
|
|
535
627
|
|
|
536
628
|
/** Set if touch gamepad should be analog stick or 8 way dpad
|
|
537
629
|
* @param {boolean} analog
|
|
538
630
|
* @memberof Settings */
|
|
539
631
|
function setTouchGamepadAnalog(analog) { touchGamepadAnalog = analog; }
|
|
540
632
|
|
|
633
|
+
/** Set if touch gamepad directional controls should float to where you press
|
|
634
|
+
* @param {boolean} floating
|
|
635
|
+
* @memberof Settings */
|
|
636
|
+
function setTouchGamepadFloating(floating) { touchGamepadFloating = floating; }
|
|
637
|
+
|
|
541
638
|
/** Set size of virtual gamepad for touch devices in pixels
|
|
542
639
|
* @param {number} size
|
|
543
640
|
* @memberof Settings */
|
|
@@ -553,6 +650,11 @@ function setTouchGamepadAlpha(alpha) { touchGamepadAlpha = alpha; }
|
|
|
553
650
|
* @memberof Settings */
|
|
554
651
|
function setTouchGamepadDisplayTime(time) { touchGamepadDisplayTime = time; }
|
|
555
652
|
|
|
653
|
+
/** Set duration in ms to vibrate when a touch gamepad face or start button is pressed (0 disables)
|
|
654
|
+
* @param {number} ms
|
|
655
|
+
* @memberof Settings */
|
|
656
|
+
function setTouchGamepadVibration(ms) { touchGamepadVibration = ms; }
|
|
657
|
+
|
|
556
658
|
/** Set to allow vibration hardware if it exists
|
|
557
659
|
* @param {boolean} enable
|
|
558
660
|
* @memberof Settings */
|