littlejsengine 1.13.4 → 1.14.4

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 (58) hide show
  1. package/README.md +4 -3
  2. package/dist/littlejs.d.ts +395 -249
  3. package/dist/littlejs.esm.js +1550 -754
  4. package/dist/littlejs.esm.min.js +1 -1
  5. package/dist/littlejs.js +1528 -744
  6. package/dist/littlejs.min.js +1 -1
  7. package/dist/littlejs.release.js +1504 -720
  8. package/examples/box2d/game.js +4 -4
  9. package/examples/box2d/gameObjects.js +1 -1
  10. package/examples/breakout/game.js +30 -25
  11. package/examples/breakoutTutorial/README.md +1 -1
  12. package/examples/breakoutTutorial/game.js +1 -1
  13. package/examples/electron/build.js +1 -1
  14. package/examples/electron/index.html +2 -2
  15. package/examples/empty/game.js +1 -1
  16. package/examples/htmlMenu/index.html +7 -7
  17. package/examples/index.html +208 -97
  18. package/examples/platformer/gameEffects.js +20 -25
  19. package/examples/platformer/gameLevel.js +6 -1
  20. package/examples/shorts/base.html +1 -1
  21. package/examples/shorts/flappyGame.js +2 -1
  22. package/examples/shorts/helloWorld.js +1 -1
  23. package/examples/shorts/music.js +106 -0
  24. package/examples/shorts/parallax.js +71 -0
  25. package/examples/shorts/piano.js +7 -8
  26. package/examples/shorts/postProcess.js +25 -8
  27. package/examples/shorts/shapes.js +12 -18
  28. package/examples/shorts/song.mp3 +0 -0
  29. package/examples/shorts/uiSystem.js +15 -8
  30. package/examples/starter/index.html +2 -2
  31. package/examples/stress/index.html +14 -7
  32. package/examples/style.css +14 -4
  33. package/examples/typescript/build.js +1 -1
  34. package/examples/uiSystem/game.js +11 -11
  35. package/package.json +1 -1
  36. package/plugins/box2d.js +12 -10
  37. package/plugins/drawUtilities.js +5 -5
  38. package/plugins/newgrounds.js +6 -6
  39. package/plugins/pluginExport.js +1 -1
  40. package/plugins/uiSystem.js +103 -79
  41. package/plugins/zzfxm.js +10 -10
  42. package/reference.md +94 -56
  43. package/src/engine.js +28 -24
  44. package/src/engineAudio.js +284 -109
  45. package/src/engineBuild.js +11 -11
  46. package/src/engineDebug.js +29 -29
  47. package/src/engineDraw.js +285 -112
  48. package/src/engineExport.js +28 -16
  49. package/src/engineInput.js +57 -67
  50. package/src/engineMedals.js +25 -25
  51. package/src/engineObject.js +28 -25
  52. package/src/engineParticles.js +59 -59
  53. package/src/engineRelease.js +1 -1
  54. package/src/engineSettings.js +20 -13
  55. package/src/engineTileLayer.js +34 -35
  56. package/src/engineUtilities.js +66 -59
  57. package/src/engineWebGL.js +466 -66
  58. /package/examples/shorts/{playSound.js → sound.js} +0 -0
package/reference.md CHANGED
@@ -13,7 +13,7 @@ To start LittleJS, you need to create a few functions and pass them to engineIni
13
13
 
14
14
  ```javascript
15
15
  // Start up LittleJS engine with your callback functions
16
- engineInit(init, update, updatePost, render, renderPost, imageSources=[]);
16
+ engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
17
17
  ```
18
18
 
19
19
  ## LittleJS Utilities Classes and Functions
@@ -33,13 +33,14 @@ tile(pos, size=(16,16), texture=0, padding=0) // Create a tile info object
33
33
 
34
34
  // Helper functions
35
35
  abs(value) // Get absolute value
36
- min(valueA, valueB) // Get lowest of values
37
- max(valueA, valueB) // Get highest of values
36
+ min(...values) // Get lowest of values
37
+ max(...values) // Get highest of values
38
38
  sign(value) // Get the sign of value
