littlejsengine 1.7.13 → 1.7.21

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.
@@ -1,12 +1,14 @@
1
1
  // LittleJS - MIT License - Copyright 2021 Frank Force
2
2
 
3
+ 'use strict';
4
+
3
5
  /**
4
6
  * LittleJS - Release Mode
5
7
  * - This file is used for release builds in place of engineDebug.js
6
8
  * - Debug functionality is disabled to reduce size and increase performance
7
9
  */
8
10
 
9
- 'use strict';
11
+
10
12
 
11
13
  let showWatermark = 0;
12
14
  let debugKeyCode = 0;
@@ -41,7 +43,7 @@ function debugSaveCanvas (){}
41
43
  * @namespace Utilities
42
44
  */
43
45
 
44
- 'use strict';
46
+
45
47
 
46
48
  /** A shortcut to get Math.PI
47
49
  * @type {Number}
@@ -696,7 +698,7 @@ class Timer
696
698
  * @namespace Settings
697
699
  */
698
700
 
699
- 'use strict';
701
+
700
702
 
701
703
  ///////////////////////////////////////////////////////////////////////////////
702
704
  // Camera settings
@@ -944,7 +946,7 @@ let medalsPreventUnlock;
944
946
  * LittleJS Object System
945
947
  */
946
948
 
947
- 'use strict';
949
+
948
950
 
949
951
  /**
950
952
  * LittleJS Object Base Object Class
@@ -1340,7 +1342,7 @@ class EngineObject
1340
1342
  * @namespace Draw
1341
1343
  */
1342
1344
 
1343
- 'use strict';
1345
+
1344
1346
 
1345
1347
  /** The primary 2D canvas visible to the user
1346
1348
  * @type {HTMLCanvasElement}
@@ -1531,12 +1533,12 @@ function drawCanvas2D(pos, size, angle, mirror, drawFunction, context = mainCont
1531
1533
  {
1532
1534
  if (!screenSpace)
1533
1535
  {
1534
- // create canvas transform from world space to screen space
1536
+ // transform from world space to screen space
1535
1537
  pos = worldToScreen(pos);
1536
1538
  size = size.scale(cameraScale);
1537
1539
  }
1538
1540
  context.save();
1539
- context.translate(pos.x+.5|0, pos.y+.5|0);
1541
+ context.translate(pos.x+.5, pos.y+.5);
1540
1542
  context.rotate(angle);
1541
1543
  context.scale(mirror ? -size.x : size.x, size.y);
1542
1544
  drawFunction(context);
@@ -1721,7 +1723,7 @@ function toggleFullscreen()
1721
1723
  * @namespace Input
1722
1724
  */
1723
1725
 
1724
- 'use strict';
1726
+
1725
1727
 
