littlejsengine 1.4.7 → 1.4.9
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/build.bat +7 -3
- package/engine/engine.all.js +291 -323
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.module.js +307 -352
- package/engine/engine.all.module.min.js +1 -0
- package/engine/engine.all.release.js +291 -323
- package/engine/engine.js +21 -30
- package/engine/engineAudio.js +8 -15
- package/engine/engineBuild.bat +10 -3
- package/engine/engineDraw.js +18 -24
- package/engine/engineExport.js +16 -29
- package/engine/engineInput.js +84 -71
- package/engine/engineMedals.js +30 -38
- package/engine/engineObject.js +8 -8
- package/engine/engineParticles.js +5 -4
- package/engine/engineSettings.js +38 -38
- package/engine/engineTileLayer.js +15 -16
- package/engine/engineUtilities.js +26 -13
- package/engine/engineWebGL.js +38 -66
- package/engine/index.d.ts +65 -54
- package/examples/breakout/game.js +10 -10
- package/examples/breakout/gameObjects.js +7 -7
- package/examples/breakout/index.html +3 -3
- package/examples/empty/tiles.png +0 -0
- package/examples/module/game.js +5 -7
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +4 -14
- 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 -9
- package/index.html +13 -13
- package/package.json +1 -1
- package/README.md +0 -75
- 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.9';
|
|
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
|
|
@@ -282,25 +285,23 @@ function drawText(text, pos, size=1, color, lineWidth, lineColor, textAlign, fon
|
|
|
282
285
|
* font.drawTextScreen("LittleJS\nHello World!", vec2(200, 50));
|
|
283
286
|
*/
|
|
284
287
|
|
|
288
|
+
// default font image created by engine
|
|
285
289
|
let engineFontImage;
|
|
286
290
|
|
|
287
291
|
class FontImage
|
|
288
292
|
{
|
|
289
293
|
/** Create an image font
|
|
290
|
-
* @param {HTMLImageElement}
|
|
291
|
-
* @param {Vector2} [tileSize=vec2(8)] -
|
|
294
|
+
* @param {HTMLImageElement} [image] - Image for the font, if undefined default font is used
|
|
295
|
+
* @param {Vector2} [tileSize=vec2(8)] - Size of the font source tiles
|
|
292
296
|
* @param {Vector2} [paddingSize=vec2(0,1)] - How much extra space to add between characters
|
|
293
297
|
* @param {Number} [startTileIndex=0] - Tile index in image where font starts
|
|
294
298
|
* @param {CanvasRenderingContext2D} [context=overlayContext] - context to draw to
|
|
295
299
|
*/
|
|
296
300
|
constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1), startTileIndex=0, context=overlayContext)
|
|
297
301
|
{
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
engineFontImage = new Image();
|
|
302
|
-
engineFontImage.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAAYAQAAAAA9+x6JAAAAAnRSTlMAAHaTzTgAAAGiSURBVHjaZZABhxxBEIUf6ECLBdFY+Q0PMNgf0yCgsSAGZcT9sgIPtBWwIA5wgAPEoHUyJeeSlW+gjK+fegWwtROWpVQEyWh2npdpBmTUFVhb29RINgLIukoXr5LIAvYQ5ve+1FqWEMqNKTX3FAJHyQDRZvmKWubAACcv5z5Gtg2oyCWE+Yk/8JZQX1jTTCpKAFGIgza+dJCNBF2UskRlsgwitHbSV0QLgt9sTPtsRlvJjEr8C/FARWA2bJ/TtJ7lko34dNDn6usJUMzuErP89UUBJbWeozrwLLncXczd508deAjLWipLO4Q5XGPcJvPu92cNDaN0P5G1FL0nSOzddZOrJ6rNhbXGmeDvO3TF7DeJWl4bvaYQTNHCTeuqKZmbjHaSOFes+IX/+IhHrnAkXOAsfn24EM68XieIECoccD4KZLk/odiwzeo2rovYdhvb2HYFgyznJyDpYJdYOmfXgVdJTaUi4xA2uWYNYec9BLeqdl9EsoTw582mSFDX2DxVLbNt9U3YYoeatBad1c2Tj8t2akrjaIGJNywKB/7h75/gN3vCMSaadIUTAAAAAElFTkSuQmCC';
|
|
303
|
-
}
|
|
302
|
+
// load default font image
|
|
303
|
+
if (!engineFontImage)
|
|
304
|
+
(engineFontImage = new Image).src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAAYAQAAAAA9+x6JAAAAAnRSTlMAAHaTzTgAAAGiSURBVHjaZZABhxxBEIUf6ECLBdFY+Q0PMNgf0yCgsSAGZcT9sgIPtBWwIA5wgAPEoHUyJeeSlW+gjK+fegWwtROWpVQEyWh2npdpBmTUFVhb29RINgLIukoXr5LIAvYQ5ve+1FqWEMqNKTX3FAJHyQDRZvmKWubAACcv5z5Gtg2oyCWE+Yk/8JZQX1jTTCpKAFGIgza+dJCNBF2UskRlsgwitHbSV0QLgt9sTPtsRlvJjEr8C/FARWA2bJ/TtJ7lko34dNDn6usJUMzuErP89UUBJbWeozrwLLncXczd508deAjLWipLO4Q5XGPcJvPu92cNDaN0P5G1FL0nSOzddZOrJ6rNhbXGmeDvO3TF7DeJWl4bvaYQTNHCTeuqKZmbjHaSOFes+IX/+IhHrnAkXOAsfn24EM68XieIECoccD4KZLk/odiwzeo2rovYdhvb2HYFgyznJyDpYJdYOmfXgVdJTaUi4xA2uWYNYec9BLeqdl9EsoTw582mSFDX2DxVLbNt9U3YYoeatBad1c2Tj8t2akrjaIGJNywKB/7h75/gN3vCMSaadIUTAAAAAElFTkSuQmCC';
|
|
304
305
|
|
|
305
306
|
this.image = image || engineFontImage;
|
|
306
307
|
this.tileSize = tileSize;
|
|
@@ -365,7 +366,7 @@ class FontImage
|
|
|
365
366
|
/** Returns true if fullscreen mode is active
|
|
366
367
|
* @return {Boolean}
|
|
367
368
|
* @memberof Draw */
|
|
368
|
-
const isFullscreen =()=> document.fullscreenElement;
|
|
369
|
+
const isFullscreen = ()=> document.fullscreenElement;
|
|
369
370
|
|
|
370
371
|
/** Toggle fullsceen mode
|
|
371
372
|
* @memberof Draw */
|
|
@@ -375,14 +376,7 @@ function toggleFullscreen()
|
|
|
375
376
|
{
|
|
376
377
|
if (document.exitFullscreen)
|
|
377
378
|
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
379
|
}
|
|
380
|
+
else if (document.body.requestFullscreen)
|
|
381
|
+
document.body.requestFullscreen();
|
|
388
382
|
}
|
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;
|
|
@@ -33,28 +32,26 @@ const setTouchGamepadAnalog = (v)=> touchGamepadAnalog = v;
|
|
|
33
32
|
const setTouchGamepadSize = (v)=> touchGamepadSize = v;
|
|
34
33
|
const setTouchGamepadAlpha = (v)=> touchGamepadAlpha = v;
|
|
35
34
|
const setVibrateEnable = (v)=> vibrateEnable = v;
|
|
36
|
-
const setSoundVolume = (v)=> soundVolume = v;
|
|
37
35
|
const setSoundEnable = (v)=> soundEnable = v;
|
|
36
|
+
const setSoundVolume = (v)=> soundVolume = v;
|
|
38
37
|
const setSoundDefaultRange = (v)=> soundDefaultRange = v;
|
|
39
38
|
const setSoundDefaultTaper = (v)=> soundDefaultTaper = v;
|
|
40
39
|
const setMedalDisplayTime = (v)=> medalDisplayTime = v;
|
|
41
40
|
const setMedalDisplaySlideTime = (v)=> medalDisplaySlideTime = v;
|
|
42
|
-
const
|
|
43
|
-
const setMedalDisplayHeight = (v)=> medalDisplayHeight = v;
|
|
41
|
+
const setMedalDisplaySize = (v)=> medalDisplaySize = v;
|
|
44
42
|
const setMedalDisplayIconSize = (v)=> medalDisplayIconSize = v;
|
|
45
43
|
const setMedalsPreventUnlock = (v)=> medalsPreventUnlock = v;
|
|
46
|
-
const setShowWatermark = (v)=> showWatermark = v;
|
|
47
|
-
const setGodMode = (v)=> godMode = v;
|
|
48
44
|
|
|
49
45
|
export {
|
|
50
|
-
//
|
|
46
|
+
// Setters for global variables
|
|
51
47
|
setCameraPos,
|
|
52
48
|
setCameraScale,
|
|
53
|
-
setRandSeed,
|
|
54
49
|
setCanvasMaxSize,
|
|
55
50
|
setCanvasFixedSize,
|
|
56
51
|
setCavasPixelated,
|
|
57
52
|
setFontDefault,
|
|
53
|
+
setGlEnable,
|
|
54
|
+
setGlOverlay,
|
|
58
55
|
setTileSizeDefault,
|
|
59
56
|
setTileFixBleedScale,
|
|
60
57
|
setObjectDefaultSize,
|
|
@@ -67,8 +64,6 @@ export {
|
|
|
67
64
|
setObjectMaxSpeed,
|
|
68
65
|
setGravity,
|
|
69
66
|
setParticleEmitRateScale,
|
|
70
|
-
setGlEnable,
|
|
71
|
-
setGlOverlay,
|
|
72
67
|
setGamepadsEnable,
|
|
73
68
|
setGamepadDirectionEmulateStick,
|
|
74
69
|
setInputWASDEmulateDirection,
|
|
@@ -77,18 +72,15 @@ export {
|
|
|
77
72
|
setTouchGamepadSize,
|
|
78
73
|
setTouchGamepadAlpha,
|
|
79
74
|
setVibrateEnable,
|
|
80
|
-
setSoundVolume,
|
|
81
75
|
setSoundEnable,
|
|
76
|
+
setSoundVolume,
|
|
82
77
|
setSoundDefaultRange,
|
|
83
78
|
setSoundDefaultTaper,
|
|
84
79
|
setMedalDisplayTime,
|
|
85
80
|
setMedalDisplaySlideTime,
|
|
86
|
-
|
|
87
|
-
setMedalDisplayHeight,
|
|
81
|
+
setMedalDisplaySize,
|
|
88
82
|
setMedalDisplayIconSize,
|
|
89
83
|
setMedalsPreventUnlock,
|
|
90
|
-
setShowWatermark,
|
|
91
|
-
setGodMode,
|
|
92
84
|
|
|
93
85
|
// Settings
|
|
94
86
|
canvasMaxSize,
|
|
@@ -119,14 +111,13 @@ export {
|
|
|
119
111
|
touchGamepadSize,
|
|
120
112
|
touchGamepadAlpha,
|
|
121
113
|
vibrateEnable,
|
|
122
|
-
soundVolume,
|
|
123
114
|
soundEnable,
|
|
115
|
+
soundVolume,
|
|
124
116
|
soundDefaultRange,
|
|
125
117
|
soundDefaultTaper,
|
|
126
118
|
medalDisplayTime,
|
|
127
119
|
medalDisplaySlideTime,
|
|
128
|
-
|
|
129
|
-
medalDisplayHeight,
|
|
120
|
+
medalDisplaySize,
|
|
130
121
|
medalDisplayIconSize,
|
|
131
122
|
|
|
132
123
|
// Globals
|
|
@@ -180,6 +171,7 @@ export {
|
|
|
180
171
|
randVector,
|
|
181
172
|
randColor,
|
|
182
173
|
randSeed,
|
|
174
|
+
setRandSeed,
|
|
183
175
|
randSeeded,
|
|
184
176
|
|
|
185
177
|
// Utility Classes
|
|
@@ -244,15 +236,12 @@ export {
|
|
|
244
236
|
// onmousemove,
|
|
245
237
|
// onwheel,
|
|
246
238
|
// oncontextmenu,
|
|
247
|
-
mouseToScreen,
|
|
248
239
|
//stickData,
|
|
240
|
+
mouseToScreen,
|
|
249
241
|
gamepadsUpdate,
|
|
250
242
|
vibrate,
|
|
251
243
|
vibrateStop,
|
|
252
244
|
isTouchDevice,
|
|
253
|
-
//touchGamepadTimer,
|
|
254
|
-
touchGamepadCreate,
|
|
255
|
-
touchGamepadRender,
|
|
256
245
|
|
|
257
246
|
// Audio
|
|
258
247
|
Sound,
|
|
@@ -320,11 +309,9 @@ export {
|
|
|
320
309
|
time,
|
|
321
310
|
timeReal,
|
|
322
311
|
paused,
|
|
323
|
-
|
|
324
|
-
drawCount,
|
|
312
|
+
setPaused,
|
|
325
313
|
engineInit,
|
|
326
|
-
|
|
327
|
-
//engineObjectsUpdate,
|
|
314
|
+
engineObjectsUpdate,
|
|
328
315
|
engineObjectsDestroy,
|
|
329
316
|
engineObjectsCallback,
|
|
330
317
|
};
|
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
|
|