littlejsengine 1.14.9 → 1.14.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/littlejs.d.ts +12 -11
- package/dist/littlejs.esm.js +121 -73
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +120 -73
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +102 -56
- package/examples/index.html +52 -47
- package/examples/platformer/gameCharacter.js +6 -2
- package/examples/platformer/gameLevel.js +1 -1
- package/examples/platformer/gameObjects.js +7 -5
- package/examples/shorts/blending.js +1 -1
- package/examples/shorts/landerGame.js +26 -2
- package/examples/shorts/music.js +3 -2
- package/examples/shorts/particles.js +11 -11
- package/examples/shorts/pongGame.js +0 -1
- package/examples/shorts/raycasting.js +4 -1
- package/examples/shorts/slidingPuzzle.js +13 -5
- package/examples/shorts/starfield.js +1 -1
- package/examples/shorts/uiSystem.js +0 -4
- package/examples/uiSystem/game.js +4 -4
- package/package.json +1 -1
- package/plugins/box2d.js +1 -1
- package/plugins/newgrounds.js +4 -4
- package/plugins/uiSystem.js +1 -1
- package/reference.md +0 -2
- package/src/engine.js +20 -12
- package/src/engineDebug.js +19 -17
- package/src/engineExport.js +1 -0
- package/src/engineInput.js +49 -22
- package/src/engineRelease.js +1 -0
- package/src/engineSettings.js +6 -0
- package/src/engineTileLayer.js +7 -1
- package/src/engineUtilities.js +12 -14
package/dist/littlejs.d.ts
CHANGED
|
@@ -78,12 +78,12 @@ declare module "littlejsengine" {
|
|
|
78
78
|
* @example
|
|
79
79
|
* // Basic engine startup
|
|
80
80
|
* engineInit(
|
|
81
|
-
* () => {
|
|
82
|
-
* () => { updateGameLogic(); },
|
|
83
|
-
* () => { updateUI(); },
|
|
84
|
-
* () => { drawBackground(); },
|
|
85
|
-
* () => { drawHUD(); },
|
|
86
|
-
* ['tiles.png', 'tilesLevel.png']
|
|
81
|
+
* () => { LOG('Game initialized!'); }, // gameInit
|
|
82
|
+
* () => { updateGameLogic(); }, // gameUpdate
|
|
83
|
+
* () => { updateUI(); }, // gameUpdatePost
|
|
84
|
+
* () => { drawBackground(); }, // gameRender
|
|
85
|
+
* () => { drawHUD(); }, // gameRenderPost
|
|
86
|
+
* ['tiles.png', 'tilesLevel.png'] // images to load
|
|
87
87
|
* );
|
|
88
88
|
* @memberof Engine */
|
|
89
89
|
export function engineInit(gameInit: Function | (() => Promise<any>), gameUpdate: Function, gameUpdatePost: Function, gameRender: Function, gameRenderPost: Function, imageSources?: Array<string>, rootElement?: HTMLElement): Promise<void>;
|
|
@@ -143,11 +143,15 @@ declare module "littlejsengine" {
|
|
|
143
143
|
* @default
|
|
144
144
|
* @memberof Debug */
|
|
145
145
|
export let showWatermark: boolean;
|
|
146
|
-
/** Asserts if the expression is false, does
|
|
146
|
+
/** Asserts if the expression is false, does nothing in release builds
|
|
147
147
|
* @param {boolean} assert
|
|
148
148
|
* @param {...Object} [output] - error message output
|
|
149
149
|
* @memberof Debug */
|
|
150
150
|
export function ASSERT(assert: boolean, ...output?: any[]): void;
|
|
151
|
+
/** Log to console if debug is enabled, does nothing in release builds
|
|
152
|
+
* @param {...Object} [output] - message output
|
|
153
|
+
* @memberof Debug */
|
|
154
|
+
export function LOG(...output?: any[]): void;
|
|
151
155
|
/** Draw a debug rectangle in world space
|
|
152
156
|
* @param {Vector2} pos
|
|
153
157
|
* @param {Vector2} [size=Vector2()]
|
|
@@ -952,10 +956,7 @@ declare module "littlejsengine" {
|
|
|
952
956
|
/** Returns the integer direction of this vector, corresponding to multiples of 90 degree rotation (0-3)
|
|
953
957
|
* @return {number} */
|
|
954
958
|
direction(): number;
|
|
955
|
-
/** Returns a copy of this vector
|
|
956
|
-
* @return {Vector2} */
|
|
957
|
-
invert(): Vector2;
|
|
958
|
-
/** Returns a copy of this vector absolute values
|
|
959
|
+
/** Returns a copy of this vector with absolute values
|
|
959
960
|
* @return {Vector2} */
|
|
960
961
|
abs(): Vector2;
|
|
961
962
|
/** Returns a copy of this vector with each axis floored
|
package/dist/littlejs.esm.js
CHANGED
|
@@ -33,7 +33,7 @@ const engineName = 'LittleJS';
|
|
|
33
33
|
* @type {string}
|
|
34
34
|
* @default
|
|
35
35
|
* @memberof Engine */
|
|
36
|
-
const engineVersion = '1.14.
|
|
36
|
+
const engineVersion = '1.14.11';
|
|
37
37
|
|
|
38
38
|
/** Frames per second to update
|
|
39
39
|
* @type {number}
|
|
@@ -122,12 +122,12 @@ function engineAddPlugin(updateFunction, renderFunction)
|
|
|
122
122
|
* @example
|
|
123
123
|
* // Basic engine startup
|
|
124
124
|
* engineInit(
|
|
125
|
-
* () => {
|
|
126
|
-
* () => { updateGameLogic(); },
|
|
127
|
-
* () => { updateUI(); },
|
|
128
|
-
* () => { drawBackground(); },
|
|
129
|
-
* () => { drawHUD(); },
|
|
130
|
-
* ['tiles.png', 'tilesLevel.png']
|
|
125
|
+
* () => { LOG('Game initialized!'); }, // gameInit
|
|
126
|
+
* () => { updateGameLogic(); }, // gameUpdate
|
|
127
|
+
* () => { updateUI(); }, // gameUpdatePost
|
|
128
|
+
* () => { drawBackground(); }, // gameRender
|
|
129
|
+
* () => { drawHUD(); }, // gameRenderPost
|
|
130
|
+
* ['tiles.png', 'tilesLevel.png'] // images to load
|
|
131
131
|
* );
|
|
132
132
|
* @memberof Engine */
|
|
133
133
|
async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
|
|
@@ -173,16 +173,20 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
173
173
|
if (!debugSpeedUp)
|
|
174
174
|
frameTimeBufferMS = min(frameTimeBufferMS, 50); // clamp min framerate
|
|
175
175
|
|
|
176
|
+
let wasUpdated = false;
|
|
176
177
|
if (paused)
|
|
177
178
|
{
|
|
179
|
+
// update everything except the game and objects
|
|
180
|
+
wasUpdated = true;
|
|
178
181
|
updateCanvas();
|
|
182
|
+
inputUpdate();
|
|
183
|
+
pluginUpdateList.forEach(f=>f());
|
|
179
184
|
|
|
180
185
|
// update object transforms even when paused
|
|
181
186
|
for (const o of engineObjects)
|
|
182
187
|
o.parent || o.updateTransforms();
|
|
183
188
|
|
|
184
|
-
|
|
185
|
-
pluginUpdateList.forEach(f=>f());
|
|
189
|
+
// do post update
|
|
186
190
|
debugUpdate();
|
|
187
191
|
gameUpdatePost();
|
|
188
192
|
inputUpdatePost();
|
|
@@ -199,12 +203,13 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
199
203
|
}
|
|
200
204
|
|
|
201
205
|
// update multiple frames if necessary in case of slow framerate
|
|
202
|
-
for (;frameTimeBufferMS >= 0; frameTimeBufferMS -= 1e3 / frameRate)
|
|
206
|
+
for (; frameTimeBufferMS >= 0; frameTimeBufferMS -= 1e3 / frameRate)
|
|
203
207
|
{
|
|
204
208
|
// increment frame and update time
|
|
205
209
|
time = frame++ / frameRate;
|
|
206
210
|
|
|
207
211
|
// update game and objects
|
|
212
|
+
wasUpdated = true;
|
|
208
213
|
updateCanvas();
|
|
209
214
|
inputUpdate();
|
|
210
215
|
gameUpdate();
|
|
@@ -215,7 +220,6 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
215
220
|
debugUpdate();
|
|
216
221
|
gameUpdatePost();
|
|
217
222
|
inputUpdatePost();
|
|
218
|
-
|
|
219
223
|
if (debugVideoCaptureIsActive())
|
|
220
224
|
renderFrame();
|
|
221
225
|
}
|
|
@@ -232,6 +236,10 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
232
236
|
{
|
|
233
237
|
if (headlessMode) return;
|
|
234
238
|
|
|
239
|
+
// canvas must be updated before rendering
|
|
240
|
+
if (!wasUpdated)
|
|
241
|
+
updateCanvas();
|
|
242
|
+
|
|
235
243
|
// render sort then render while removing destroyed objects
|
|
236
244
|
enginePreRender();
|
|
237
245
|
gameRender();
|
|
@@ -391,7 +399,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
391
399
|
promises.push(new Promise(resolve =>
|
|
392
400
|
{
|
|
393
401
|
let t = 0;
|
|
394
|
-
|
|
402
|
+
LOG(`${engineName} Engine v${engineVersion}`);
|
|
395
403
|
updateSplash();
|
|
396
404
|
function updateSplash()
|
|
397
405
|
{
|
|
@@ -688,12 +696,6 @@ function drawEngineSplashScreen(t)
|
|
|
688
696
|
* @memberof Debug */
|
|
689
697
|
const debug = true;
|
|
690
698
|
|
|
691
|
-
/** True if asserts are enabled
|
|
692
|
-
* @type {boolean}
|
|
693
|
-
* @default
|
|
694
|
-
* @memberof Debug */
|
|
695
|
-
const enableAsserts = true;
|
|
696
|
-
|
|
697
699
|
/** Size to render debug points by default
|
|
698
700
|
* @type {number}
|
|
699
701
|
* @default
|
|
@@ -724,15 +726,16 @@ let debugPrimitives = [], debugPhysics = false, debugRaycast = false, debugParti
|
|
|
724
726
|
///////////////////////////////////////////////////////////////////////////////
|
|
725
727
|
// Debug helper functions
|
|
726
728
|
|
|
727
|
-
/** Asserts if the expression is false, does
|
|
729
|
+
/** Asserts if the expression is false, does nothing in release builds
|
|
728
730
|
* @param {boolean} assert
|
|
729
731
|
* @param {...Object} [output] - error message output
|
|
730
732
|
* @memberof Debug */
|
|
731
|
-
function ASSERT(assert, ...output)
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
733
|
+
function ASSERT(assert, ...output) { console.assert(assert, ...output); }
|
|
734
|
+
|
|
735
|
+
/** Log to console if debug is enabled, does nothing in release builds
|
|
736
|
+
* @param {...Object} [output] - message output
|
|
737
|
+
* @memberof Debug */
|
|
738
|
+
function LOG(...output) { console.log(...output); }
|
|
736
739
|
|
|
737
740
|
/** Draw a debug rectangle in world space
|
|
738
741
|
* @param {Vector2} pos
|
|
@@ -1127,7 +1130,8 @@ function debugRender()
|
|
|
1127
1130
|
{
|
|
1128
1131
|
overlayContext.fillText(`${engineName} v${engineVersion}`, x, y += h/2 );
|
|
1129
1132
|
overlayContext.fillText('Time: ' + formatTime(time), x, y += h);
|
|
1130
|
-
overlayContext.fillText('FPS: ' + averageFPS.toFixed(1)
|
|
1133
|
+
overlayContext.fillText('FPS: ' + averageFPS.toFixed(1) + (glEnable?' WebGL':' Canvas2D'),
|
|
1134
|
+
x, y += h);
|
|
1131
1135
|
overlayContext.fillText('Objects: ' + engineObjects.length, x, y += h);
|
|
1132
1136
|
overlayContext.fillText('Draw Count: ' + drawCount, x, y += h);
|
|
1133
1137
|
overlayContext.fillText('---------', x, y += h);
|
|
@@ -1146,12 +1150,18 @@ function debugRender()
|
|
|
1146
1150
|
overlayContext.fillText('6: Toggle Video Capture', x, y += h);
|
|
1147
1151
|
|
|
1148
1152
|
let keysPressed = '';
|
|
1153
|
+
let mousePressed = '';
|
|
1149
1154
|
for (const i in inputData[0])
|
|
1150
1155
|
{
|
|
1151
|
-
if (keyIsDown(i, 0))
|
|
1156
|
+
if (!keyIsDown(i, 0))
|
|
1157
|
+
continue;
|
|
1158
|
+
if (parseInt(i) < 3)
|
|
1159
|
+
mousePressed += i + ' ' ;
|
|
1160
|
+
else if (keyIsDown(i, 0))
|
|
1152
1161
|
keysPressed += i + ' ' ;
|
|
1153
1162
|
}
|
|
1154
|
-
|
|
1163
|
+
mousePressed && overlayContext.fillText('Mouse: ' + mousePressed, x, y += h);
|
|
1164
|
+
keysPressed && overlayContext.fillText('Keys: ' + keysPressed, x, y += h);
|
|
1155
1165
|
|
|
1156
1166
|
let buttonsPressed = '';
|
|
1157
1167
|
if (inputData[1])
|
|
@@ -1219,7 +1229,7 @@ function debugVideoCaptureStart()
|
|
|
1219
1229
|
}
|
|
1220
1230
|
|
|
1221
1231
|
// start recording
|
|
1222
|
-
|
|
1232
|
+
LOG('Video capture started.');
|
|
1223
1233
|
debugVideoCapture.start();
|
|
1224
1234
|
debugVideoCaptureTimer = new Timer(0);
|
|
1225
1235
|
|
|
@@ -1246,7 +1256,7 @@ function debugVideoCaptureStop()
|
|
|
1246
1256
|
return; // not recording
|
|
1247
1257
|
|
|
1248
1258
|
// stop recording
|
|
1249
|
-
|
|
1259
|
+
LOG(`Video capture ended. ${debugVideoCaptureTimer.get().toFixed(2)} seconds recorded.`);
|
|
1250
1260
|
debugVideoCapture.stop();
|
|
1251
1261
|
debugVideoCapture = 0;
|
|
1252
1262
|
debugVideoCaptureIcon.style.display = 'none';
|
|
@@ -1480,7 +1490,12 @@ function wave(frequency=1, amplitude=1, t=time, offset=0)
|
|
|
1480
1490
|
* @param {number} t - time in seconds
|
|
1481
1491
|
* @return {string}
|
|
1482
1492
|
* @memberof Utilities */
|
|
1483
|
-
function formatTime(t)
|
|
1493
|
+
function formatTime(t)
|
|
1494
|
+
{
|
|
1495
|
+
const sign = t < 0 ? '-' : '';
|
|
1496
|
+
t = abs(t)|0;
|
|
1497
|
+
return sign + (t/60|0) + ':' + (t%60<10?'0':'') + t%60;
|
|
1498
|
+
}
|
|
1484
1499
|
|
|
1485
1500
|
/** Fetches a JSON file from a URL and returns the parsed JSON object. Must be used with await!
|
|
1486
1501
|
* @param {string} url - URL of JSON file
|
|
@@ -1816,11 +1831,7 @@ class Vector2
|
|
|
1816
1831
|
direction()
|
|
1817
1832
|
{ return abs(this.x) > abs(this.y) ? this.x < 0 ? 3 : 1 : this.y < 0 ? 2 : 0; }
|
|
1818
1833
|
|
|
1819
|
-
/** Returns a copy of this vector
|
|
1820
|
-
* @return {Vector2} */
|
|
1821
|
-
invert() { return new Vector2(this.y, -this.x); }
|
|
1822
|
-
|
|
1823
|
-
/** Returns a copy of this vector absolute values
|
|
1834
|
+
/** Returns a copy of this vector with absolute values
|
|
1824
1835
|
* @return {Vector2} */
|
|
1825
1836
|
abs() { return new Vector2(abs(this.x), abs(this.y)); }
|
|
1826
1837
|
|
|
@@ -1862,13 +1873,10 @@ class Vector2
|
|
|
1862
1873
|
toString(digits=3)
|
|
1863
1874
|
{
|
|
1864
1875
|
ASSERT_NUMBER_VALID(digits);
|
|
1865
|
-
if (
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
else
|
|
1870
|
-
return `(${this.x}, ${this.y})`;
|
|
1871
|
-
}
|
|
1876
|
+
if (this.isValid())
|
|
1877
|
+
return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`;
|
|
1878
|
+
else
|
|
1879
|
+
return `(${this.x}, ${this.y})`;
|
|
1872
1880
|
}
|
|
1873
1881
|
|
|
1874
1882
|
/** Checks if this is a valid vector
|
|
@@ -2257,7 +2265,7 @@ class Timer
|
|
|
2257
2265
|
|
|
2258
2266
|
/** Returns this timer expressed as a string
|
|
2259
2267
|
* @return {string} */
|
|
2260
|
-
toString() {
|
|
2268
|
+
toString() { return this.isSet() ? Math.abs(this.get()) + ' seconds ' + (this.get()<0 ? 'before' : 'after' ) : 'unset'; }
|
|
2261
2269
|
|
|
2262
2270
|
/** Get how long since elapsed, returns 0 if not set (returns negative if currently active)
|
|
2263
2271
|
* @return {number} */
|
|
@@ -2485,6 +2493,12 @@ let touchGamepadEnable = false;
|
|
|
2485
2493
|
* @memberof Settings */
|
|
2486
2494
|
let touchGamepadAnalog = true;
|
|
2487
2495
|
|
|
2496
|
+
/** Number of buttons on touch gamepad
|
|
2497
|
+
* @type {number}
|
|
2498
|
+
* @default
|
|
2499
|
+
* @memberof Settings */
|
|
2500
|
+
let touchGamepadButtonCount = 4;
|
|
2501
|
+
|
|
2488
2502
|
/** Size of virtual gamepad for touch devices in pixels
|
|
2489
2503
|
* @type {number}
|
|
2490
2504
|
* @default
|
|
@@ -4515,7 +4529,7 @@ function inputInit()
|
|
|
4515
4529
|
function onMouseLeave()
|
|
4516
4530
|
{
|
|
4517
4531
|
// set mouse position and delta when leaving canvas
|
|
4518
|
-
mousePosScreen = vec2(
|
|
4532
|
+
mousePosScreen = vec2(-1);
|
|
4519
4533
|
mouseDeltaScreen = vec2(0);
|
|
4520
4534
|
}
|
|
4521
4535
|
}
|
|
@@ -4570,10 +4584,12 @@ function gamepadsUpdate()
|
|
|
4570
4584
|
const data = inputData[1] || (inputData[1] = []);
|
|
4571
4585
|
for (let i=10; i--;)
|
|
4572
4586
|
{
|
|
4573
|
-
const
|
|
4574
|
-
|
|
4575
|
-
data[j] = touchGamepadButtons[i] ? wasDown ? 1 : 3 : wasDown ? 4 : 0;
|
|
4587
|
+
const wasDown = gamepadIsDown(i,0);
|
|
4588
|
+
data[i] = touchGamepadButtons[i] ? wasDown ? 1 : 3 : wasDown ? 4 : 0;
|
|
4576
4589
|
}
|
|
4590
|
+
|
|
4591
|
+
// disable normal gamepads when touch gamepad is active
|
|
4592
|
+
return;
|
|
4577
4593
|
}
|
|
4578
4594
|
|
|
4579
4595
|
// return if gamepads are disabled or not supported
|
|
@@ -4648,6 +4664,15 @@ const isTouchDevice = !headlessMode && window.ontouchstart !== undefined;
|
|
|
4648
4664
|
// touch gamepad internal variables
|
|
4649
4665
|
let touchGamepadTimer = new Timer, touchGamepadButtons = [], touchGamepadStick = vec2();
|
|
4650
4666
|
|
|
4667
|
+
function touchGamepadButtonCenter()
|
|
4668
|
+
{
|
|
4669
|
+
// draw right face buttons
|
|
4670
|
+
let center = vec2(mainCanvasSize.x-touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
4671
|
+
if (touchGamepadButtonCount <= 2)
|
|
4672
|
+
center.x += touchGamepadSize/2;
|
|
4673
|
+
return center;
|
|
4674
|
+
}
|
|
4675
|
+
|
|
4651
4676
|
// enable touch input mouse passthrough
|
|
4652
4677
|
function touchInputInit()
|
|
4653
4678
|
{
|
|
@@ -4695,8 +4720,8 @@ function touchInputInit()
|
|
|
4695
4720
|
// set was touching
|
|
4696
4721
|
wasTouching = touching;
|
|
4697
4722
|
|
|
4698
|
-
// prevent default handling like copy
|
|
4699
|
-
if (inputPreventDefault && document.hasFocus()
|
|
4723
|
+
// prevent default handling like copy, magnifier lens, and scrolling
|
|
4724
|
+
if (inputPreventDefault && document.hasFocus() && e.cancelable)
|
|
4700
4725
|
e.preventDefault();
|
|
4701
4726
|
|
|
4702
4727
|
// must return true so the document will get focus
|
|
@@ -4725,25 +4750,36 @@ function touchInputInit()
|
|
|
4725
4750
|
|
|
4726
4751
|
// get center of left and right sides
|
|
4727
4752
|
const stickCenter = vec2(touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
4728
|
-
const buttonCenter =
|
|
4753
|
+
const buttonCenter = touchGamepadButtonCenter();
|
|
4729
4754
|
const startCenter = mainCanvasSize.scale(.5);
|
|
4730
4755
|
|
|
4731
4756
|
// check each touch point
|
|
4732
4757
|
for (const touch of e.touches)
|
|
4733
4758
|
{
|
|
4734
4759
|
const touchPos = mouseEventToScreen(vec2(touch.clientX, touch.clientY));
|
|
4735
|
-
if (
|
|
4760
|
+
if (stickCenter.distance(touchPos) < touchGamepadSize)
|
|
4736
4761
|
{
|
|
4737
4762
|
// virtual analog stick
|
|
4738
4763
|
touchGamepadStick = touchPos.subtract(stickCenter).scale(2/touchGamepadSize).clampLength();
|
|
4739
4764
|
}
|
|
4740
|
-
else if (
|
|
4765
|
+
else if (buttonCenter.distance(touchPos) < touchGamepadSize)
|
|
4741
4766
|
{
|
|
4742
4767
|
// virtual face buttons
|
|
4743
|
-
|
|
4744
|
-
|
|
4768
|
+
let button = buttonCenter.subtract(touchPos).direction();
|
|
4769
|
+
button = mod(button+2, 4);
|
|
4770
|
+
if (touchGamepadButtonCount === 1)
|
|
4771
|
+
button = 0;
|
|
4772
|
+
else if (touchGamepadButtonCount === 2)
|
|
4773
|
+
{
|
|
4774
|
+
const delta = buttonCenter.subtract(touchPos);
|
|
4775
|
+
button = -delta.x < delta.y ? 1 : 0;
|
|
4776
|
+
}
|
|
4777
|
+
// fix button locations (swap 2 and 3 to match gamepad layout)
|
|
4778
|
+
button = button === 3 ? 2 : button === 2 ? 3 : button;
|
|
4779
|
+
if (button < touchGamepadButtonCount)
|
|
4780
|
+
touchGamepadButtons[button] = 1;
|
|
4745
4781
|
}
|
|
4746
|
-
else if (
|
|
4782
|
+
else if (startCenter.distance(touchPos) < touchGamepadSize && !wasTouching)
|
|
4747
4783
|
{
|
|
4748
4784
|
// virtual start button in center
|
|
4749
4785
|
touchGamepadButtons[9] = 1;
|
|
@@ -4774,11 +4810,10 @@ function touchGamepadRender()
|
|
|
4774
4810
|
// draw left analog stick
|
|
4775
4811
|
context.fillStyle = touchGamepadStick.lengthSquared() > 0 ? '#fff' : '#000';
|
|
4776
4812
|
context.beginPath();
|
|
4777
|
-
|
|
4778
|
-
const leftCenter = vec2(touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
4813
|
+
const stickCenter = vec2(touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
4779
4814
|
if (touchGamepadAnalog) // draw circle shaped gamepad
|
|
4780
4815
|
{
|
|
4781
|
-
context.arc(
|
|
4816
|
+
context.arc(stickCenter.x, stickCenter.y, touchGamepadSize/2, 0, 9);
|
|
4782
4817
|
context.fill();
|
|
4783
4818
|
context.stroke();
|
|
4784
4819
|
}
|
|
@@ -4787,21 +4822,27 @@ function touchGamepadRender()
|
|
|
4787
4822
|
for (let i=10; i--;)
|
|
4788
4823
|
{
|
|
4789
4824
|
const angle = i*PI/4;
|
|
4790
|
-
context.arc(
|
|
4791
|
-
i%2 && context.arc(
|
|
4825
|
+
context.arc(stickCenter.x, stickCenter.y,touchGamepadSize*.6, angle + PI/8, angle + PI/8);
|
|
4826
|
+
i%2 && context.arc(stickCenter.x, stickCenter.y, touchGamepadSize*.33, angle, angle);
|
|
4792
4827
|
i===1 && context.fill();
|
|
4793
4828
|
}
|
|
4794
4829
|
context.stroke();
|
|
4795
4830
|
}
|
|
4796
4831
|
|
|
4797
4832
|
// draw right face buttons
|
|
4798
|
-
const
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4833
|
+
const buttonCenter = touchGamepadButtonCenter();
|
|
4834
|
+
const buttonSize = touchGamepadButtonCount > 1 ? touchGamepadSize/4 : touchGamepadSize/2;
|
|
4835
|
+
for (let i=0; i<touchGamepadButtonCount; i++)
|
|
4836
|
+
{
|
|
4837
|
+
let j = mod(i-1, 4);
|
|
4838
|
+
let button = touchGamepadButtonCount > 2 ?
|
|
4839
|
+
j : min(j, touchGamepadButtonCount-1);
|
|
4840
|
+
// fix button locations (swap 2 and 3 to match gamepad layout)
|
|
4841
|
+
button = button === 3 ? 2 : button === 2 ? 3 : button;
|
|
4842
|
+
const pos = buttonCenter.add(vec2().setDirection(j, touchGamepadSize/2));
|
|
4843
|
+
context.fillStyle = touchGamepadButtons[button] ? '#fff' : '#000';
|
|
4803
4844
|
context.beginPath();
|
|
4804
|
-
context.arc(pos.x, pos.y,
|
|
4845
|
+
context.arc(pos.x, pos.y, buttonSize, 0,9);
|
|
4805
4846
|
context.fill();
|
|
4806
4847
|
context.stroke();
|
|
4807
4848
|
}
|
|
@@ -5591,6 +5632,12 @@ function tileCollisionLoad(tileMapData, tileInfo=tile(), renderOrder=0, collisio
|
|
|
5591
5632
|
const tileLayer = new TileCollisionLayer(vec2(), levelSize, tileInfo, layerRenderOrder);
|
|
5592
5633
|
tileLayers[layerIndex] = tileLayer;
|
|
5593
5634
|
|
|
5635
|
+
// apply layer color
|
|
5636
|
+
const layerColor = dataLayer.color || WHITE;
|
|
5637
|
+
if (dataLayer.tintcolor)
|
|
5638
|
+
layerColor.setHex(dataLayer.tintcolor);
|
|
5639
|
+
ASSERT(isColor(layerColor), 'layer color is not a color');
|
|
5640
|
+
|
|
5594
5641
|
for (let x=levelSize.x; x--;)
|
|
5595
5642
|
for (let y=levelSize.y; y--;)
|
|
5596
5643
|
{
|
|
@@ -5598,7 +5645,7 @@ function tileCollisionLoad(tileMapData, tileInfo=tile(), renderOrder=0, collisio
|
|
|
5598
5645
|
const data = dataLayer.data[x + y*levelSize.x];
|
|
5599
5646
|
if (data)
|
|
5600
5647
|
{
|
|
5601
|
-
const layerData = new TileLayerData(data-1);
|
|
5648
|
+
const layerData = new TileLayerData(data-1, 0, false, layerColor);
|
|
5602
5649
|
tileLayer.setData(pos, layerData);
|
|
5603
5650
|
|
|
5604
5651
|
// set collision for top layer
|
|
@@ -7492,7 +7539,7 @@ class NewgroundsPlugin
|
|
|
7492
7539
|
// get medals
|
|
7493
7540
|
const medalsResult = this.call('Medal.getList');
|
|
7494
7541
|
this.medals = medalsResult ? medalsResult.result.data['medals'] : [];
|
|
7495
|
-
debugMedals &&
|
|
7542
|
+
debugMedals && LOG(this.medals);
|
|
7496
7543
|
for (const newgroundsMedal of this.medals)
|
|
7497
7544
|
{
|
|
7498
7545
|
const medal = medals[newgroundsMedal['id']];
|
|
@@ -7515,7 +7562,7 @@ class NewgroundsPlugin
|
|
|
7515
7562
|
// get scoreboards
|
|
7516
7563
|
const scoreboardResult = this.call('ScoreBoard.getBoards');
|
|
7517
7564
|
this.scoreboards = scoreboardResult ? scoreboardResult.result.data.scoreboards : [];
|
|
7518
|
-
debugMedals &&
|
|
7565
|
+
debugMedals && LOG(this.scoreboards);
|
|
7519
7566
|
|
|
7520
7567
|
// keep the session alive with a ping every minute
|
|
7521
7568
|
const keepAliveMS = 60 * 1e3;
|
|
@@ -7584,10 +7631,10 @@ class NewgroundsPlugin
|
|
|
7584
7631
|
try { xmlHttp.send(formData); }
|
|
7585
7632
|
catch(e)
|
|
7586
7633
|
{
|
|
7587
|
-
debugMedals &&
|
|
7634
|
+
debugMedals && LOG('newgrounds call failed', e);
|
|
7588
7635
|
return;
|
|
7589
7636
|
}
|
|
7590
|
-
debugMedals &&
|
|
7637
|
+
debugMedals && LOG(xmlHttp.responseText);
|
|
7591
7638
|
return xmlHttp.responseText && JSON.parse(xmlHttp.responseText);
|
|
7592
7639
|
}
|
|
7593
7640
|
}
|
|
@@ -8157,7 +8204,7 @@ class UIObject
|
|
|
8157
8204
|
const mouseDown = mouseIsDown(0);
|
|
8158
8205
|
const mousePress = this.dragActivate ? mouseDown : mouseWasPressed(0);
|
|
8159
8206
|
if (!uiSystem.hoverObject)
|
|
8160
|
-
if (mousePress || !mouseDown
|
|
8207
|
+
if (mousePress || isActive || (!mouseDown && !isTouchDevice))
|
|
8161
8208
|
{
|
|
8162
8209
|
const size = this.size.add(vec2(isTouchDevice && this.extraTouchSize || 0));
|
|
8163
8210
|
if (isOverlapping(this.pos, size, mousePosScreen))
|
|
@@ -10184,7 +10231,7 @@ async function box2dInit()
|
|
|
10184
10231
|
}
|
|
10185
10232
|
function box2dRender()
|
|
10186
10233
|
{
|
|
10187
|
-
if (box2dDebug || debugPhysics
|
|
10234
|
+
if (box2dDebug || debugPhysics)
|
|
10188
10235
|
box2d.world.DrawDebugData();
|
|
10189
10236
|
}
|
|
10190
10237
|
|
|
@@ -10421,6 +10468,7 @@ export
|
|
|
10421
10468
|
|
|
10422
10469
|
// Debug
|
|
10423
10470
|
ASSERT,
|
|
10471
|
+
LOG,
|
|
10424
10472
|
debugRect,
|
|
10425
10473
|
debugPoly,
|
|
10426
10474
|
debugCircle,
|