1726
1728
  /** Returns true if device key is down
1727
1729
  * @param {Number} key
@@ -1905,18 +1907,26 @@ function mouseToScreen(mousePos)
1905
1907
  const stickData = [];
1906
1908
  function gamepadsUpdate()
1907
1909
  {
1908
- if (touchGamepadEnable && touchGamepadTimer.isSet())
1910
+ // update touch gamepad if enabled
1911
+ if (touchGamepadEnable && isTouchDevice)
1909
1912
  {
1910
- // read virtual analog stick
1911
- const sticks = stickData[0] || (stickData[0] = []);
1912
- sticks[0] = vec2(touchGamepadStick.x, -touchGamepadStick.y); // flip vertical
1913
+ // create the touch gamepad if it doesn't exist
1914
+ if (!touchGamepadButtons)
1915
+ createTouchGamepad();
1913
1916
 
1914
- // read virtual gamepad buttons
1915
- const data = inputData[1] || (inputData[1] = []);
1916
- for (let i=10; i--;)
1917
+ if (touchGamepadTimer.isSet())
1917
1918
  {
1918
- const j = i == 3 ? 2 : i == 2 ? 3 : i; // fix button locations
1919
- data[j] = touchGamepadButtons[i] ? 1 + 2*!gamepadIsDown(j,0) : 4*gamepadIsDown(j,0);
1919
+ // read virtual analog stick
1920
+ const sticks = stickData[0] || (stickData[0] = []);
1921
+ sticks[0] = vec2(touchGamepadStick.x, -touchGamepadStick.y); // flip vertical
1922
+
1923
+ // read virtual gamepad buttons
1924
+ const data = inputData[1] || (inputData[1] = []);
1925
+ for (let i=10; i--;)
1926
+ {
1927
+ const j = i == 3 ? 2 : i == 2 ? 3 : i; // fix button locations
1928
+ data[j] = touchGamepadButtons[i] ? 1 + 2*!gamepadIsDown(j,0) : 4*gamepadIsDown(j,0);
1929
+ }
1920
1930
  }
1921
1931
  }
1922
1932
 
@@ -2013,6 +2023,10 @@ if (isTouchDevice)
2013
2023
  // set was touching
2014
2024
  wasTouching = touching;
2015
2025
 
2026
+ // prevent default handling like copy and magnifier lens
2027
+ if (document.hasFocus()) // allow document to get focus
2028
+ e.preventDefault();
2029
+
2016
2030
  // must return true so the document will get focus
2017
2031
  return true;
2018
2032
  }
@@ -2025,7 +2039,7 @@ if (isTouchDevice)
2025
2039
  let touchGamepadTimer = new Timer, touchGamepadButtons, touchGamepadStick;
2026
2040
 
2027
2041
  // create the touch gamepad, called automatically by the engine
2028
- if (touchGamepadEnable)
2042
+ function createTouchGamepad()
2029
2043
  {
2030
2044
  // touch input internal variables
2031
2045
  touchGamepadButtons = [];
@@ -2159,7 +2173,7 @@ function touchGamepadRender()
2159
2173
  * @namespace Audio
2160
2174
  */
2161
2175
 
2162
- 'use strict';
2176
+
2163
2177
 
2164
2178
  /**
2165
2179
  * Sound Object - Stores a zzfx sound for later use and can be played positionally
@@ -2195,8 +2209,9 @@ class Sound
2195
2209
  if (zzfxSound)
2196
2210
  {
2197
2211
  // generate zzfx sound now for fast playback
2198
- this.randomness = zzfxSound[1] || (zzfxSound[1] = 0);
2199
- this.cachedSamples = zzfxSound && zzfxG(...zzfxSound);
2212
+ this.randomness = zzfxSound[1] || (zzfxSound[1] = 0);
2213
+ this.sampleChannels = [zzfxG(...zzfxSound)];
2214
+ this.sampleRate = zzfxR;
2200
2215
  }
2201
2216
  }
2202
2217
 
@@ -2205,11 +2220,12 @@ class Sound
2205
2220
  * @param {Number} [volume=1] - How much to scale volume by (in addition to range fade)
2206
2221
  * @param {Number} [pitch=1] - How much to scale pitch by (also adjusted by this.randomness)
2207
2222
  * @param {Number} [randomnessScale=1] - How much to scale randomness
2208
- * @return {AudioBufferSourceNode} - The audio, can be used to stop sound later
2223
+ * @param {Boolean} [loop=0] - Should the sound loop
2224
+ * @return {AudioBufferSourceNode} - The audio source node
2209
2225
  */
2210
- play(pos, volume=1, pitch=1, randomnessScale=1)
2226
+ play(pos, volume=1, pitch=1, randomnessScale=1, loop=0)
2211
2227
  {
2212
- if (!soundEnable || !this.cachedSamples) return;
2228
+ if (!soundEnable || !this.sampleChannels) return;
2213
2229
 
2214
2230
  let pan;
2215
2231
  if (pos)
@@ -2232,43 +2248,80 @@ class Sound
2232
2248
 
2233
2249
  // play the sound
2234
2250
  const playbackRate = pitch + pitch * this.randomness*randomnessScale*rand(-1,1);
2235
- return playSamples([this.cachedSamples], volume, playbackRate, pan);
2251
+ return this.source = playSamples(this.sampleChannels, volume, playbackRate, pan, loop, this.sampleRate);
2252
+ }
2253
+
2254
+ /** Stop the last instance of this sound that was played */
2255
+ stop()
2256
+ {
2257
+ if (this.source)
2258
+ this.source.stop();
2259
+ this.source = 0;
2236
2260
  }
2237
2261
 
