littlejsengine 1.8.5 → 1.8.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.
Files changed (40) hide show
  1. package/README.md +13 -3
  2. package/build/littlejs.d.ts +22 -15
  3. package/build/littlejs.esm.js +255 -55
  4. package/build/littlejs.esm.min.js +1 -1
  5. package/build/littlejs.js +253 -55
  6. package/build/littlejs.min.js +1 -1
  7. package/build/littlejs.release.js +253 -55
  8. package/examples/breakout/game.js +3 -0
  9. package/examples/breakout/index.html +3 -3
  10. package/examples/breakoutTutorial/index.html +2 -2
  11. package/examples/electron/game.js +3 -0
  12. package/examples/electron/index.html +2 -2
  13. package/examples/js13k/index.html +13 -13
  14. package/examples/logo.png +0 -0
  15. package/examples/module/game.js +3 -0
  16. package/examples/module/index.html +1 -1
  17. package/examples/particles/index.html +1 -1
  18. package/examples/platformer/game.js +3 -0
  19. package/examples/platformer/gamePlayer.js +1 -1
  20. package/examples/platformer/index.html +6 -6
  21. package/examples/puzzle/game.js +3 -0
  22. package/examples/puzzle/index.html +2 -2
  23. package/examples/starter/game.js +3 -0
  24. package/examples/starter/index.html +13 -13
  25. package/examples/stress/index.html +3 -1
  26. package/examples/typescript/game.js +3 -1
  27. package/examples/typescript/game.ts +3 -0
  28. package/examples/typescript/index.html +1 -1
  29. package/package.json +1 -1
  30. package/src/engine.js +186 -9
  31. package/src/engineAudio.js +1 -1
  32. package/src/engineDraw.js +1 -1
  33. package/src/engineExport.js +2 -0
  34. package/src/engineInput.js +24 -14
  35. package/src/engineObject.js +1 -1
  36. package/src/engineParticles.js +1 -1
  37. package/src/engineSettings.js +11 -0
  38. package/src/engineTileLayer.js +8 -8
  39. package/src/engineUtilities.js +5 -6
  40. package/src/engineWebGL.js +15 -14
@@ -442,7 +442,7 @@ class Vector2
442
442
  arrayCheck(arraySize) { return this.x >= 0 && this.y >= 0 && this.x < arraySize.x && this.y < arraySize.y; }
443
443
 
444
444
  /** Returns this vector expressed as a string
445
- * @param {float} digits - precision to display
445
+ * @param {Number} digits - precision to display
446
446
  * @return {String} */
447
447
  toString(digits=3)
