littlejsengine 1.4.7 → 1.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/build.bat +7 -3
- package/engine/engine.all.js +266 -295
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.module.js +276 -315
- package/engine/engine.all.module.min.js +1 -0
- package/engine/engine.all.release.js +266 -295
- package/engine/engine.js +21 -30
- package/engine/engineAudio.js +8 -15
- package/engine/engineBuild.bat +10 -3
- package/engine/engineDraw.js +14 -18
- package/engine/engineExport.js +10 -20
- package/engine/engineInput.js +84 -71
- package/engine/engineMedals.js +25 -32
- package/engine/engineObject.js +2 -2
- package/engine/engineParticles.js +7 -6
- package/engine/engineSettings.js +27 -27
- package/engine/engineTileLayer.js +15 -16
- package/engine/engineUtilities.js +26 -13
- package/engine/engineWebGL.js +38 -66
- package/engine/index.d.ts +52 -39
- package/examples/breakout/index.html +3 -3
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +12 -12
- package/examples/platformer/index.html +6 -6
- package/examples/puzzle/index.html +2 -2
- package/examples/stress/index.html +1 -1
- package/favicon.png +0 -0
- package/game.js +6 -8
- package/index.html +13 -13
- package/package.json +1 -1
- package/engine/engine.all.release.module.js +0 -4464
package/engine/engine.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
- Particle effect system
|
|
14
14
|
- Medal system tracks and displays achievements
|
|
15
15
|
- Debug tools and debug rendering system
|
|
16
|
+
- Post processing effects
|
|
16
17
|
- Call engineInit() to start it up!
|
|
17
18
|
*/
|
|
18
19
|
|
|
@@ -22,7 +23,7 @@
|
|
|
22
23
|
const engineName = 'LittleJS';
|
|
23
24
|
|
|
24
25
|
/** Version of engine */
|
|
25
|
-
const engineVersion = '1.4.
|
|
26
|
+
const engineVersion = '1.4.8';
|
|
26
27
|
|
|
27
28
|
/** Frames per second to update objects
|
|
28
29
|
* @default */
|
|
@@ -47,14 +48,13 @@ let time = 0;
|
|
|
47
48
|
/** Actual clock time since start in seconds (not affected by pause or frame rate clamping) */
|
|
48
49
|
let timeReal = 0;
|
|
49
50
|
|
|
50
|
-
/** Is the game paused? Causes time and objects to not be updated
|
|
51
|
+
/** Is the game paused? Causes time and objects to not be updated */
|
|
51
52
|
let paused = 0;
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
let averageFPS, drawCount;
|
|
54
|
+
/** Set if game is paused
|
|
55
|
+
* @param {Boolean} paused
|
|
56
|
+
*/
|
|
57
|
+
function setPaused(_paused) { paused = _paused; }
|
|
58
58
|
|
|
59
59
|
///////////////////////////////////////////////////////////////////////////////
|
|
60
60
|
|
|
@@ -75,13 +75,11 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
75
75
|
tileImageFixBleed = vec2(tileFixBleedScale).divide(tileImageSize = vec2(tileImage.width, tileImage.height));
|
|
76
76
|
debug && (tileImage.onload=()=>ASSERT(1)); // tile sheet can not reloaded
|
|
77
77
|
|
|
78
|
-
// setup
|
|
78
|
+
// setup html
|
|
79
79
|
const styleBody = 'margin:0;overflow:hidden;background:#000' + // fill the window
|
|
80
80
|
';touch-action:none' + // prevent mobile pinch to resize
|
|
81
81
|
';user-select:none' + // prevent mobile hold to select
|
|
82
|
-
';-webkit-user-select:none
|
|
83
|
-
|
|
84
|
-
// setup html
|
|
82
|
+
';-webkit-user-select:none'; // compatibility for ios
|
|
85
83
|
document.body.style = styleBody;
|
|
86
84
|
document.body.appendChild(mainCanvas = document.createElement('canvas'));
|
|
87
85
|
mainContext = mainCanvas.getContext('2d');
|
|
@@ -96,7 +94,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
96
94
|
|
|
97
95
|
// set canvas style to fill the window
|
|
98
96
|
const styleCanvas = 'position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)';
|
|
99
|
-
(glCanvas||mainCanvas).style =
|
|
97
|
+
(glCanvas||mainCanvas).style = mainCanvas.style = overlayCanvas.style = styleCanvas;
|
|
100
98
|
|
|
101
99
|
gameInit();
|
|
102
100
|
touchGamepadCreate();
|
|
@@ -104,16 +102,16 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
104
102
|
};
|
|
105
103
|
|
|
106
104
|
// frame time tracking
|
|
107
|
-
let frameTimeLastMS = 0, frameTimeBufferMS
|
|
105
|
+
let frameTimeLastMS = 0, frameTimeBufferMS, averageFPS;
|
|
108
106
|
|
|
109
107
|
// main update loop
|
|
110
|
-
|
|
108
|
+
function engineUpdate(frameTimeMS=0)
|
|
111
109
|
{
|
|
112
110
|
// update time keeping
|
|
113
111
|
let frameTimeDeltaMS = frameTimeMS - frameTimeLastMS;
|
|
114
112
|
frameTimeLastMS = frameTimeMS;
|
|
115
113
|
if (debug || showWatermark)
|
|
116
|
-
averageFPS = lerp(.05, averageFPS
|
|
114
|
+
averageFPS = lerp(.05, averageFPS, 1e3/(frameTimeDeltaMS||1));
|
|
117
115
|
const debugSpeedUp = debug && keyIsDown(107); // +
|
|
118
116
|
const debugSpeedDown = debug && keyIsDown(109); // -
|
|
119
117
|
if (debug)
|
|
@@ -125,24 +123,19 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
125
123
|
|
|
126
124
|
if (canvasFixedSize.x)
|
|
127
125
|
{
|
|
128
|
-
// clear set fixed size
|
|
126
|
+
// clear canvas and set fixed size
|
|
129
127
|
overlayCanvas.width = mainCanvas.width = canvasFixedSize.x;
|
|
130
128
|
overlayCanvas.height = mainCanvas.height = canvasFixedSize.y;
|
|
131
129
|
|
|
132
130
|
// fit to window by adding space on top or bottom if necessary
|
|
133
131
|
const aspect = innerWidth / innerHeight;
|
|
134
132
|
const fixedAspect = mainCanvas.width / mainCanvas.height;
|
|
135
|
-
mainCanvas.style.width
|
|
136
|
-
mainCanvas.style.height = overlayCanvas.style.height = aspect < fixedAspect ? '' : '100%';
|
|
137
|
-
if (glCanvas)
|
|
138
|
-
{
|
|
139
|
-
glCanvas.style.width = mainCanvas.style.width;
|
|
140
|
-
glCanvas.style.height = mainCanvas.style.height;
|
|
141
|
-
}
|
|
133
|
+
(glCanvas||mainCanvas).style.width = mainCanvas.style.width = overlayCanvas.style.width = aspect < fixedAspect ? '100%' : '';
|
|
134
|
+
(glCanvas||mainCanvas).style.height = mainCanvas.style.height = overlayCanvas.style.height = aspect < fixedAspect ? '' : '100%';
|
|
142
135
|
}
|
|
143
136
|
else
|
|
144
137
|
{
|
|
145
|
-
|
|
138
|
+
// clear canvas and set size to same as window
|
|
146
139
|
overlayCanvas.width = mainCanvas.width = min(innerWidth, canvasMaxSize.x);
|
|
147
140
|
overlayCanvas.height = mainCanvas.height = min(innerHeight, canvasMaxSize.y);
|
|
148
141
|
}
|
|
@@ -209,7 +202,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
209
202
|
overlayContext.fillStyle = '#000';
|
|
210
203
|
const text = engineName + ' ' + 'v' + engineVersion + ' / '
|
|
211
204
|
+ drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
|
|
212
|
-
+
|
|
205
|
+
+ (glEnable ? ' GL' : ' 2D') ;
|
|
213
206
|
overlayContext.fillText(text, mainCanvas.width-3, 3);
|
|
214
207
|
overlayContext.fillStyle = '#fff';
|
|
215
208
|
overlayContext.fillText(text, mainCanvas.width-2, 2);
|
|
@@ -223,7 +216,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
223
216
|
tileImageSource ? tileImage.src = tileImageSource : tileImage.onload();
|
|
224
217
|
}
|
|
225
218
|
|
|
226
|
-
//
|
|
219
|
+
// Called automatically by engine to setup render system
|
|
227
220
|
function enginePreRender()
|
|
228
221
|
{
|
|
229
222
|
// save canvas size
|
|
@@ -233,12 +226,10 @@ function enginePreRender()
|
|
|
233
226
|
mainContext.imageSmoothingEnabled = !cavasPixelated;
|
|
234
227
|
|
|
235
228
|
// setup gl rendering if enabled
|
|
236
|
-
glEnable && glPreRender(
|
|
229
|
+
glEnable && glPreRender();
|
|
237
230
|
}
|
|
238
231
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
/** Calls update on each engine object (recursively if child), removes destroyed objects, and updated time */
|
|
232
|
+
/** Update each engine object, remove destroyed objects, and update time */
|
|
242
233
|
function engineObjectsUpdate()
|
|
243
234
|
{
|
|
244
235
|
// get list of solid objects for physics optimzation
|
package/engine/engineAudio.js
CHANGED
|
@@ -57,7 +57,7 @@ class Sound
|
|
|
57
57
|
{
|
|
58
58
|
if (!soundEnable) return;
|
|
59
59
|
|
|
60
|
-
let pan
|
|
60
|
+
let pan;
|
|
61
61
|
if (pos)
|
|
62
62
|
{
|
|
63
63
|
const range = this.range;
|
|
@@ -87,7 +87,7 @@ class Sound
|
|
|
87
87
|
* @param {Number} [volume=1] - How much to scale volume by (in addition to range fade)
|
|
88
88
|
* @return {AudioBufferSourceNode} - The audio, can be used to stop sound later
|
|
89
89
|
*/
|
|
90
|
-
playNote(semitoneOffset, pos, volume
|
|
90
|
+
playNote(semitoneOffset, pos, volume)
|
|
91
91
|
{
|
|
92
92
|
if (!soundEnable) return;
|
|
93
93
|
|
|
@@ -142,7 +142,7 @@ class Music
|
|
|
142
142
|
* @param {Boolean} [loop=1] - True if the music should loop when it reaches the end
|
|
143
143
|
* @return {AudioBufferSourceNode} - The audio node, can be used to stop sound later
|
|
144
144
|
*/
|
|
145
|
-
play(volume
|
|
145
|
+
play(volume, loop = 1)
|
|
146
146
|
{
|
|
147
147
|
if (!soundEnable) return;
|
|
148
148
|
|
|
@@ -224,7 +224,7 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0)
|
|
|
224
224
|
|
|
225
225
|
// create audio context
|
|
226
226
|
if (!audioContext)
|
|
227
|
-
audioContext = new
|
|
227
|
+
audioContext = new AudioContext;
|
|
228
228
|
|
|
229
229
|
// fix stalled audio
|
|
230
230
|
audioContext.resume();
|
|
@@ -243,18 +243,13 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0)
|
|
|
243
243
|
source.playbackRate.value = rate;
|
|
244
244
|
source.loop = loop;
|
|
245
245
|
|
|
246
|
-
// create and connect gain node (createGain is more
|
|
246
|
+
// create and connect gain node (createGain is more widely spported then GainNode construtor)
|
|
247
247
|
const gainNode = audioContext.createGain();
|
|
248
248
|
gainNode.gain.value = soundVolume*volume;
|
|
249
249
|
gainNode.connect(audioContext.destination);
|
|
250
250
|
|
|
251
|
-
// connect source to gain
|
|
252
|
-
(
|
|
253
|
-
window.StereoPannerNode ? // create pan node if possible
|
|
254
|
-
source.connect(new StereoPannerNode(audioContext, {'pan':clamp(pan, -1, 1)}))
|
|
255
|
-
: source
|
|
256
|
-
)
|
|
257
|
-
.connect(gainNode);
|
|
251
|
+
// connect source to stereo panner and gain
|
|
252
|
+
source.connect(new StereoPannerNode(audioContext, {'pan':clamp(pan, -1, 1)})).connect(gainNode);
|
|
258
253
|
|
|
259
254
|
// play and return sound
|
|
260
255
|
source.start();
|
|
@@ -372,10 +367,8 @@ function zzfxG
|
|
|
372
367
|
* @memberof Audio */
|
|
373
368
|
function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
374
369
|
{
|
|
370
|
+
let i, j, k;
|
|
375
371
|
let instrumentParameters;
|
|
376
|
-
let i;
|
|
377
|
-
let j;
|
|
378
|
-
let k;
|
|
379
372
|
let note;
|
|
380
373
|
let sample;
|
|
381
374
|
let patternChannel;
|
package/engine/engineBuild.bat
CHANGED
|
@@ -112,9 +112,16 @@ echo.>> %OUTPUT_FILENAME%
|
|
|
112
112
|
|
|
113
113
|
rem --- BUILD ENGINE MODULE RELEASE ---
|
|
114
114
|
|
|
115
|
-
set OUTPUT_FILENAME=engine.all.
|
|
115
|
+
set OUTPUT_FILENAME=engine.all.module.min.js
|
|
116
116
|
del %OUTPUT_FILENAME%
|
|
117
|
-
type engine.all.
|
|
117
|
+
type engine.all.min.js >> %OUTPUT_FILENAME%
|
|
118
118
|
echo.>> %OUTPUT_FILENAME%
|
|
119
119
|
type engineExport.js >> %OUTPUT_FILENAME%
|
|
120
|
-
echo.>> %OUTPUT_FILENAME%
|
|
120
|
+
echo.>> %OUTPUT_FILENAME%
|
|
121
|
+
|
|
122
|
+
rem lightly minify with uglify
|
|
123
|
+
call npx uglifyjs -o %OUTPUT_FILENAME% -- %OUTPUT_FILENAME%
|
|
124
|
+
if %ERRORLEVEL% NEQ 0 (
|
|
125
|
+
pause
|
|
126
|
+
exit /b %ERRORLEVEL%
|
|
127
|
+
)
|
package/engine/engineDraw.js
CHANGED
|
@@ -22,11 +22,6 @@
|
|
|
22
22
|
|
|
23
23
|
'use strict';
|
|
24
24
|
|
|
25
|
-
/** Tile sheet for batch rendering system
|
|
26
|
-
* @type {Image}
|
|
27
|
-
* @memberof Draw */
|
|
28
|
-
const tileImage = new Image();
|
|
29
|
-
|
|
30
25
|
/** The primary 2D canvas visible to the user
|
|
31
26
|
* @type {HTMLCanvasElement}
|
|
32
27
|
* @memberof Draw */
|
|
@@ -52,6 +47,14 @@ let overlayContext;
|
|
|
52
47
|
* @memberof Draw */
|
|
53
48
|
let mainCanvasSize = vec2();
|
|
54
49
|
|
|
50
|
+
/** Tile sheet for batch rendering system
|
|
51
|
+
* @type {Image}
|
|
52
|
+
* @memberof Draw */
|
|
53
|
+
const tileImage = new Image;
|
|
54
|
+
|
|
55
|
+
// Engine internal variables not exposed to documentation
|
|
56
|
+
let tileImageSize, tileImageFixBleed, drawCount;
|
|
57
|
+
|
|
55
58
|
/** Convert from screen to world space coordinates
|
|
56
59
|
* - if calling outside of render, you may need to manually set mainCanvasSize
|
|
57
60
|
* @param {Vector2} screenPos
|
|
@@ -76,7 +79,7 @@ const worldToScreen = (worldPos)=>
|
|
|
76
79
|
|
|
77
80
|
/** Draw textured tile centered in world space, with color applied if using WebGL
|
|
78
81
|
* @param {Vector2} pos - Center of the tile in world space
|
|
79
|
-
* @param {Vector2} [size=new Vector2(1,1)] - Size of the tile in world space
|
|
82
|
+
* @param {Vector2} [size=new Vector2(1,1)] - Size of the tile in world space
|
|
80
83
|
* @param {Number} [tileIndex=-1] - Tile index to use, negative is untextured
|
|
81
84
|
* @param {Vector2} [tileSize=tileSizeDefault] - Tile size in source pixels
|
|
82
85
|
* @param {Color} [color=new Color(1,1,1)] - Color to modulate with
|
|
@@ -295,10 +298,10 @@ class FontImage
|
|
|
295
298
|
*/
|
|
296
299
|
constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1), startTileIndex=0, context=overlayContext)
|
|
297
300
|
{
|
|
298
|
-
if (!
|
|
301
|
+
if (!engineFontImage)
|
|
299
302
|
{
|
|
300
303
|
// load default font image
|
|
301
|
-
engineFontImage = new Image
|
|
304
|
+
engineFontImage = new Image;
|
|
302
305
|
engineFontImage.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAAYAQAAAAA9+x6JAAAAAnRSTlMAAHaTzTgAAAGiSURBVHjaZZABhxxBEIUf6ECLBdFY+Q0PMNgf0yCgsSAGZcT9sgIPtBWwIA5wgAPEoHUyJeeSlW+gjK+fegWwtROWpVQEyWh2npdpBmTUFVhb29RINgLIukoXr5LIAvYQ5ve+1FqWEMqNKTX3FAJHyQDRZvmKWubAACcv5z5Gtg2oyCWE+Yk/8JZQX1jTTCpKAFGIgza+dJCNBF2UskRlsgwitHbSV0QLgt9sTPtsRlvJjEr8C/FARWA2bJ/TtJ7lko34dNDn6usJUMzuErP89UUBJbWeozrwLLncXczd508deAjLWipLO4Q5XGPcJvPu92cNDaN0P5G1FL0nSOzddZOrJ6rNhbXGmeDvO3TF7DeJWl4bvaYQTNHCTeuqKZmbjHaSOFes+IX/+IhHrnAkXOAsfn24EM68XieIECoccD4KZLk/odiwzeo2rovYdhvb2HYFgyznJyDpYJdYOmfXgVdJTaUi4xA2uWYNYec9BLeqdl9EsoTw582mSFDX2DxVLbNt9U3YYoeatBad1c2Tj8t2akrjaIGJNywKB/7h75/gN3vCMSaadIUTAAAAAElFTkSuQmCC';
|
|
303
306
|
}
|
|
304
307
|
|
|
@@ -365,7 +368,7 @@ class FontImage
|
|
|
365
368
|
/** Returns true if fullscreen mode is active
|
|
366
369
|
* @return {Boolean}
|
|
367
370
|
* @memberof Draw */
|
|
368
|
-
const isFullscreen =()=> document.fullscreenElement;
|
|
371
|
+
const isFullscreen = ()=> document.fullscreenElement;
|
|
369
372
|
|
|
370
373
|
/** Toggle fullsceen mode
|
|
371
374
|
* @memberof Draw */
|
|
@@ -375,14 +378,7 @@ function toggleFullscreen()
|
|
|
375
378
|
{
|
|
376
379
|
if (document.exitFullscreen)
|
|
377
380
|
document.exitFullscreen();
|
|
378
|
-
else if (document.mozCancelFullScreen)
|
|
379
|
-
document.mozCancelFullScreen();
|
|
380
|
-
}
|
|
381
|
-
else
|
|
382
|
-
{
|
|
383
|
-
if (document.body.webkitRequestFullScreen)
|
|
384
|
-
document.body.webkitRequestFullScreen();
|
|
385
|
-
else if (document.body.mozRequestFullScreen)
|
|
386
|
-
document.body.mozRequestFullScreen();
|
|
387
381
|
}
|
|
382
|
+
else if (document.body.requestFullscreen)
|
|
383
|
+
document.body.requestFullscreen();
|
|
388
384
|
}
|
package/engine/engineExport.js
CHANGED
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
* <br> - Export engine as a module with extra functions where necessary
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
//
|
|
6
|
+
// Setters for all variables that devs will need to modify
|
|
7
7
|
const setCameraPos = (v)=> cameraPos = v;
|
|
8
8
|
const setCameraScale = (v)=> cameraScale = v;
|
|
9
|
-
const setRandSeed = (v)=> randSeed = v;
|
|
10
9
|
const setCanvasMaxSize = (v)=> canvasMaxSize = v;
|
|
11
10
|
const setCanvasFixedSize = (v)=> canvasFixedSize = v;
|
|
12
11
|
const setCavasPixelated = (v)=> cavasPixelated = v;
|
|
13
12
|
const setFontDefault = (v)=> fontDefault = v;
|
|
13
|
+
const setGlEnable = (v)=> glEnable = v;
|
|
14
|
+
const setGlOverlay = (v)=> glOverlay = v;
|
|
14
15
|
const setTileSizeDefault = (v)=> tileSizeDefault = v;
|
|
15
16
|
const setTileFixBleedScale = (v)=> tileFixBleedScale = v;
|
|
16
17
|
const setObjectDefaultSize = (v)=> objectDefaultSize = v;
|
|
@@ -23,8 +24,6 @@ const setObjectDefaultFriction = (v)=> objectDefaultFriction = v;
|
|
|
23
24
|
const setObjectMaxSpeed = (v)=> objectMaxSpeed = v;
|
|
24
25
|
const setGravity = (v)=> gravity = v;
|
|
25
26
|
const setParticleEmitRateScale = (v)=> particleEmitRateScale = v;
|
|
26
|
-
const setGlEnable = (v)=> glEnable = v;
|
|
27
|
-
const setGlOverlay = (v)=> glOverlay = v;
|
|
28
27
|
const setGamepadsEnable = (v)=> gamepadsEnable = v;
|
|
29
28
|
const setGamepadDirectionEmulateStick = (v)=> gamepadDirectionEmulateStick = v;
|
|
30
29
|
const setInputWASDEmulateDirection = (v)=> inputWASDEmulateDirection = v;
|
|
@@ -43,18 +42,17 @@ const setMedalDisplayWidth = (v)=> medalDisplayWidth = v;
|
|
|
43
42
|
const setMedalDisplayHeight = (v)=> medalDisplayHeight = v;
|
|
44
43
|
const setMedalDisplayIconSize = (v)=> medalDisplayIconSize = v;
|
|
45
44
|
const setMedalsPreventUnlock = (v)=> medalsPreventUnlock = v;
|
|
46
|
-
const setShowWatermark = (v)=> showWatermark = v;
|
|
47
|
-
const setGodMode = (v)=> godMode = v;
|
|
48
45
|
|
|
49
46
|
export {
|
|
50
|
-
//
|
|
47
|
+
// Setters for global variables
|
|
51
48
|
setCameraPos,
|
|
52
49
|
setCameraScale,
|
|
53
|
-
setRandSeed,
|
|
54
50
|
setCanvasMaxSize,
|
|
55
51
|
setCanvasFixedSize,
|
|
56
52
|
setCavasPixelated,
|
|
57
53
|
setFontDefault,
|
|
54
|
+
setGlEnable,
|
|
55
|
+
setGlOverlay,
|
|
58
56
|
setTileSizeDefault,
|
|
59
57
|
setTileFixBleedScale,
|
|
60
58
|
setObjectDefaultSize,
|
|
@@ -67,8 +65,6 @@ export {
|
|
|
67
65
|
setObjectMaxSpeed,
|
|
68
66
|
setGravity,
|
|
69
67
|
setParticleEmitRateScale,
|
|
70
|
-
setGlEnable,
|
|
71
|
-
setGlOverlay,
|
|
72
68
|
setGamepadsEnable,
|
|
73
69
|
setGamepadDirectionEmulateStick,
|
|
74
70
|
setInputWASDEmulateDirection,
|
|
@@ -87,8 +83,6 @@ export {
|
|
|
87
83
|
setMedalDisplayHeight,
|
|
88
84
|
setMedalDisplayIconSize,
|
|
89
85
|
setMedalsPreventUnlock,
|
|
90
|
-
setShowWatermark,
|
|
91
|
-
setGodMode,
|
|
92
86
|
|
|
93
87
|
// Settings
|
|
94
88
|
canvasMaxSize,
|
|
@@ -180,6 +174,7 @@ export {
|
|
|
180
174
|
randVector,
|
|
181
175
|
randColor,
|
|
182
176
|
randSeed,
|
|
177
|
+
setRandSeed,
|
|
183
178
|
randSeeded,
|
|
184
179
|
|
|
185
180
|
// Utility Classes
|
|
@@ -244,15 +239,12 @@ export {
|
|
|
244
239
|
// onmousemove,
|
|
245
240
|
// onwheel,
|
|
246
241
|
// oncontextmenu,
|
|
247
|
-
mouseToScreen,
|
|
248
242
|
//stickData,
|
|
243
|
+
mouseToScreen,
|
|
249
244
|
gamepadsUpdate,
|
|
250
245
|
vibrate,
|
|
251
246
|
vibrateStop,
|
|
252
247
|
isTouchDevice,
|
|
253
|
-
//touchGamepadTimer,
|
|
254
|
-
touchGamepadCreate,
|
|
255
|
-
touchGamepadRender,
|
|
256
248
|
|
|
257
249
|
// Audio
|
|
258
250
|
Sound,
|
|
@@ -320,11 +312,9 @@ export {
|
|
|
320
312
|
time,
|
|
321
313
|
timeReal,
|
|
322
314
|
paused,
|
|
323
|
-
|
|
324
|
-
drawCount,
|
|
315
|
+
setPaused,
|
|
325
316
|
engineInit,
|
|
326
|
-
|
|
327
|
-
//engineObjectsUpdate,
|
|
317
|
+
engineObjectsUpdate,
|
|
328
318
|
engineObjectsDestroy,
|
|
329
319
|
engineObjectsCallback,
|
|
330
320
|
};
|
package/engine/engineInput.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* @param {Number} [device=0]
|
|
15
15
|
* @return {Boolean}
|
|
16
16
|
* @memberof Input */
|
|
17
|
-
const keyIsDown = (key, device=0)=> inputData[device] && inputData[device][key] & 1
|
|
17
|
+
const keyIsDown = (key, device=0)=> inputData[device] && inputData[device][key] & 1;
|
|
18
18
|
|
|
19
19
|
/** Returns true if device key was pressed this frame
|
|
20
20
|
* @param {Number} key
|
|
@@ -254,35 +254,40 @@ const isTouchDevice = window.ontouchstart !== undefined;
|
|
|
254
254
|
if (isTouchDevice)
|
|
255
255
|
{
|
|
256
256
|
// override mouse events
|
|
257
|
-
|
|
258
|
-
onmousedown = onmouseup =
|
|
257
|
+
let wasTouching, mouseDown = onmousedown, mouseUp = onmouseup;
|
|
258
|
+
onmousedown = onmouseup = ()=> 0;
|
|
259
259
|
|
|
260
|
-
//
|
|
261
|
-
|
|
262
|
-
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
260
|
+
// setup touch input
|
|
261
|
+
ontouchstart = (e)=>
|
|
263
262
|
{
|
|
264
|
-
|
|
263
|
+
// fix mobile audio, force it to play a sound on first touch
|
|
264
|
+
zzfx(0);
|
|
265
265
|
|
|
266
|
-
//
|
|
267
|
-
|
|
268
|
-
if (touching)
|
|
266
|
+
// handle all touch events the same way
|
|
267
|
+
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
269
268
|
{
|
|
270
|
-
|
|
271
|
-
hadTouch || zzfx(0, hadTouch=1);
|
|
269
|
+
e.button = 0; // all touches are left click
|
|
272
270
|
|
|
273
|
-
//
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
271
|
+
// check if touching and pass to mouse events
|
|
272
|
+
const touching = e.touches.length;
|
|
273
|
+
if (touching)
|
|
274
|
+
{
|
|
275
|
+
// set event pos and pass it along
|
|
276
|
+
e.x = e.touches[0].clientX;
|
|
277
|
+
e.y = e.touches[0].clientY;
|
|
278
|
+
wasTouching ? onmousemove(e) : mouseDown(e);
|
|
279
|
+
}
|
|
280
|
+
else if (wasTouching)
|
|
281
|
+
mouseUp(e);
|
|
280
282
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
+
// set was touching
|
|
284
|
+
wasTouching = touching;
|
|
283
285
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
+
// must return true so the document will get focus
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
return ontouchstart(e);
|
|
286
291
|
}
|
|
287
292
|
}
|
|
288
293
|
|
|
@@ -290,7 +295,7 @@ if (isTouchDevice)
|
|
|
290
295
|
// touch gamepad, virtual on screen gamepad emulator for touch devices
|
|
291
296
|
|
|
292
297
|
// touch input internal variables
|
|
293
|
-
let touchGamepadTimer = new Timer, touchGamepadButtons
|
|
298
|
+
let touchGamepadTimer = new Timer, touchGamepadButtons, touchGamepadStick;
|
|
294
299
|
|
|
295
300
|
// create the touch gamepad, called automatically by the engine
|
|
296
301
|
function touchGamepadCreate()
|
|
@@ -298,65 +303,73 @@ function touchGamepadCreate()
|
|
|
298
303
|
if (!touchGamepadEnable || !isTouchDevice)
|
|
299
304
|
return;
|
|
300
305
|
|
|
301
|
-
|
|
306
|
+
// touch input internal variables
|
|
307
|
+
touchGamepadButtons = [];
|
|
308
|
+
touchGamepadStick = vec2();
|
|
309
|
+
|
|
310
|
+
// setup touch input
|
|
311
|
+
ontouchstart = (e)=>
|
|
302
312
|
{
|
|
303
|
-
|
|
304
|
-
|
|
313
|
+
// fix mobile audio, force it to play a sound on first touch
|
|
314
|
+
zzfx(0);
|
|
305
315
|
|
|
306
|
-
|
|
307
|
-
touchGamepadStick = vec2();
|
|
308
|
-
touchGamepadButtons = [];
|
|
309
|
-
|
|
310
|
-
const touching = e.touches.length;
|
|
311
|
-
if (touching)
|
|
316
|
+
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
312
317
|
{
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
if (paused)
|
|
318
|
+
// clear touch gamepad input
|
|
319
|
+
touchGamepadStick = vec2();
|
|
320
|
+
touchGamepadButtons = [];
|
|
321
|
+
|
|
322
|
+
const touching = e.touches.length;
|
|
323
|
+
if (touching)
|
|
320
324
|
{
|
|
321
|
-
//
|
|
322
|
-
|
|
323
|
-
|
|
325
|
+
// set that gamepad is active
|
|
326
|
+
isUsingGamepad = 1;
|
|
327
|
+
touchGamepadTimer.set();
|
|
328
|
+
|
|
329
|
+
if (paused)
|
|
330
|
+
{
|
|
331
|
+
// touch anywhere to press start when paused
|
|
332
|
+
touchGamepadButtons[9] = 1;
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
324
335
|
}
|
|
325
|
-
}
|
|
326
336
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
337
|
+
// get center of left and right sides
|
|
338
|
+
const stickCenter = vec2(touchGamepadSize, mainCanvasSize.y-touchGamepadSize);
|
|
339
|
+
const buttonCenter = mainCanvasSize.subtract(vec2(touchGamepadSize, touchGamepadSize));
|
|
340
|
+
const startCenter = mainCanvasSize.scale(.5);
|
|
331
341
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
{
|
|
335
|
-
const touchPos = mouseToScreen(vec2(touch.clientX, touch.clientY));
|
|
336
|
-
if (touchPos.distance(stickCenter) < touchGamepadSize)
|
|
342
|
+
// check each touch point
|
|
343
|
+
for (const touch of e.touches)
|
|
337
344
|
{
|
|
338
|
-
|
|
339
|
-
if (
|
|
340
|
-
touchGamepadStick = touchPos.subtract(stickCenter).scale(2/touchGamepadSize).clampLength();
|
|
341
|
-
else
|
|
345
|
+
const touchPos = mouseToScreen(vec2(touch.clientX, touch.clientY));
|
|
346
|
+
if (touchPos.distance(stickCenter) < touchGamepadSize)
|
|
342
347
|
{
|
|
343
|
-
//
|
|
344
|
-
|
|
345
|
-
|
|
348
|
+
// virtual analog stick
|
|
349
|
+
if (touchGamepadAnalog)
|
|
350
|
+
touchGamepadStick = touchPos.subtract(stickCenter).scale(2/touchGamepadSize).clampLength();
|
|
351
|
+
else
|
|
352
|
+
{
|
|
353
|
+
// 8 way dpad
|
|
354
|
+
const angle = touchPos.subtract(stickCenter).angle();
|
|
355
|
+
touchGamepadStick.setAngle((angle * 4 / PI + 8.5 | 0) * PI / 4);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
else if (touchPos.distance(buttonCenter) < touchGamepadSize)
|
|
359
|
+
{
|
|
360
|
+
// virtual face buttons
|
|
361
|
+
const button = touchPos.subtract(buttonCenter).direction();
|
|
362
|
+
touchGamepadButtons[button] = 1;
|
|
363
|
+
}
|
|
364
|
+
else if (touchPos.distance(startCenter) < touchGamepadSize)
|
|
365
|
+
{
|
|
366
|
+
// virtual start button in center
|
|
367
|
+
touchGamepadButtons[9] = 1;
|
|
346
368
|
}
|
|
347
|
-
}
|
|
348
|
-
else if (touchPos.distance(buttonCenter) < touchGamepadSize)
|
|
349
|
-
{
|
|
350
|
-
// virtual face buttons
|
|
351
|
-
const button = touchPos.subtract(buttonCenter).direction();
|
|
352
|
-
touchGamepadButtons[button] = 1;
|
|
353
|
-
}
|
|
354
|
-
else if (touchPos.distance(startCenter) < touchGamepadSize)
|
|
355
|
-
{
|
|
356
|
-
// virtual start button in center
|
|
357
|
-
touchGamepadButtons[9] = 1;
|
|
358
369
|
}
|
|
359
370
|
}
|
|
371
|
+
|
|
372
|
+
return ontouchstart(e);
|
|
360
373
|
}
|
|
361
374
|
}
|
|
362
375
|
|