2238
2262
  /** Play the sound as a note with a semitone offset
2239
2263
  * @param {Number} semitoneOffset - How many semitones to offset pitch
2240
2264
  * @param {Vector2} [pos] - World space position to play the sound, sound is not attenuated if null
2241
2265
  * @param {Number} [volume=1] - How much to scale volume by (in addition to range fade)
2242
- * @return {AudioBufferSourceNode} - The audio, can be used to stop sound later
2266
+ * @return {AudioBufferSourceNode} - The audio source node
2243
2267
  */
2244
2268
  playNote(semitoneOffset, pos, volume)
2245
2269
  { return this.play(pos, volume, 2**(semitoneOffset/12), 0); }
2270
+
2271
+ /** Get how long this sound is in seconds
2272
+ * @return {Number} - How long the sound is in seconds (undefined if loading)
2273
+ */
2274
+ getDuration()
2275
+ { return this.sampleChannels && this.sampleChannels[0].length / this.sampleRate; }
2276
+
2277
+ /** Check if the last instance of this sound is playing
2278
+ * @return {Boolean} - True if the sound is playing
2279
+ */
2280
+ isPlaying() { return this.source && !this.source.ended; }
2281
+
2282
+ /** Check if sound is loading, for sounds fetched from a url
2283
+ * @return {Boolean} - True if sound is loading and not ready to play
2284
+ */
2285
+ isLoading() { return !this.sampleChannels; }
2246
2286
  }
2247
2287
 
2248
2288
  /**
2249
2289
  * Sound Wave Object - Stores a wave sound for later use and can be played positionally
2290
+ * - this can be used to play wave, mp3, and ogg files
2291
+ * @example
2292
+ * // create a sound
2293
+ * const sound_example = new SoundWave('sound.mp3');
2294
+ *
2295
+ * // play the sound
2296
+ * sound_example.play();
2250
2297
  */
2251
2298
  class SoundWave extends Sound
2252
2299
  {
2253
2300
  /** Create a sound object and cache the wave file for later use
2254
- * @param {String} waveFilename - Filename of wave file to load
2255
- * @param {Number} [randomness=.05] - How much to randomize frequency each time sound plays
2301
+ * @param {String} filename - Filename of audio file to load
2302
+ * @param {Number} [randomness=0] - How much to randomize frequency each time sound plays
2256
2303
  * @param {Number} [range=soundDefaultRange] - World space max range of sound, will not play if camera is farther away
2257
2304
  * @param {Number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering off
2258
2305
  */
2259
- constructor(waveFilename, randomness=.05, range, taper)
2306
+ constructor(filename, randomness=0, range, taper)
2260
2307
  {
2261
2308
  super(0, range, taper);
2262
2309
  this.randomness = randomness;
2263
2310
 
2264
2311
  if (!soundEnable) return;
2265
- if (!soundWaveDecoderContext)
2312
+ if (!soundDecoderContext)
2266
2313
  soundDecoderContext = new AudioContext;
2267
2314
 
2268
- fetch(waveFilename)
2315
+ fetch(filename)
2269
2316
  .then(response => response.arrayBuffer())
2270
- .then(arrayBuffer => soundWaveDecoderContext.decodeAudioData(arrayBuffer))
2271
- .then(audioBuffer => this.cachedSamples = audioBuffer.getChannelData(0));
2317
+ .then(arrayBuffer => soundDecoderContext.decodeAudioData(arrayBuffer))
2318
+ .then(audioBuffer =>
2319
+ {
2320
+ this.sampleChannels = [];
2321
+ for (let i = audioBuffer.numberOfChannels; i--;)
2322
+ this.sampleChannels[i] = audioBuffer.getChannelData(i);
2323
+ this.sampleRate = audioBuffer.sampleRate;
2324
+ });
2272
2325
  }
2273
2326
  }
2274
2327
  let soundDecoderContext; // audio context used only to decode audio files
@@ -2303,48 +2356,34 @@ let soundDecoderContext; // audio context used only to decode audio files
2303
2356
  * // play the music
2304
2357
  * music_example.play();
2305
2358
  */
