littlejsengine 1.4.6 → 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 +80 -0
- package/build.bat +7 -3
- package/engine/engine.all.js +276 -295
- package/engine/engine.all.min.js +1 -1
- package/engine/engine.all.module.js +286 -318
- package/engine/engine.all.module.min.js +1 -0
- package/engine/engine.all.release.js +276 -295
- package/engine/engine.js +28 -30
- package/engine/engineAudio.js +8 -15
- package/engine/engineBuild.bat +10 -3
- package/engine/engineDraw.js +14 -18
- package/engine/engineExport.js +10 -23
- package/engine/engineFont.png +0 -0
- package/engine/engineInput.js +86 -69
- package/engine/engineMedals.js +25 -32
- package/engine/engineObject.js +2 -2
- package/engine/engineParticles.js +7 -6
- package/engine/engineSettings.js +28 -28
- package/engine/engineTileLayer.js +15 -16
- package/engine/engineUtilities.js +26 -13
- package/engine/engineWebGL.js +38 -67
- package/engine/index.d.ts +52 -43
- 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 -4457
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,18 +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;
|
|
58
|
-
|
|
59
|
-
// css text used for elements created by engine
|
|
60
|
-
const styleBody = 'margin:0;overflow:hidden;background:#000';
|
|
61
|
-
const styleCanvas = 'position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)';
|
|
54
|
+
/** Set if game is paused
|
|
55
|
+
* @param {Boolean} paused
|
|
56
|
+
*/
|
|
57
|
+
function setPaused(_paused) { paused = _paused; }
|
|
62
58
|
|
|
63
59
|
///////////////////////////////////////////////////////////////////////////////
|
|
64
60
|
|
|
@@ -80,10 +76,13 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
80
76
|
debug && (tileImage.onload=()=>ASSERT(1)); // tile sheet can not reloaded
|
|
81
77
|
|
|
82
78
|
// setup html
|
|
79
|
+
const styleBody = 'margin:0;overflow:hidden;background:#000' + // fill the window
|
|
80
|
+
';touch-action:none' + // prevent mobile pinch to resize
|
|
81
|
+
';user-select:none' + // prevent mobile hold to select
|
|
82
|
+
';-webkit-user-select:none'; // compatibility for ios
|
|
83
83
|
document.body.style = styleBody;
|
|
84
84
|
document.body.appendChild(mainCanvas = document.createElement('canvas'));
|
|
85
85
|
mainContext = mainCanvas.getContext('2d');
|
|
86
|
-
mainCanvas.style = styleCanvas;
|
|
87
86
|
|
|
88
87
|
// init stuff and start engine
|
|
89
88
|
debugInit();
|
|
@@ -92,21 +91,27 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
92
91
|
// create overlay canvas for hud to appear above gl canvas
|
|
93
92
|
document.body.appendChild(overlayCanvas = document.createElement('canvas'));
|
|
94
93
|
overlayContext = overlayCanvas.getContext('2d');
|
|
95
|
-
|
|
94
|
+
|
|
95
|
+
// set canvas style to fill the window
|
|
96
|
+
const styleCanvas = 'position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)';
|
|
97
|
+
(glCanvas||mainCanvas).style = mainCanvas.style = overlayCanvas.style = styleCanvas;
|
|
96
98
|
|
|
97
99
|
gameInit();
|
|
98
100
|
touchGamepadCreate();
|
|
99
101
|
engineUpdate();
|
|
100
102
|
};
|
|
101
103
|
|
|
104
|
+
// frame time tracking
|
|
105
|
+
let frameTimeLastMS = 0, frameTimeBufferMS, averageFPS;
|
|
106
|
+
|
|
102
107
|
// main update loop
|
|
103
|
-
|
|
108
|
+
function engineUpdate(frameTimeMS=0)
|
|
104
109
|
{
|
|
105
110
|
// update time keeping
|
|
106
111
|
let frameTimeDeltaMS = frameTimeMS - frameTimeLastMS;
|
|
107
112
|
frameTimeLastMS = frameTimeMS;
|
|
108
113
|
if (debug || showWatermark)
|
|
109
|
-
averageFPS = lerp(.05, averageFPS
|
|
114
|
+
averageFPS = lerp(.05, averageFPS, 1e3/(frameTimeDeltaMS||1));
|
|
110
115
|
const debugSpeedUp = debug && keyIsDown(107); // +
|
|
111
116
|
const debugSpeedDown = debug && keyIsDown(109); // -
|
|
112
117
|
if (debug)
|
|
@@ -118,24 +123,19 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
118
123
|
|
|
119
124
|
if (canvasFixedSize.x)
|
|
120
125
|
{
|
|
121
|
-
// clear set fixed size
|
|
126
|
+
// clear canvas and set fixed size
|
|
122
127
|
overlayCanvas.width = mainCanvas.width = canvasFixedSize.x;
|
|
123
128
|
overlayCanvas.height = mainCanvas.height = canvasFixedSize.y;
|
|
124
129
|
|
|
125
130
|
// fit to window by adding space on top or bottom if necessary
|
|
126
131
|
const aspect = innerWidth / innerHeight;
|
|
127
132
|
const fixedAspect = mainCanvas.width / mainCanvas.height;
|
|
128
|
-
mainCanvas.style.width
|
|
129
|
-
mainCanvas.style.height = overlayCanvas.style.height = aspect < fixedAspect ? '' : '100%';
|
|
130
|
-
if (glCanvas)
|
|
131
|
-
{
|
|
132
|
-
glCanvas.style.width = mainCanvas.style.width;
|
|
133
|
-
glCanvas.style.height = mainCanvas.style.height;
|
|
134
|
-
}
|
|
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%';
|
|
135
135
|
}
|
|
136
136
|
else
|
|
137
137
|
{
|
|
138
|
-
|
|
138
|
+
// clear canvas and set size to same as window
|
|
139
139
|
overlayCanvas.width = mainCanvas.width = min(innerWidth, canvasMaxSize.x);
|
|
140
140
|
overlayCanvas.height = mainCanvas.height = min(innerHeight, canvasMaxSize.y);
|
|
141
141
|
}
|
|
@@ -202,7 +202,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
202
202
|
overlayContext.fillStyle = '#000';
|
|
203
203
|
const text = engineName + ' ' + 'v' + engineVersion + ' / '
|
|
204
204
|
+ drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
|
|
205
|
-
+
|
|
205
|
+
+ (glEnable ? ' GL' : ' 2D') ;
|
|
206
206
|
overlayContext.fillText(text, mainCanvas.width-3, 3);
|
|
207
207
|
overlayContext.fillStyle = '#fff';
|
|
208
208
|
overlayContext.fillText(text, mainCanvas.width-2, 2);
|
|
@@ -216,7 +216,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
216
216
|
tileImageSource ? tileImage.src = tileImageSource : tileImage.onload();
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
//
|
|
219
|
+
// Called automatically by engine to setup render system
|
|
220
220
|
function enginePreRender()
|
|
221
221
|
{
|
|
222
222
|
// save canvas size
|
|
@@ -226,12 +226,10 @@ function enginePreRender()
|
|
|
226
226
|
mainContext.imageSmoothingEnabled = !cavasPixelated;
|
|
227
227
|
|
|
228
228
|
// setup gl rendering if enabled
|
|
229
|
-
glEnable && glPreRender(
|
|
229
|
+
glEnable && glPreRender();
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
/** 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 */
|
|
235
233
|
function engineObjectsUpdate()
|
|
236
234
|
{
|
|
237
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,14 +312,9 @@ export {
|
|
|
320
312
|
time,
|
|
321
313
|
timeReal,
|
|
322
314
|
paused,
|
|
323
|
-
|
|
324
|
-
//averageFPS,
|
|
325
|
-
//drawCount,
|
|
326
|
-
//styleBody,
|
|
327
|
-
//styleCanvas,
|
|
315
|
+
setPaused,
|
|
328
316
|
engineInit,
|
|
329
|
-
|
|
330
|
-
//engineObjectsUpdate,
|
|
317
|
+
engineObjectsUpdate,
|
|
331
318
|
engineObjectsDestroy,
|
|
332
319
|
engineObjectsCallback,
|
|
333
320
|
};
|
package/engine/engineFont.png
CHANGED
|
Binary file
|
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
|
|
@@ -253,32 +253,41 @@ const isTouchDevice = window.ontouchstart !== undefined;
|
|
|
253
253
|
// try to enable touch mouse
|
|
254
254
|
if (isTouchDevice)
|
|
255
255
|
{
|
|
256
|
-
//
|
|
257
|
-
let wasTouching,
|
|
258
|
-
|
|
256
|
+
// override mouse events
|
|
257
|
+
let wasTouching, mouseDown = onmousedown, mouseUp = onmouseup;
|
|
258
|
+
onmousedown = onmouseup = ()=> 0;
|
|
259
|
+
|
|
260
|
+
// setup touch input
|
|
261
|
+
ontouchstart = (e)=>
|
|
259
262
|
{
|
|
260
|
-
|
|
263
|
+
// fix mobile audio, force it to play a sound on first touch
|
|
264
|
+
zzfx(0);
|
|
261
265
|
|
|
262
|
-
//
|
|
263
|
-
|
|
264
|
-
if (touching)
|
|
266
|
+
// handle all touch events the same way
|
|
267
|
+
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
265
268
|
{
|
|
266
|
-
|
|
267
|
-
hadTouch || zzfx(0, hadTouch=1);
|
|
269
|
+
e.button = 0; // all touches are left click
|
|
268
270
|
|
|
269
|
-
//
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
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);
|
|
282
|
+
|
|
283
|
+
// set was touching
|
|
284
|
+
wasTouching = touching;
|
|
276
285
|
|
|
277
|
-
|
|
278
|
-
|
|
286
|
+
// must return true so the document will get focus
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
279
289
|
|
|
280
|
-
|
|
281
|
-
return true;
|
|
290
|
+
return ontouchstart(e);
|
|
282
291
|
}
|
|
283
292
|
}
|
|
284
293
|
|
|
@@ -286,7 +295,7 @@ if (isTouchDevice)
|
|
|
286
295
|
// touch gamepad, virtual on screen gamepad emulator for touch devices
|
|
287
296
|
|
|
288
297
|
// touch input internal variables
|
|
289
|
-
let touchGamepadTimer = new Timer, touchGamepadButtons
|
|
298
|
+
let touchGamepadTimer = new Timer, touchGamepadButtons, touchGamepadStick;
|
|
290
299
|
|
|
291
300
|
// create the touch gamepad, called automatically by the engine
|
|
292
301
|
function touchGamepadCreate()
|
|
@@ -294,65 +303,73 @@ function touchGamepadCreate()
|
|
|
294
303
|
if (!touchGamepadEnable || !isTouchDevice)
|
|
295
304
|
return;
|
|
296
305
|
|
|
297
|
-
|
|
306
|
+
// touch input internal variables
|
|
307
|
+
touchGamepadButtons = [];
|
|
308
|
+
touchGamepadStick = vec2();
|
|
309
|
+
|
|
310
|
+
// setup touch input
|
|
311
|
+
ontouchstart = (e)=>
|
|
298
312
|
{
|
|
299
|
-
|
|
300
|
-
|
|
313
|
+
// fix mobile audio, force it to play a sound on first touch
|
|
314
|
+
zzfx(0);
|
|
301
315
|
|
|
302
|
-
|
|
303
|
-
touchGamepadStick = vec2();
|
|
304
|
-
touchGamepadButtons = [];
|
|
305
|
-
|
|
306
|
-
const touching = e.touches.length;
|
|
307
|
-
if (touching)
|
|
316
|
+
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
308
317
|
{
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if (paused)
|
|
318
|
+
// clear touch gamepad input
|
|
319
|
+
touchGamepadStick = vec2();
|
|
320
|
+
touchGamepadButtons = [];
|
|
321
|
+
|
|
322
|
+
const touching = e.touches.length;
|
|
323
|
+
if (touching)
|
|
316
324
|
{
|
|
317
|
-
//
|
|
318
|
-
|
|
319
|
-
|
|
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
|
+
}
|
|
320
335
|
}
|
|
321
|
-
}
|
|
322
336
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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);
|
|
327
341
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
{
|
|
331
|
-
const touchPos = mouseToScreen(vec2(touch.clientX, touch.clientY));
|
|
332
|
-
if (touchPos.distance(stickCenter) < touchGamepadSize)
|
|
342
|
+
// check each touch point
|
|
343
|
+
for (const touch of e.touches)
|
|
333
344
|
{
|
|
334
|
-
|
|
335
|
-
if (
|
|
336
|
-
touchGamepadStick = touchPos.subtract(stickCenter).scale(2/touchGamepadSize).clampLength();
|
|
337
|
-
else
|
|
345
|
+
const touchPos = mouseToScreen(vec2(touch.clientX, touch.clientY));
|
|
346
|
+
if (touchPos.distance(stickCenter) < touchGamepadSize)
|
|
338
347
|
{
|
|
339
|
-
//
|
|
340
|
-
|
|
341
|
-
|
|
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;
|
|
342
368
|
}
|
|
343
|
-
}
|
|
344
|
-
else if (touchPos.distance(buttonCenter) < touchGamepadSize)
|
|
345
|
-
{
|
|
346
|
-
// virtual face buttons
|
|
347
|
-
const button = touchPos.subtract(buttonCenter).direction();
|
|
348
|
-
touchGamepadButtons[button] = 1;
|
|
349
|
-
}
|
|
350
|
-
else if (touchPos.distance(startCenter) < touchGamepadSize)
|
|
351
|
-
{
|
|
352
|
-
// virtual start button in center
|
|
353
|
-
touchGamepadButtons[9] = 1;
|
|
354
369
|
}
|
|
355
370
|
}
|
|
371
|
+
|
|
372
|
+
return ontouchstart(e);
|
|
356
373
|
}
|
|
357
374
|
}
|
|
358
375
|
|