448
448
  { if (debug) { return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`; }}
@@ -631,11 +631,10 @@ class Color
631
631
  * @return {Number} */
632
632
  rgbaInt()
633
633
  {
634
- const toByte = (c)=> clamp(c)*255|0;
635
- const r = toByte(this.r);
636
- const g = toByte(this.g)<<8;
637
- const b = toByte(this.b)<<16;
638
- const a = toByte(this.a)<<24;
634
+ const r = clamp(this.r)*255|0;
635
+ const g = clamp(this.g)*255<<8;
636
+ const b = clamp(this.b)*255<<16;
637
+ const a = clamp(this.a)*255<<24;
639
638
  return r + g + b + a;
640
639
  }
641
640
  }
@@ -743,6 +742,12 @@ let canvasPixelated = 1;
743
742
  * @memberof Settings */
744
743
  let fontDefault = 'arial';
745
744
 
745
+ /** Enable to show the LittleJS splash screen be shown on startup
746
+ * @type {Boolean}
747
+ * @default
748
+ * @memberof Settings */
749
+ let showSplashScreen = 0;
750
+
746
751
  ///////////////////////////////////////////////////////////////////////////////
747
752
  // WebGL settings
748
753
 
@@ -976,6 +981,11 @@ function setCanvasPixelated(pixelated) { canvasPixelated = pixelated; }
976
981
  * @memberof Settings */
977
982
  function setFontDefault(font) { fontDefault = font; }
978
983
 
984
+ /** Set if the LittleJS splash screen be shown on startup
985
+ * @param {Boolean} show
986
+ * @memberof Settings */
987
+ function setShowSplashScreen(show) { showSplashScreen = show; }
988
+
979
989
  /** Set if webgl rendering is enabled
980
990
  * @param {Boolean} enable
981
991
  * @memberof Settings */
@@ -1222,7 +1232,7 @@ class EngineObject
1222
1232
  // init other internal object stuff
1223
1233
  this.spawnTime = time;
1224
1234
  this.children = [];
1225
- this.collideTiles = 1;
1235
+ this.collideTiles = false;
1226
1236
 
1227
1237
  // add to list of objects
1228
1238
  engineObjects.push(this);
@@ -1567,7 +1577,7 @@ let mainCanvasSize = vec2();
1567
1577
  * @memberof Draw */
1568
1578
  let textureInfos = [];
1569
1579
 
1570
- // Engine internal variables not exposed to documentation
1580
+ // Keep track of how many draw calls there were each frame for debugging
1571
1581
  let drawCount;
1572
1582
 
1573
1583
  ///////////////////////////////////////////////////////////////////////////////
@@ -2170,23 +2180,33 @@ function inputUpdatePost()
2170
2180
  ///////////////////////////////////////////////////////////////////////////////
2171
2181
  // Keyboard event handlers
2172
2182
 
2173
- onkeydown = (e)=>
2174
2183
  {
2175
- if (debug && e.target != document.body) return;
2176
- e.repeat || (inputData[isUsingGamepad = 0][remapKey(e.which)] = 3);
2177
- preventDefaultInput && e.preventDefault();
2178
- }
2184
+ onkeydown = (e)=>
2185
+ {
2186
+ if (debug && e.target != document.body) return;
2187
+ if (!e.repeat)
2188
+ {
2189
+ inputData[isUsingGamepad = 0][e.which] = 3;
2190
+ if (inputWASDEmulateDirection)
2191
+ inputData[0][remapKey(e.which)] = 3;
2192
+ }
2193
+ preventDefaultInput && e.preventDefault();
2194
+ }
2179
2195
 
2180
- onkeyup = (e)=>
2181
- {
2182
- if (debug && e.target != document.body) return;
2183
- inputData[0][remapKey(e.which)] = 4;
2184
- }
2196
+ onkeyup = (e)=>
2197
+ {
2198
+ if (debug && e.target != document.body) return;
2199
+ inputData[0][e.which] = 4;
2200
+ if (inputWASDEmulateDirection)
2201
+ inputData[0][remapKey(e.which)] = 4;
2202
+ }
2185
2203
 
2186
- function remapKey(c)
2187
- {
2188
- return inputWASDEmulateDirection ?
2189
- c==87?38 : c==83?40 : c==65?37 : c==68?39 : c : c;
2204
+ // handle remapping wasd keys to directions
2205
+ function remapKey(c)
2206
+ {
2207
+ return inputWASDEmulateDirection ?
2208
+ c==87?38 : c==83?40 : c==65?37 : c==68?39 : c : c;
2209
+ }
2190
2210
  }
2191
2211
 
2192
2212
  ///////////////////////////////////////////////////////////////////////////////
@@ -2685,7 +2705,7 @@ class Music extends Sound
2685
2705
  * @param {Boolean} [loop=1] - True if the music should loop
2686
2706
  * @return {AudioBufferSourceNode} - The audio source node
2687
2707
  */
2688
- play(volume, loop = 1)
2708
+ playMusic(volume, loop = 1)
2689
2709
  { return super.play(0, volume, 1, 1, loop); }
2690
2710
  }
2691
2711
 
@@ -3332,10 +3352,10 @@ constructor(pos, size=tileCollisionSize, tileInfo=tile(), scale=vec2(1), renderO
3332
3352
  /** Draw directly to the 2D canvas in world space (bipass webgl)
3333
3353
  * @param {Vector2} pos
3334
3354
  * @param {Vector2} size
3335
- * @param {Number} [angle=0]
3336
- * @param {Boolean} [mirror=0]
3355
+ * @param {Number} angle
3356
+ * @param {Boolean} mirror
3337
3357
  * @param {Function} drawFunction */
3338
- drawCanvas2D(pos, size, angle=0, mirror, drawFunction)
3358
+ drawCanvas2D(pos, size, angle, mirror, drawFunction)
3339
3359
  {
3340
3360
  const context = this.context;
3341
3361
  context.save();
@@ -3349,12 +3369,12 @@ constructor(pos, size=tileCollisionSize, tileInfo=tile(), scale=vec2(1), renderO
3349
3369
  }
3350
3370
 
3351
3371
  /** Draw a tile directly onto the layer canvas
3352
- * @param {Vector2} pos
3353
- * @param {Vector2} [size=Vector2(1,1)]
3372
+ * @param {Vector2} pos
3373
+ * @param {Vector2} [size=Vector2(1,1)]
3354
3374
  * @param {TileInfo} [tileInfo]
3355
- * @param {Color} [color=Color()]
3356
- * @param {Number} [angle=0]
3357
- * @param {Boolean} [mirror=0] */
3375
+ * @param {Color} [color=Color()]
3376
+ * @param {Number} [angle=0]
3377
+ * @param {Boolean} [mirror=0] */
3358
3378
  drawTile(pos, size=vec2(1), tileInfo, color=new Color, angle, mirror)
3359
3379
  {
3360
3380
  this.drawCanvas2D(pos, size, angle, mirror, (context)=>
@@ -3517,7 +3537,7 @@ class ParticleEmitter extends EngineObject
3517
3537
  this.fadeRate = fadeRate;
3518
3538
  /** @property {Number} - Apply extra randomness percent */
3519
3539
  this.randomness = randomness;
3520
- /** @property {Number} - Do particles collide against tiles */
3540
+ /** @property {Boolean} - Do particles collide against tiles */
3521
3541
  this.collideTiles = collideTiles;
3522
3542
  /** @property {Number} - Should particles use addtive blend */
3523
3543
  this.additive = additive;
@@ -4005,7 +4025,7 @@ let glCanvas;
4005
4025
  let glContext;
4006
4026
 
4007
4027
  // WebGL internal variables not exposed to documentation
4008
- let glActiveTexture, glShader, glArrayBuffer, glPositionData, glColorData, glBatchCount, glBatchAdditive, glAdditive;
4028
+ let glActiveTexture, glShader, glArrayBuffer, glVertexData, glPositionData, glColorData, glBatchCount, glBatchAdditive, glAdditive;
4009
4029
 
4010
4030
  ///////////////////////////////////////////////////////////////////////////////
4011
4031
 
@@ -4042,10 +4062,10 @@ function glInit()
4042
4062
  );
4043
4063
 
4044
4064
  // init buffers
4045
- const vertexData = new ArrayBuffer(gl_VERTEX_BUFFER_SIZE);
4065
+ glVertexData = new ArrayBuffer(gl_VERTEX_BUFFER_SIZE);
4066
+ glPositionData = new Float32Array(glVertexData);
4067
+ glColorData = new Uint32Array(glVertexData);
4046
4068
  glArrayBuffer = glContext.createBuffer();
4047
- glPositionData = new Float32Array(vertexData);
4048
- glColorData = new Uint32Array(vertexData);
4049
4069
  glBatchCount = 0;
4050
4070
  }
4051
4071
 
@@ -4073,7 +4093,7 @@ function glPreRender()
4073
4093
  glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
4074
4094
  offset += size*typeSize;
4075
4095
  }
4076
- initVertexAttribArray('p', gl_FLOAT, 4, 4); // position & texture coords
4096
+ initVertexAttribArray('p', gl_FLOAT, 4, 4); // position & texture
4077
4097
  initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
4078
4098
  initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
4079
4099
 
@@ -4143,7 +4163,7 @@ function glCreateProgram(vsSource, fsSource)
4143
4163
  return program;
4144
4164
  }
4145
4165
 
4146
- /** Create WebGL texture from an image and set the texture settings
4166
+ /** Create WebGL texture from an image and init the texture settings
4147
4167
  * @param {Image} image
4148
4168
  * @return {WebGLTexture}
4149
4169
  * @memberof WebGL */
@@ -4152,7 +4172,8 @@ function glCreateTexture(image)
4152
4172
  // build the texture
4153
4173
  const texture = glContext.createTexture();
4154
4174
  glContext.bindTexture(gl_TEXTURE_2D, texture);
4155
- image && image.width && glContext.texImage2D(gl_TEXTURE_2D, 0, gl_RGBA, gl_RGBA, gl_UNSIGNED_BYTE, image);
4175
+ if (image)
4176
+ glContext.texImage2D(gl_TEXTURE_2D, 0, gl_RGBA, gl_RGBA, gl_UNSIGNED_BYTE, image);
4156
4177
 
4157
4178
  // use point filtering for pixelated rendering
4158
4179
  const filter = canvasPixelated ? gl_NEAREST : gl_LINEAR;
@@ -4160,6 +4181,7 @@ function glCreateTexture(image)
4160
4181
  glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, filter);
4161
4182
  glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE);
4162
4183
  glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE);
4184
+
4163
4185
  return texture;
4164
4186
  }
4165
4187
 
@@ -4174,8 +4196,7 @@ function glFlush()
4174
4196
  glContext.enable(gl_BLEND);
4175
4197
 
4176
4198
  // draw all the sprites in the batch and reset the buffer
4177
- glContext.bufferSubData(gl_ARRAY_BUFFER, 0,
4178
- glPositionData.subarray(0, glBatchCount * gl_INDICIES_PER_VERT));
4199
+ glContext.bufferSubData(gl_ARRAY_BUFFER, 0, glVertexData);
4179
4200
  glContext.drawArrays(gl_TRIANGLE_STRIP, 0, glBatchCount);
4180
4201
  glBatchCount = 0;
4181
4202
  glBatchAdditive = glAdditive;
@@ -4230,11 +4251,11 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
4230
4251
  // setup 2 triangle strip quad
4231
4252
  for(let i = vertCount, offset = glBatchCount * gl_INDICIES_PER_VERT; i--;)
4232
4253
  {
4233
- let j = clamp(i-1, 0, 3)*4; // degenerate tri at ends
4234
- glPositionData[offset++] = positionData[j++];
4235
- glPositionData[offset++] = positionData[j++];
4236
- glPositionData[offset++] = positionData[j++];
4237
- glPositionData[offset++] = positionData[j++];
4254
+ const j = clamp(i-1, 0, 3)*4; // degenerate tri at ends
4255
+ glPositionData[offset++] = positionData[j+0];
4256
+ glPositionData[offset++] = positionData[j+1];
4257
+ glPositionData[offset++] = positionData[j+2];
4258
+ glPositionData[offset++] = positionData[j+3];
4238
4259
  glColorData[offset++] = rgba;
4239
4260
  glColorData[offset++] = rgbaAdditive;
4240
4261
  }
@@ -4435,7 +4456,7 @@ const engineName = 'LittleJS';
4435
4456
  * @type {String}
4436
4457
  * @default
4437
4458
  * @memberof Engine */
4438
- const engineVersion = '1.8.5';
4459
+ const engineVersion = '1.8.8';
4439
4460
 
4440
4461
  /** Frames per second to update objects
4441
4462
  * @type {Number}
@@ -4618,7 +4639,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
4618
4639
  }
4619
4640
 
4620
4641
  // setup html
4621
- const styleBody =
4642
+ const styleBody =
4622
4643
  'margin:0;overflow:hidden;' + // fill the window
4623
4644
  'background:#000;' + // set background color
4624
4645
  'touch-action:none;' + // prevent mobile pinch to resize
@@ -4639,14 +4660,13 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
4639
4660
 
4640
4661
  // set canvas style
4641
4662
  const styleCanvas =
4642
- 'position:absolute;' + // position
4643
- 'top:50%;left:50%;transform:translate(-50%,-50%);' + // center
4644
- (canvasPixelated?'image-rendering:pixelated':''); // pixelated rendering
4663
+ 'position:absolute;' + // position
4664
+ 'top:50%;left:50%;transform:translate(-50%,-50%)'; // center
4645
4665
  (glCanvas||mainCanvas).style = mainCanvas.style = overlayCanvas.style = styleCanvas;
4646
4666
 
4647
- // load all of the images
4648
- Promise.all(imageSources.map((src, textureIndex)=>
4649
- new Promise((resolve, reject)=>
4667
+ // create promises for loading images
4668
+ const promises = imageSources.map((src, textureIndex)=>
4669
+ new Promise(resolve =>
4650
4670
  {
4651
4671
  const image = new Image;
4652
4672
  image.onerror = image.onload = ()=>
@@ -4656,7 +4676,24 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
4656
4676
  }
4657
4677
  image.src = src;
4658
4678
  })
4659
- )).then(()=>
4679
+ )
4680
+
4681
+ // draw splash screen
4682
+ showSplashScreen && promises.push(new Promise(resolve =>
4683
+ {
4684
+ let t = 0;
4685
+ console.log(`LittleJS Engine v${engineVersion}`);
4686
+ updateSplash();
4687
+ function updateSplash()
4688
+ {
4689
+ clearInput();
4690
+ drawEngineSplashScreen(t+=.01);
4691
+ t>1 ? resolve() : setTimeout(updateSplash,16);
4692
+ }
4693
+ }));
4694
+
4695
+ // load all of the images
4696
+ Promise.all(promises).then(()=>
4660
4697
  {
4661
4698
  // start the engine
4662
4699
  gameInit();
@@ -4734,4 +4771,165 @@ function engineObjectsCallback(pos, size, callbackFunction, objects=engineObject
4734
4771
  for (const o of objects)
4735
4772
  pos.distanceSquared(o.pos) < sizeSquared && callbackFunction(o);
4736
4773
  }
4774
+ }
4775
+
4776
+ ///////////////////////////////////////////////////////////////////////////////
4777
+ // LittleJS splash screen and logo
4778
+
4779
+ function drawEngineSplashScreen(t)
4780
+ {
4781
+ // background
4782
+ const grayscale = 0;
4783
+ const x = mainContext;
4784
+ const w = mainCanvas.width = innerWidth;
4785
+ const h = mainCanvas.height = innerHeight;
4786
+ const p3 = percent(t, 1, .8);
4787
+ const p4 = percent(t, 0, .5);
4788
+ const g = x.createRadialGradient(w/2,h/2,0,w/2,h/2,Math.hypot(w,h)*.7);
4789
+ g.addColorStop(0,hsl(0,0,lerp(p4,0,p3/2),p3));
4790
+ g.addColorStop(1,hsl(0,0,0,p3));
4791
+ x.save();
4792
+ x.fillStyle = g;
4793
+ x.fillRect(0,0,w,h);
4794
+
4795
+ // logo - fade in and out
4796
+ const rect = (X, Y, W, H, C)=>
4797
+ {
4798
+ x.beginPath();
4799
+ x.rect(X,Y,W,C?H*p:H);
4800
+ x.fillStyle = C;
4801
+ C ? x.fill() : x.stroke();
4802
+ };
4803
+ const line = (X, Y, Z, W)=>
4804
+ {
4805
+ x.beginPath();
4806
+ x.lineTo(X,Y);
4807
+ x.lineTo(Z,W);
4808
+ x.stroke();
4809
+ };
4810
+ const circle = (X, Y, R, A=0, B=2*PI, C, F)=>
4811
+ {
4812
+ const D = (A+B)/2, E = p*(B-A)/2;
4813
+ x.beginPath();
4814
+ F && x.lineTo(X,Y);
4815
+ x.arc(X,Y,R,D-E,D+E);
4816
+ x.fillStyle = C;
4817
+ C ? x.fill() : x.stroke();
4818
+ };
4819
+ const color = (c=0, l=0) =>
4820
+ hsl([.98,.3,.57,.14][c%4]-10,grayscale?0:.8,[0,.3,.5,.8,.9][l]);
4821
+ const alpha = wave(1,1,t);
4822
+ const p = percent(alpha, .1, .5);
4823
+
4824
+ // setup
4825
+ x.translate(w/2,h/2);
4826
+ const size = min(6, min(w,h)/99); // fit to screen
4827
+ x.scale(size,size);
4828
+ x.translate(-40,-35);
4829
+ x.lineJoin = x.lineCap = 'round';
4830
+ x.lineWidth = 1+p;
4831
+
4832
+ // drawing effect
4833
+ const p2 = percent(alpha,.1,1);
4834
+ x.setLineDash([99*p2,99]);
4835
+
4836
+ // cab top
4837
+ rect(7,17,18,-8,color(2,2));
4838
+ rect(7,9,18,4,color(2,3));
4839
+ rect(25,9,8,8,color(2,1));
4840
+ rect(25,9,-18,8);
4841
+ rect(25,9,8,8);
4842
+
4843
+ // cab
4844
+ rect(25,17,7,22,color());
4845
+ rect(11,40,14,-23,color(1,1));
4846
+ rect(11,17,14,17,color(1,2));
4847
+ rect(11,17,14,9,color(1,3));
4848
+ rect(15,31,6,-9,color(2,2));
4849
+ circle(15,23,5,0,PI/2,color(2,4),1);
4850
+ rect(25,17,-14,23);
4851
+ rect(21,22,-6,9);
4852
+
4853
+ // little stack
4854
+ rect(37,14,9,6,color(3,2));
4855
+ rect(37,14,4,6,color(3,3));
4856
+ rect(37,14,9,6);
4857
+
4858
+ // big stack
4859
+ rect(50,20,10,-10,color(0,1));
4860
+ rect(50,20,6,-10,color(0,2));
4861
+ rect(50,20,3,-10,color(0,3));
4862
+ rect(50,10,10,10);
4863
+ circle(55,2,11,.5,PI-.5,color(3,3));
4864
+ circle(55,2,11,.5,PI/2,color(3,2),1);
4865
+ circle(55,2,11,.5,PI-.5);
4866
+ rect(45,7,20,-7,color(0,2));
4867
+ rect(45,0,20,3,color(0,3));
4868
+ rect(45,0,20,7);
4869
+
4870
+ // engine
4871
+ for (let i=5; i--;)
4872
+ {
4873
+ // stagger radius to fix slight seam
4874
+ circle(60-i*6,30, 9.9,0,2*PI,color(i+2,3));
4875
+ circle(60-i*6,30,10.0,-.5,PI+.5,color(i+2,2));
4876
+ circle(60-i*6,30,10.1,.5,PI-.5,color(i+2,1));
4877
+ }
4878
+
4879
+ // engine outline
4880
+ circle(36,30,10,PI/2,PI*3/2);
4881
+ circle(47,30,10,PI/2,PI*3/2);
4882
+ circle(60,30,10);
4883
+ line(36,20,60,20);
4884
+
4885
+ // engine front light
4886
+ circle(60,30,4,PI,3*PI,color(3,2));
4887
+ circle(60,30,4,PI,2*PI,color(3,3));
4888
+ circle(60,30,4,PI,3*PI);
4889
+
4890
+ // front brush
4891
+ for (let i=6; i--;)
4892
+ {
4893
+ x.beginPath();
4894
+ x.lineTo(53,54);
4895
+ x.lineTo(53,40);
4896
+ x.lineTo(53+(1+i*2.9)*p,40);
4897
+ x.lineTo(53+(4+i*3.5)*p,54);
4898
+ x.fillStyle = color(0,i%2+2);
4899
+ x.fill() || i%2 && x.stroke();
4900
+ }
4901
+
4902
+ // wheels
4903
+ rect(5,40,9,6,color());
4904
+ rect(15,54,38,-14,color())
4905
+ for (let i=3; i--;)
4906
+ for (let j=2; j--;)
4907
+ {
4908
+ circle(15*i+15,47,j?7:1,PI,3*PI,color(i,3));
4909
+ x.stroke();
4910
+ circle(15*i+15,47,j?7:1,0,PI,color(i,2));
4911
+ x.stroke();
4912
+ }
4913
+ line(6,40,68,40) // center
4914
+ line(77,54,4,54) // bottom
4915
+
4916
+ // text
4917
+ const s = engineName;
4918
+ x.font = '900 16px arial';
4919
+ x.textAlign = 'center';
4920
+ x.textBaseline = 'top';
4921
+ x.lineWidth = 1+p*3
4922
+ let w2 = 0;
4923
+ for (let i=0; i<s.length; ++i)
4924
+ w2 += x.measureText(s[i]).width;
4925
+ for (let j=2; j--;)
4926
+ for (let i=0, X=41-w2/2; i<s.length; ++i)
4927
+ {
4928
+ x.fillStyle = color(i,grayscale?3:2);
4929
+ const w = x.measureText(s[i]).width;
4930
+ x[j?'strokeText':'fillText'](s[i],X+w/2,55.5,17*p);
4931
+ X += w;
4932
+ }
4933
+
4934
+ x.restore();
4737
4935
  }
@@ -8,6 +8,9 @@
8
8
 
9
9
  'use strict';
10
10
 
11
+ // show the LittleJS splash screen
12
+ showSplashScreen = 1;
13
+
11
14
  let levelSize, ball, paddle, score, brickCount;
12
15
 
13
16
  // sound effects
@@ -5,6 +5,6 @@
5
5
  <link rel=icon type=image/png href=../favicon.png>
6
6
  </head><body>
7
7
 
8
- <script src=../../build/littlejs.js?183></script>
9
- <script src=gameObjects.js?183></script>
10
- <script src=game.js?183></script>
8
+ <script src=../../build/littlejs.js?188></script>
9
+ <script src=gameObjects.js?188></script>
10
+ <script src=game.js?188></script>
@@ -5,5 +5,5 @@
5
5
  <link rel=icon type=image/png href=../favicon.png>
6
6
  </head><body>
7
7
 
8
- <script src=../../build/littlejs.js?183></script>
9
- <script src=game.js?183></script>
8
+ <script src=../../build/littlejs.js?188></script>
9
+ <script src=game.js?188></script>
@@ -16,6 +16,9 @@ medalsInit('Hello World');
16
16
  // game variables
17
17
  let particleEmiter;
18
18
 
19
+ // show the LittleJS splash screen
20
+ showSplashScreen = 1;
21
+
19
22
  ///////////////////////////////////////////////////////////////////////////////
20
23
  function gameInit()
21
24
  {
@@ -6,7 +6,7 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- LittleJS Engine -->
9
- <script src=../../build/littlejs.js?183></script>
9
+ <script src=../../build/littlejs.js?188></script>
10
10
 
11
11
  <!-- Add your game scripts here -->
12
- <script src=game.js?183></script>
12
+ <script src=game.js?188></script>
@@ -1,18 +1,18 @@
1
1
  <head><title>LittleJS JS13K Project</title></head><body>
2
2
 
3
3
  <!-- LittleJS Engine -->
4
- <script src=../../src/engineDebug.js?183></script>
5
- <script src=../../src/engineUtilities.js?183></script>
6
- <script src=../../src/engineSettings.js?183></script>
7
- <script src=../../src/engineObject.js?183></script>
8
- <script src=../../src/engineDraw.js?183></script>
9
- <script src=../../src/engineInput.js?183></script>
10
- <script src=../../src/engineAudio.js?183></script>
11
- <script src=../../src/engineTileLayer.js?183></script>
12
- <script src=../../src/engineParticles.js?183></script>
13
- <script src=../../src/engineMedals.js?183></script>
14
- <script src=../../src/engineWebGL.js?183></script>
15
- <script src=../../src/engine.js?183></script>
4
+ <script src=../../src/engineDebug.js?188></script>
5
+ <script src=../../src/engineUtilities.js?188></script>
6
+ <script src=../../src/engineSettings.js?188></script>
7
+ <script src=../../src/engineObject.js?188></script>
8
+ <script src=../../src/engineDraw.js?188></script>
9
+ <script src=../../src/engineInput.js?188></script>
10
+ <script src=../../src/engineAudio.js?188></script>
11
+ <script src=../../src/engineTileLayer.js?188></script>
12
+ <script src=../../src/engineParticles.js?188></script>
13
+ <script src=../../src/engineMedals.js?188></script>
14
+ <script src=../../src/engineWebGL.js?188></script>
15
+ <script src=../../src/engine.js?188></script>
16
16
 
17
17
  <!-- Add your game scripts here -->
18
- <script src=game.js?183></script>
18
+ <script src=game.js?188></script>
Binary file
@@ -10,6 +10,9 @@
10
10
  import * as LittleJS from '../../build/littlejs.esm.js';
11
11
  const {Vector2, Color, Timer, vec2, tile} = LittleJS;
12
12
 
13
+ // show the LittleJS splash screen
14
+ LittleJS.setShowSplashScreen(1);
15
+
13
16
  // sound effects
14
17
  const sound_click = new LittleJS.Sound([1,.5]);
15
18
 
@@ -6,4 +6,4 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- Add your game scripts here -->
9
- <script src=game.js?183 type=module></script>
9
+ <script src=game.js?188 type=module></script>
@@ -9,7 +9,7 @@ button { margin:1px; }
9
9
  </style>
10
10
  </head><body>
11
11
 
12
- <script src=../../build/littlejs.js?183></script>
12
+ <script src=../../build/littlejs.js?188></script>
13
13
  <script>
14
14
 
15
15
  'use strict';
@@ -8,6 +8,9 @@
8
8
 
9
9
  'use strict';
10
10
 
11
+ // show the LittleJS splash screen
12
+ showSplashScreen = 1;
13
+
11
14
  let score, deaths;
12
15
 
13
16
  ///////////////////////////////////////////////////////////////////////////////
@@ -107,9 +107,9 @@ class Character extends GameObject
107
107
  if (this.weapon) // update weapon trigger
108
108
  this.weapon.triggerIsDown = this.holdingShoot && !this.dodgeTimer.active();
109
109
 
110
- // update ladder
111
110
  if (this.climbingLadder)
112
111
  {
112
+ // update ladder
113
113
  this.gravityScale = this.climbingWall = this.groundObject = 0;
114
114
  this.jumpTimer.unset();
115
115
  this.groundTimer.unset();
@@ -6,9 +6,9 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.js?183></script>
10
- <script src=gameObjects.js?183></script>
11
- <script src=gamePlayer.js?183></script>
12
- <script src=gameEffects.js?183></script>
13
- <script src=gameLevel.js?183></script>
14
- <script src=game.js?183></script>
9
+ <script src=../../build/littlejs.js?188></script>
10
+ <script src=gameObjects.js?188></script>
11
+ <script src=gamePlayer.js?188></script>
12
+ <script src=gameEffects.js?188></script>
13
+ <script src=gameLevel.js?188></script>
14
+ <script src=game.js?188></script>
@@ -8,6 +8,9 @@
8
8
 
9
9
  'use strict';
10
10
 
11
+ // show the LittleJS splash screen
12
+ showSplashScreen = 1;
13
+
11
14
  canvasPixelated = 0; // do not use pixelated rendering
12
15
 
13
16
  const fallTime = .2;
@@ -5,5 +5,5 @@
5
5
  <link rel=icon type=image/png href=../favicon.png>
6
6
  </head><body>
7
7
 
8
- <script src=../../build/littlejs.js?183></script>
9
- <script src=game.js?183></script>
8
+ <script src=../../build/littlejs.js?188></script>
9
+ <script src=game.js?188></script>
@@ -7,6 +7,9 @@
7
7
 
8
8
  'use strict';
9
9
 
10
+ // show the LittleJS splash screen
11
+ showSplashScreen = 1;
12
+
10
13
  // sound effects
11
14
  const sound_click = new Sound([1,.5]);
12
15