2306
- class Music
2359
+ class Music extends Sound
2307
2360
  {
2308
2361
  /** Create a music object and cache the zzfx music samples for later use
2309
2362
  * @param {Array} zzfxMusic - Array of zzfx music parameters
2310
2363
  */
2311
2364
  constructor(zzfxMusic)
2312
2365
  {
2313
- if (!soundEnable) return;
2366
+ super();
2314
2367
 
2315
- this.cachedSamples = zzfxM(...zzfxMusic);
2368
+ if (!soundEnable) return;
2369
+ this.randomness = 0;
2370
+ this.sampleChannels = zzfxM(...zzfxMusic);
2371
+ this.sampleRate = zzfxR;
2316
2372
  }
2317
2373
 
2318
2374
  /** Play the music
2319
2375
  * @param {Number} [volume=1] - How much to scale volume by
2320
- * @param {Boolean} [loop=1] - True if the music should loop when it reaches the end
2321
- * @return {AudioBufferSourceNode} - The audio node, can be used to stop sound later
2376
+ * @param {Boolean} [loop=1] - True if the music should loop
2377
+ * @return {AudioBufferSourceNode} - The audio source node
2322
2378
  */
2323
2379
  play(volume, loop = 1)
2324
- {
2325
- if (!soundEnable) return;
2326
-
2327
- return this.source = playSamples(this.cachedSamples, volume, 1, 0, loop);
2328
- }
2329
-
2330
- /** Stop the music */
2331
- stop()
2332
- {
2333
- if (this.source)
2334
- this.source.stop();
2335
- this.source = 0;
2336
- }
2337
-
2338
- /** Check if music is playing
2339
- * @return {Boolean}
2340
- */
2341
- isPlaying() { return this.source; }
2380
+ { return super.play(0, volume, 1, 1, loop); }
2342
2381
  }
2343
2382
 
2344
- /** Play an mp3 or wav audio from a local file or url
2383
+ /** Play an mp3, ogg, or wav audio from a local file or url
2345
2384
  * @param {String} url - Location of sound file to play
2346
2385
  * @param {Number} [volume=1] - How much to scale volume by
2347
- * @param {Boolean} [loop=1] - True if the music should loop when it reaches the end
2386
+ * @param {Boolean} [loop=1] - True if the music should loop
2348
2387
  * @return {HTMLAudioElement} - The audio element for this sound
2349
2388
  * @memberof Audio */
2350
2389
  function playAudioFile(url, volume=1, loop=1)
@@ -2408,9 +2447,10 @@ let audioContext;
2408
2447
  * @param {Number} [rate=1] - The playback rate to use
2409
2448
  * @param {Number} [pan=0] - How much to apply stereo panning
2410
2449
  * @param {Boolean} [loop=0] - True if the sound should loop when it reaches the end
2450
+ * @param {Number} [sampleRate=44100] - Sample rate for the sound
2411
2451
  * @return {AudioBufferSourceNode} - The audio node of the sound played
2412
2452
  * @memberof Audio */
2413
- function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0)
2453
+ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0, sampleRate=zzfxR)
2414
2454
  {
2415
2455
  if (!soundEnable) return;
2416
2456
 
@@ -2427,7 +2467,7 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0)
2427
2467
  }
2428
2468
 
2429
2469
  // create buffer and source
2430
- const buffer = audioContext.createBuffer(sampleChannels.length, sampleChannels[0].length, zzfxR),
2470
+ const buffer = audioContext.createBuffer(sampleChannels.length, sampleChannels[0].length, sampleRate),
2431
2471
  source = audioContext.createBufferSource();
2432
2472
 
2433
2473
  // copy samples to buffer and setup source
@@ -2686,7 +2726,7 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
2686
2726
  * @namespace TileCollision
2687
2727
  */
2688
2728
 
2689
- 'use strict';
2729
+
2690
2730
 
2691
2731
  /** The tile collision layer array, use setTileCollisionData and getTileCollisionData to access
2692
2732
  * @type {Array}
@@ -3039,7 +3079,7 @@ constructor(pos, size=tileCollisionSize, tileSize=tileSizeDefault, scale=vec2(1)
3039
3079
  * LittleJS Particle System
3040
3080
  */
3041
3081
 
3042
- 'use strict';
3082
+
3043
3083
 