39
39
  mod(dividend, divisor=1) // Get remainder of division
40
40
  clamp(value, min=0, max=1) // Clamps between values
41
41
  percent(value, valueA, valueB) // Get percentage between values
42
42
  lerp(valueA, valueB, percent) // Linearly interpolates between values
43
+ percentLerp(value, percentA, percentB, lerpA, lerpB) // Lerp that remaps the percent
43
44
  distanceWrap(valueA, valueB, wrapSize=1) // Signed wrapped distance between values
44
45
  lerpWrap(valueA, valueB, percent, wrapSize=1) // Linearly interpolates with wrapping
45
46
  distanceAngle(angleA, angleB) // Signed wrapped distance between angles
@@ -54,7 +55,8 @@ formatTime(t) // Formats seconds for display
54
55
  // Random functions
55
56
  rand(valueA=1, valueB=0) // Random float between values
56
57
  randInt(valueA, valueB=0) // Random integer between values
57
- randSign() // Randomly bool either -1 or 1
58
+ randBool(chance=.5) // Random boolean with given chance (0 to 1)
59
+ randSign() // Randomly either -1 or 1
58
60
  randVec2(length=1) // Random Vector2 with the passed in length
59
61
  randInCircle(radius=1, minRadius=0) // Random Vector2 within a circle
60
62
  randColor(colorA, colorB, linear) // Random color between values
@@ -111,16 +113,16 @@ RandomGenerator.int(valueA, valueB=0) // Random integer between values
111
113
  RandomGenerator.sign() // Randomly either -1 or 1
112
114
 
113
115
  // Time tracking system
114
- Timer(timeLeft) // Create a timer object
115
- Timer.set(timeLeft=0) // Set the timer with seconds passed in
116
- Timer.unset() // Unset the timer
117
- Timer.isSet() // Returns true if set
118
- Timer.active() // Returns true if set and has not elapsed
119
- Timer.elapsed() // Returns true if set and elapsed
120
- Timer.get() // Get how long since elapsed, 0 if not set
121
- Timer.getPercent() // Get percent elapsed, 0 if not set
122
- Timer.toString() // Get this timer expressed as a string
123
- Timer.valueOf() // Get how long since elapsed, 0 if not set
116
+ Timer(timeLeft) // Create a timer object
117
+ Timer.set(timeLeft=0) // Set the timer with seconds passed in
118
+ Timer.unset() // Unset the timer
119
+ Timer.isSet() // Returns true if set
120
+ Timer.active() // Returns true if set and has not elapsed
121
+ Timer.elapsed() // Returns true if set and elapsed
122
+ Timer.get() // Get how long since elapsed, 0 if not set
123
+ Timer.getPercent() // Get percent elapsed, 0 if not set
124
+ Timer.toString() // Get this timer expressed as a string
125
+ Timer.valueOf() // Get how long since elapsed, 0 if not set
124
126
  ```
125
127
 
126
128
  ## LittleJS Drawing System
@@ -131,35 +133,48 @@ Timer.valueOf() // Get how long since elapsed, 0 if not set
131
133
 
132
134
  ```javascript
133
135
  // Drawing functions