3044
3084
  /**
3045
3085
  * Particle Emitter - Spawns particles with the given settings
@@ -3349,7 +3389,7 @@ class Particle extends EngineObject
3349
3389
  * @namespace Medals
3350
3390
  */
3351
3391
 
3352
- 'use strict';
3392
+
3353
3393
 
3354
3394
  /** List of all medals
3355
3395
  * @type {Array}
@@ -3673,7 +3713,7 @@ class Newgrounds
3673
3713
  * @namespace WebGL
3674
3714
  */
3675
3715
 
3676
- 'use strict';
3716
+
3677
3717
 
3678
3718
  /** The WebGL canvas which appears above the main canvas and below the overlay canvas
3679
3719
  * @type {HTMLCanvasElement}
@@ -3695,7 +3735,7 @@ let glActiveTexture, glShader, glArrayBuffer, glPositionData, glColorData, glBat
3695
3735
 
3696
3736
  ///////////////////////////////////////////////////////////////////////////////
3697
3737
 
3698
- // Init WebGL, called automatically by the engine
3738
+ // Initalize WebGL, called automatically by the engine
3699
3739
  function glInit()
3700
3740
  {
3701
3741
  // create the canvas and tile texture
@@ -3734,6 +3774,48 @@ function glInit()
3734
3774
  glBatchCount = 0;
3735
3775
  }
3736
3776
 
3777
+ // Setup render each frame, called automatically by engine
3778
+ function glPreRender()
3779
+ {
3780
+ // clear and set to same size as main canvas
3781
+ glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
3782
+ glContext.clear(gl_COLOR_BUFFER_BIT);
3783
+
3784
+ // set up the shader
3785
+ glContext.useProgram(glShader);
3786
+ glContext.activeTexture(gl_TEXTURE0);
3787
+ glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = glTileTexture);
3788
+ glContext.bindBuffer(gl_ARRAY_BUFFER, glArrayBuffer);
3789
+ glContext.bufferData(gl_ARRAY_BUFFER, gl_VERTEX_BUFFER_SIZE, gl_DYNAMIC_DRAW);
3790
+ glSetBlendMode();
3791
+
3792
+ // set vertex attributes
3793
+ let offset = 0;
3794
+ const initVertexAttribArray = (name, type, typeSize, size, normalize=0)=>
3795
+ {
3796
+ const location = glContext.getAttribLocation(glShader, name);
3797
+ glContext.enableVertexAttribArray(location);
3798
+ glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
3799
+ offset += size*typeSize;
3800
+ }
3801
+ initVertexAttribArray('p', gl_FLOAT, 4, 2); // position
3802
+ initVertexAttribArray('t', gl_FLOAT, 4, 2); // texture coords
3803
+ initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
3804
+ initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
3805
+
3806
+ // build the transform matrix
3807
+ const sx = 2 * cameraScale / mainCanvas.width;
3808
+ const sy = 2 * cameraScale / mainCanvas.height;
3809
+ glContext.uniformMatrix4fv(glContext.getUniformLocation(glShader, 'm'), 0,
3810
+ new Float32Array([
3811
+ sx, 0, 0, 0,
3812
+ 0, sy, 0, 0,
3813
+ 1, 1, -1, 1,
3814
+ -1-sx*cameraPos.x, -1-sy*cameraPos.y, 0, 0
3815
+ ])
3816
+ );
3817
+ }
3818
+
3737
3819
  /** Set the WebGl blend mode, normally you should call setBlendMode instead
3738
3820
  * @param {Boolean} [additive=0]
3739
3821
  * @memberof WebGL */
@@ -3813,48 +3895,6 @@ function glCreateTexture(image)
3813
3895
  return texture;
3814
3896
  }
3815
3897
 
3816
- // called automatically by engine before render
3817
- function glPreRender()
3818
- {
3819
- // clear and set to same size as main canvas
3820
- glContext.viewport(0, 0, glCanvas.width = mainCanvas.width, glCanvas.height = mainCanvas.height);
3821
- glContext.clear(gl_COLOR_BUFFER_BIT);
3822
-
3823
- // set up the shader
3824
- glContext.useProgram(glShader);
3825
- glContext.activeTexture(gl_TEXTURE0);
3826
- glContext.bindTexture(gl_TEXTURE_2D, glActiveTexture = glTileTexture);
3827
- glContext.bindBuffer(gl_ARRAY_BUFFER, glArrayBuffer);
3828
- glContext.bufferData(gl_ARRAY_BUFFER, gl_VERTEX_BUFFER_SIZE, gl_DYNAMIC_DRAW);
3829
- glSetBlendMode();
3830
-
3831
- // set vertex attributes
3832
- let offset = 0;
3833
- const initVertexAttribArray = (name, type, typeSize, size, normalize=0)=>
3834
- {
3835
- const location = glContext.getAttribLocation(glShader, name);
3836
- glContext.enableVertexAttribArray(location);
3837
- glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
3838
- offset += size*typeSize;
3839
- }
3840
- initVertexAttribArray('p', gl_FLOAT, 4, 2); // position
3841
- initVertexAttribArray('t', gl_FLOAT, 4, 2); // texture coords
3842
- initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
3843
- initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
3844
-
3845
- // build the transform matrix
3846
- const sx = 2 * cameraScale / mainCanvas.width;
3847
- const sy = 2 * cameraScale / mainCanvas.height;
3848
- glContext.uniformMatrix4fv(glContext.getUniformLocation(glShader, 'm'), 0,
3849
- new Float32Array([
3850
- sx, 0, 0, 0,
3851
- 0, sy, 0, 0,
3852
- 1, 1, -1, 1,
3853
- -1-sx*cameraPos.x, -1-sy*cameraPos.y, 0, 0
3854
- ])
3855
- );
3856
- }
3857
-
3858
3898
  /** Draw all sprites and clear out the buffer, called automatically by the system whenever necessary
3859
3899
  * @memberof WebGL */
3860
3900
  function glFlush()
@@ -4112,7 +4152,7 @@ gl_VERTEX_BUFFER_SIZE = gl_MAX_BATCH * gl_VERTEX_BYTE_STRIDE;
4112
4152
  * @namespace Engine
4113
4153
  */
4114
4154
 
4115
- 'use strict';
4155
+
4116
4156
 
4117
4157
  /** Name of engine
4118
4158
  * @type {String}
@@ -4124,7 +4164,7 @@ const engineName = 'LittleJS';
4124
4164
  * @type {String}
4125
4165
  * @default
4126
4166
  * @memberof Engine */
4127
- const engineVersion = '1.7.13';
4167
+ const engineVersion = '1.7.21';
4128
4168
 
4129
4169
  /** Frames per second to update objects
4130
4170
  * @type {Number}
@@ -4194,11 +4234,13 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
4194
4234
  debug && (tileImage.onload=()=>ASSERT(1)); // tile sheet can not reloaded
4195
4235
 
4196
4236
  // setup html
4197
- const styleBody = 'margin:0;overflow:hidden;' + // fill the window
4198
- 'background:#000;' + // set background color
4199
- 'touch-action:none;' + // prevent mobile pinch to resize
4200
- 'user-select:none;' + // prevent mobile hold to select
4201
- '-webkit-user-select:none'; // compatibility for ios
4237
+ const styleBody =
4238
+ 'margin:0;overflow:hidden;' + // fill the window
4239
+ 'background:#000;' + // set background color
4240
+ 'touch-action:none;' + // prevent mobile pinch to resize
4241
+ 'user-select:none;' + // prevent mobile hold to select
4242
+ '-webkit-user-select:none;' + // compatibility for ios
4243
+ '-webkit-touch-callout:none'; // compatibility for ios
4202
4244
  document.body.style = styleBody;
4203
4245
  document.body.appendChild(mainCanvas = document.createElement('canvas'));
4204
4246
  mainContext = mainCanvas.getContext('2d');
@@ -4212,7 +4254,8 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
4212
4254
  overlayContext = overlayCanvas.getContext('2d');
4213
4255
 
4214
4256
  // set canvas style
4215
- const styleCanvas = 'position:absolute;' +
4257
+ const styleCanvas =
4258
+ 'position:absolute;' + // position canvas
4216
4259
  'top:50%;left:50%;transform:translate(-50%,-50%);' + // center the canvas
4217
4260
  (canvasPixelated?'image-rendering:pixelated':''); // set pixelated rendering
4218
4261
  (glCanvas||mainCanvas).style = mainCanvas.style = overlayCanvas.style = styleCanvas;
@@ -4,6 +4,8 @@
4
4
  * LittleJS Build System
5
5
  */