134
- drawTile(pos, size=(1,1), tileInfo, color=WHITE, angle=0, mirror, additiveColor)
135
- drawRect(pos, size=(1,1), color=WHITE, angle=0)
136
- drawLine(posA, posB, thickness=.1, color=WHITE)
137
- drawCanvas2D(pos, size, angle, mirror, drawFunction)
138
- drawText(text, pos, size=1, color=WHITE, lineWidth, lineColor)
139
- drawTextScreen(text, pos, size=1, color=WHITE, lineWidth, lineColor)
136
+ drawTile(pos, size, tileInfo, color=WHITE, angle=0, mirror, additiveColor)
137
+ drawRect(pos, size, color=WHITE, angle=0)
138
+ drawRectGradient(pos, size, colorTop=WHITE, colorBottom=BLACK, angle=0)
139
+ drawLine(posA, posB, width=.1, color=WHITE, pos=(0,0), angle=0)
140
+ drawLineList(points, width=.1, color, wrap=false, pos=(0,0), angle=0)
141
+ drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos, angle=0)
142
+ drawRegularPoly(pos, size=(1,1), sides=3, color=WHITE, lineWidth=0, lineColor=BLACK, angle=0)
143
+ drawEllipse(pos, size=(1,1), color=WHITE, angle=0, lineWidth=0, lineColor=BLACK)
144
+ drawCircle(pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
145
+ drawCanvas2D(pos, size, angle=0, mirror, drawFunction, screenSpace, context)
146
+
147
+ // Text functions
148
+ drawText(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
149
+ drawTextOverlay(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
150
+ drawTextScreen(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK)
151
+
152
+ // Utility drawing functions
140
153
  setBlendMode(additive)
141
- toggleFullscreen()
142
154
  isFullscreen()
155
+ toggleFullscreen()
143
156
 
144
157
  // Tile Info Object
145
- TileInfo(pos=(0,0), size, textureIndex=0) // Create a tile info object
146
- TileInfo.pos // Top left corner of tile in pixels
147
- TileInfo.size // Size of tile in pixels
148
- TileInfo.textureIndex // Texture index to use
149
- TileInfo.offset(offset) // Offset this tile by a certain amount in pixels
150
- TileInfo.frame(frame) // Offset this tile by a number of animation frames
151
- TileInfo.textureInfo // The texture info for this tile
158
+ TileInfo(pos, size, textureIndex=0, padding=0) // Create a tile info object
159
+ TileInfo.pos // Top left corner of tile in pixels
160
+ TileInfo.size // Size of tile in pixels
161
+ TileInfo.textureIndex // Texture index to use
162
+ TileInfo.padding // How many pixels padding around tiles
163
+ TileInfo.offset(offset) // Offset this tile by a certain amount in pixels
164
+ TileInfo.frame(frame) // Offset this tile by a number of animation frames
165
+ TileInfo.textureInfo // The texture info for this tile
152
166
 
153
167
  // Texture Info Object
154
- TextureInfo(image) // Created automatically for each image
155
- TextureInfo.image // Image source
156
- TextureInfo.size // Size of the image
157
- TextureInfo.glTexture // WebGL texture
168
+ TextureInfo(image) // Created automatically for each image
169
+ TextureInfo.image // Image source
170
+ TextureInfo.size // Size of the image
171
+ TextureInfo.glTexture // WebGL texture
158
172
 
159
173
  // Font Image Object draws text using characters in an image
160
174
  FontImage(image, tileSize=(8,8), paddingSize=(0,1)) // Create an image font
161
175
  FontImage.drawText(text, pos, scale, center) // Draw text in world space
162
176
  FontImage.drawTextScreen(text, pos, scale, center) // Draw text in screen space
177
+ FontImage.drawTextOverlay(text, pos, scale, center) // Draw text to overlay canvas
163
178
 
164
179
  // Camera settings
165
180
  cameraPos = (0,0) // Position of camera in world space
@@ -183,31 +198,45 @@ tileFixBleedScale = .3 // How much smaller to draw tiles to prevent bleeding
183
198
  ```
184
199
 
185
200
  ## LittleJS Audio System
186
- - Caches sounds and music for fast playback
201
+ - Caches sounds and music for fast playback with frame-spread loading
202
+ - Individual sound instance control with pause/resume capabilities
187
203
  - Can attenuate and apply stereo panning to sounds
188
- - Ability to play mp3, ogg, and wave file
204
+ - Ability to play mp3, ogg, and wave files with loading progress tracking
189
205
  - [ZzFX Sound Effect Generator](https://killedbyapixel.github.io/ZzFX)
190
206
  - [ZzFXM Music System](https://keithclark.github.io/ZzFXM)
191
207
 
192
208
  ```javascript
193
209
  // Sound Object
194
- Sound(zzfxSound) // Create a zzfx sound
195
- SoundWave(filename, randomness=0) // Load a wave, mp3, and ogg
196
- Sound.play(pos, volume=1, pitch=1, randomness=1, loop) // Play a sound
197
- Sound.playNote(semitoneOffset, pos, volume=1) // Play as note with a semitone offset
198
- Sound.stop() // Stop the last instance that was played
199
- Sound.getSource() // Get source of most recent instance
200
- Sound.getDuration() // Get length of sound in seconds
201
- Sound.isLoading() // Check if sound is loading
202
-
203
- // ZzFXM - A tiny music system
204
- Music(..zzfxMusic) // Create a zzfx music object
205
- Music.playMusic(volume, loop=false) // Play the music
210
+ Sound(zzfxSound, range, taper) // Create a zzfx sound
211
+ SoundWave(filename, randomness=0, range, taper) // Load a wave, mp3, or ogg
212
+ Sound.play(pos, volume=1, pitch=1, randomness=1, loop) // Play a sound, returns SoundInstance
213
+ Sound.playMusic(volume=1, loop=true) // Play as music with looping
214
+ Sound.playNote(semitoneOffset, pos, volume=1) // Play as note with a semitone offset
215
+ Sound.getDuration() // Get length of sound in seconds
216
+ Sound.isLoaded() // Check if sound is currently loading
217
+ Sound.loadedPercent // Get loading progress (0 to 1)
218
+
219
+ // SoundInstance
220
+ SoundInstance.start() // Start playing the sound
221
+ SoundInstance.setVolume(volume) // Change volume during playback
222
+ SoundInstance.stop(fadeTime=0) // Stop with optional fade out
223
+ SoundInstance.pause() // Pause the sound
224
+ SoundInstance.unpause() // Resume paused sound
225
+ SoundInstance.isPlaying() // Check if currently playing
226
+ SoundInstance.isPaused() // Check if paused
227
+ SoundInstance.isStopped() // Check if stopped
228
+ SoundInstance.getCurrentTime() // Get current playback position
229
+ SoundInstance.getDuration() // Get total duration
230
+ SoundInstance.getSource() // Get AudioBufferSourceNode
231
+
232
+ // ZzFXM - Tiny music playing system
233
+ Music(..zzfxMusic) // Create a zzfx music object
234
+ Music.playMusic(volume=1, loop=true) // Play the music
206
235
 
207
236
  // Audio functions
208
- playAudioFile(filename, volume=1, loop=false) // Play an audio file or url
209
- speak(text, language='', volume=1, rate=1, pitch=1) // Speak text line
210
- speakStop() // Stop all queued speech
237
+ speak(text, language='', volume=1, rate=1, pitch=1) // Speak text line
238
+ speakStop() // Stop all queued speech
239
+ getNoteFrequency(semitoneOffset, rootFrequency=220) // Get frequency for musical notes
211
240
 
212
241
  // Audio settings
213
242
  soundEnable = true // Should sound be enabled?
@@ -228,11 +257,13 @@ soundDefaultTaper = .7 // Default range percent to taper off sound (0-1)
228
257
  keyIsDown(key) // Is key down?
229
258
  keyWasPressed(key) // Was key pressed this frame?
230
259
  keyWasReleased(key) // Was key released this frame?
231
- keyDirection(up, down, left, right) // Get input vector from arrow keys or wasd
260
+ keyDirection(up, down, left, right) // Get input vector from arrow keys or wasd
232
261
 
233
262
  // Mouse / Touch
234
263
  mousePos // World space mouse position
235
264
  mousePosScreen // Screen space mouse position
265
+ mouseDelta // World space mouse movement delta
266
+ mouseDeltaScreen // Screen space mouse movement delta
236
267
  mouseWheel // Delta mouse wheel this frame
237
268
  mouseIsDown(button) // Is mouse button down?
238
269
  mouseWasPressed(button) // Was mouse button pressed this frame?
@@ -286,7 +317,7 @@ EngineObject.render() // Render object, called auto
286
317
  EngineObject.destroy() // Destroy this object and children
287
318
  EngineObject.collideWithTile(tileData, pos) // Tile collision resolve check
288
319
  EngineObject.collideWithObject(object) // Object collision resolve check
289
- EngineObject.getAliveTime(object) // How long since object was created
320
+ EngineObject.getAliveTime() // How long since object was created
290
321
  EngineObject.applyAcceleration(acceleration) // Apply acceleration
291
322
  EngineObject.applyForce(force) // Apply force
292
323
  EngineObject.getMirrorSign() // Get mirror direction (1 or -1)
@@ -324,7 +355,7 @@ objectMaxSpeed = 1 // Clamp max speed to avoid fast objects missing c
324
355
  gravity = (0,0) // How much gravity to apply to objects
325
356
 
326
357
  // Engine Object functions
327
- engineObjectsCollect(pos, size, objects=engineObjects)k
358
+ engineObjectsCollect(pos, size, objects=engineObjects)
328
359
  engineObjectsCallback(pos, size, callbackFunction, objects=engineObjects)
329
360
  engineObjectsRaycast(start, end, objects=engineObjects)
330
361
  engineObjectsDestroy()
@@ -341,6 +372,13 @@ engineObjectsDestroy()
341
372
 
342
373
  ```javascript
343
374
 
375
+ // Canvas Layer
376
+ CanvasLayer(position, size) // Create a canvas layer object
377
+ CanvasLayer.canvas // The canvas used by this layer
378
+ CanvasLayer.context // The 2D context of the canvas
379
+ CanvasLayer.getImageData() // Get image data from canvas
380
+ CanvasLayer.useWebGL() // Creates or updates WebGL texture
381
+
344
382
  // LittleJS Layer System
345
383
  TileLayer(position, size, tileInfo, scale) // Create a tile layer object
346
384
  TileLayer.setData(layerPos, data, redraw) // Set data at position
@@ -353,7 +391,7 @@ TileLayer.drawCanvas2D(pos, size, angle, mirror, drawFunction) // Draw to 2
353
391
 
354
392
  // Tile Layer Data Object
355
393
  TileLayerData(tile, direction=0, mirror=false, color=WHITE) // Create tile data object
356
- TileLayerData.clear() // Clear this tile data
394
+ TileLayerData.clear() // Clear this tile data
357
395
 
358
396
  // Tile Collision Layer
359
397
  TileCollisionLayer(position, size, tileInfo=tile()) // Create a tile collision layer object
@@ -387,10 +425,10 @@ particleEmitRateScale = 1 // Scales particles emit rate
387
425
 
388
426
  ```javascript
389
427
  ASSERT(assert, output) // Asserts if the expression is false
390
- debugRect(pos, size, color='#fff', time=0, angle=0, fill) // Draw debug rectangle
391
- debugCircle(pos, radius, color='#fff', time=0, fill) // Draw debug circle
428
+ debugRect(pos, size, color='#fff', time=0, angle=0, fill) // Draw debug rectangle
429
+ debugCircle(pos, radius, color='#fff', time=0, fill) // Draw debug circle
392
430
  debugPoint(pos, color, time, angle) // Draw debug point
393
- debugLine(posA, posB, color, thickness=.1, time) // Draw debug line
431
+ debugLine(posA, posB, color, width=.1, time) // Draw debug line
394
432
  debugText(text, pos, size=1, color='#fff', time=0, angle=0) // Draw debug text
395
433
  debugAABB(pA, sA, pB, sB, color) // Draw a debug axis aligned box
396
434
  debugClear() // Clear all debug primitives
package/src/engine.js CHANGED
@@ -1,7 +1,7 @@
1
- /**
1
+ /**
2
2
  * LittleJS - The Tiny Fast JavaScript Game Engine
3
3
  * MIT License - Copyright 2021 Frank Force
4
- *
4
+ *
5
5
  * Engine Features
6
6
  * - Object oriented system with base class engine object
7
7
  * - Base class object handles update, physics, collision, rendering, etc
@@ -30,7 +30,7 @@ const engineName = 'LittleJS';
30
30
  * @type {string}
31
31
  * @default
32
32
  * @memberof Engine */
33
- const engineVersion = '1.13.4';
33
+ const engineVersion = '1.14.4';
34
34
 
35
35
  /** Frames per second to update
36
36
  * @type {number}
@@ -120,7 +120,7 @@ function engineAddPlugin(updateFunction, renderFunction)
120
120
  * // Basic engine startup
121
121
  * engineInit(
122
122
  * () => { console.log('Game initialized!'); }, // gameInit
123
- * () => { updatePlayer(); }, // gameUpdate
123
+ * () => { updateGameLogic(); }, // gameUpdate
124
124
  * () => { updateUI(); }, // gameUpdatePost
125
125
  * () => { drawBackground(); }, // gameRender
126
126
  * () => { drawHUD(); }, // gameRenderPost
@@ -146,7 +146,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
146
146
  mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
147
147
 
148
148
  // disable smoothing for pixel art
149
- overlayContext.imageSmoothingEnabled =
149
+ overlayContext.imageSmoothingEnabled =
150
150
  mainContext.imageSmoothingEnabled = !tilesPixelated;
151
151
 
152
152
  // setup gl rendering if enabled
@@ -194,7 +194,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
194
194
  deltaSmooth = frameTimeBufferMS;
195
195
  frameTimeBufferMS = 0;
196
196
  }
197
-
197
+
198
198
  // update multiple frames if necessary in case of slow framerate
199
199
  for (;frameTimeBufferMS >= 0; frameTimeBufferMS -= 1e3 / frameRate)
200
200
  {
@@ -239,15 +239,14 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
239
239
  overlayContext.textBaseline = 'top';
240
240
  overlayContext.font = '1em monospace';
241
241
  overlayContext.fillStyle = '#000';
242
- const text = engineName + ' ' + 'v' + engineVersion + ' / '
242
+ const text = engineName + ' ' + 'v' + engineVersion + ' / '
243
243
  + drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
244
244
  + (glEnable ? ' GL' : ' 2D') ;
245
245
  overlayContext.fillText(text, mainCanvas.width-3, 3);
246
246
  overlayContext.fillStyle = '#fff';
247
247
  overlayContext.fillText(text, mainCanvas.width-2, 2);
248
248
  }
249
- if (debug || showWatermark)
250
- drawCount = 0;
249
+ drawCount = 0;
251
250
  }
252
251
  requestAnimationFrame(engineUpdate);
253
252
  }
@@ -255,13 +254,13 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
255
254
  function updateCanvas()
256
255
  {
257
256
  if (headlessMode) return;
258
-
257
+
259
258
  if (canvasFixedSize.x)
260
259
  {
261
260
  // clear canvas and set fixed size
262
261
  mainCanvas.width = canvasFixedSize.x;
263
262
  mainCanvas.height = canvasFixedSize.y;
264
-
263
+
265
264
  // fit to window by adding space on top or bottom if necessary
266
265
  const aspect = innerWidth / innerHeight;
267
266
  const fixedAspect = mainCanvas.width / mainCanvas.height;
@@ -271,16 +270,21 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
271
270
  else
272
271
  {
273
272
  // clear canvas and set size to same as window
274
- mainCanvas.width = min(innerWidth, canvasMaxSize.x);
273
+ mainCanvas.width = min(innerWidth, canvasMaxSize.x);
275
274
  mainCanvas.height = min(innerHeight, canvasMaxSize.y);
276
275
  }
277
-
276
+
278
277
  // clear overlay canvas and set size
279
278
  overlayCanvas.width = mainCanvas.width;
280
279
  overlayCanvas.height = mainCanvas.height;
281
280
 
282
281
  // save canvas size
283
282
  mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
283
+
284
+ // set default line join and cap
285
+ const lineJoin = 'round', lineCap = 'round';
286
+ mainContext.lineJoin = overlayContext.lineJoin = lineJoin;
287
+ mainContext.lineCap = overlayContext.lineCap = lineCap;
284
288
  }
285
289
 
286
290
  // wait for gameInit to load
@@ -293,15 +297,14 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
293
297
  return startEngine();
294
298
 
295
299
  // setup html
296
- const styleRoot =
300
+ const styleRoot =
297
301
  'margin:0;' + // fill the window
298
302
  'overflow:hidden;' + // no scroll bars
299
303
  'background:#000;' + // set background color
300
304
  'user-select:none;' + // prevent hold to select
301
305
  '-webkit-user-select:none;' + // compatibility for ios
302
- (!touchInputEnable ? '' : // no touch css settings
303
306
  'touch-action:none;' + // prevent mobile pinch to resize
304
- '-webkit-touch-callout:none');// compatibility for ios
307
+ '-webkit-touch-callout:none';// compatibility for ios
305
308
  rootElement.style.cssText = styleRoot;
306
309
  drawCanvas = mainCanvas = document.createElement('canvas');
307
310
  rootElement.appendChild(mainCanvas);
@@ -318,7 +321,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
318
321
  rootElement.appendChild(overlayCanvas);
319
322
  overlayContext = overlayCanvas.getContext('2d');
320
323
 
321
- // set canvas style
324
+ // set canvases
322
325
  const styleCanvas = 'position:absolute;'+ // allow canvases to overlap
323
326
  'top:50%;left:50%;transform:translate(-50%,-50%)'; // center on screen
324
327
  mainCanvas.style.cssText = overlayCanvas.style.cssText = styleCanvas;
@@ -327,17 +330,18 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
327
330
  setCanvasPixelated(canvasPixelated);
328
331
  setOverlayCanvasPixelated(overlayCanvasPixelated);
329
332
  updateCanvas();
333
+ glPreRender();
330
334
 
331
335
  // create offscreen canvas for image processing
332
336
  workCanvas = new OffscreenCanvas(256, 256);
333
337
  workContext = workCanvas.getContext('2d', { willReadFrequently: true });
334
-
338
+
335
339
  // create promises for loading images
336
340
  const promises = imageSources.map((src, textureIndex)=>
337
- new Promise(resolve =>
341
+ new Promise(resolve =>
338
342
  {
339
343
  const image = new Image;
340
- image.onerror = image.onload = ()=>
344
+ image.onerror = image.onload = ()=>
341
345
  {
342
346
  const textureInfo = new TextureInfo(image);
343
347
  textureInfo.createWebGLTexture();
@@ -352,7 +356,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
352
356
  if (!imageSources.length)
353
357
  {
354
358
  // no images to load
355
- promises.push(new Promise(resolve =>
359
+ promises.push(new Promise(resolve =>
356
360
  {
357
361
  const textureInfo = new TextureInfo(new Image);
358
362
  textureInfos[0] = textureInfo;
@@ -364,7 +368,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
364
368
  if (showSplashScreen)
365
369
  {
366
370
  // draw splash screen
367
- promises.push(new Promise(resolve =>
371
+ promises.push(new Promise(resolve =>
368
372
  {
369
373
  let t = 0;
370
374
  console.log(`${engineName} Engine v${engineVersion}`);
@@ -596,7 +600,7 @@ function drawEngineSplashScreen(t)
596
600
  line(36,20,60,20);
597
601
 
598
602
  // engine front light
599
- circle(60,30,4,PI,3*PI,color(3,2));
603
+ circle(60,30,4,PI,3*PI,color(3,2));
600
604
  circle(60,30,4,PI,2*PI,color(3,3));
601
605
  circle(60,30,4,PI,3*PI);
602
606
 
@@ -645,6 +649,6 @@ function drawEngineSplashScreen(t)
645
649
  x[j?'strokeText':'fillText'](s[i],X+w/2,55.5,17*p);
646
650
  X += w;
647
651
  }
648
-
652
+
649
653
  x.restore();
650
654
  }