6
6
 
7
+ 'use strict';
8
+
7
9
  const PROGRAM_NAME = 'game';
8
10
  const BUILD_FOLDER = 'build';
9
11
  const sourceFiles =
@@ -4,6 +4,8 @@
4
4
  * LittleJS Build System
5
5
  */
6
6
 
7
+ 'use strict';
8
+
7
9
  const PROGRAM_NAME = 'game';
8
10
  const BUILD_FOLDER = 'build';
9
11
  const sourceFiles =
Binary file
@@ -4,6 +4,8 @@
4
4
  * LittleJS Build System
5
5
  */
6
6
 
7
+ 'use strict';
8
+
7
9
  const PROGRAM_TITLE = 'Little JS Starter Project';
8
10
  const PROGRAM_NAME = 'game';
9
11
  const BUILD_FOLDER = 'build';
@@ -99,7 +99,7 @@ function gameUpdatePost()
99
99
  function gameRender()
100
100
  {
101
101
  // draw a grey square in the background without using webgl
102
- drawRect(cameraPos, tileCollisionSize.add(vec2(5)), new Color(.2,.2,.2), 0, 0);
102
+ drawRect(cameraPos, tileCollisionSize.add(vec2(5)), new Color(.4,.4,.4), 0, 0);
103
103
  }
104
104
 
105
105
  ///////////////////////////////////////////////////////////////////////////////
@@ -4,6 +4,8 @@
4
4
  * LittleJS Build System
5
5
  */
6
6
 
7
+ 'use strict';
8
+
7
9
  const PROGRAM_NAME = 'game';
8
10
  const BUILD_FOLDER = 'build';
9
11
  const ROOT_FOLDER = 'examples/typescript';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.7.13",
3
+ "version": "1.7.21",
4
4
  "description": "LittleJS - Tiny and Fast HTML5 Game Engine",
5
5
  "main": "build/littlejs.esm.js",
6
6
  "repository": {
package/src/engine.js CHANGED
@@ -30,7 +30,7 @@ const engineName = 'LittleJS';
30
30
  * @type {String}
31
31
  * @default
32
32
  * @memberof Engine */
33
- const engineVersion = '1.7.13';
33
+ const engineVersion = '1.7.21';
34
34
 
35
35
  /** Frames per second to update objects
36
36
  * @type {Number}
@@ -100,11 +100,13 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
100
100
  debug && (tileImage.onload=()=>ASSERT(1)); // tile sheet can not reloaded
101
101
 
102
102
  // setup html
103
- const styleBody = 'margin:0;overflow:hidden;' + // fill the window
104
- 'background:#000;' + // set background color
105
- 'touch-action:none;' + // prevent mobile pinch to resize
106
- 'user-select:none;' + // prevent mobile hold to select
107
- '-webkit-user-select:none'; // compatibility for ios
103
+ const styleBody =
104
+ 'margin:0;overflow:hidden;' + // fill the window
105
+ 'background:#000;' + // set background color
106
+ 'touch-action:none;' + // prevent mobile pinch to resize
107
+ 'user-select:none;' + // prevent mobile hold to select
108
+ '-webkit-user-select:none;' + // compatibility for ios
109
+ '-webkit-touch-callout:none'; // compatibility for ios
108
110
  document.body.style = styleBody;
109
111
  document.body.appendChild(mainCanvas = document.createElement('canvas'));
110
112
  mainContext = mainCanvas.getContext('2d');
@@ -118,7 +120,8 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
118
120
  overlayContext = overlayCanvas.getContext('2d');
119
121
 
120
122
  // set canvas style
121
- const styleCanvas = 'position:absolute;' +
123
+ const styleCanvas =
124
+ 'position:absolute;' + // position canvas
122
125
  'top:50%;left:50%;transform:translate(-50%,-50%);' + // center the canvas
123
126
  (canvasPixelated?'image-rendering:pixelated':''); // set pixelated rendering
124
127
  (glCanvas||mainCanvas).style = mainCanvas.style = overlayCanvas.style = styleCanvas;