littlejsengine 1.9.5 → 1.9.6

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.
@@ -5,6 +5,6 @@
5
5
  <link rel=icon type=image/png href=../favicon.png>
6
6
  </head><body>
7
7
 
8
- <script src=../../dist/littlejs.js?192></script>
9
- <script src=gameObjects.js?192></script>
10
- <script src=game.js?192></script>
8
+ <script src=../../dist/littlejs.js?196></script>
9
+ <script src=gameObjects.js?196></script>
10
+ <script src=game.js?196></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=../../dist/littlejs.js?192></script>
9
- <script src=game.js?192></script>
8
+ <script src=../../dist/littlejs.js?196></script>
9
+ <script src=game.js?196></script>
@@ -6,7 +6,7 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- LittleJS Engine -->
9
- <script src=../../dist/littlejs.js?192></script>
9
+ <script src=../../dist/littlejs.js?196></script>
10
10
 
11
11
  <!-- Add your game scripts here -->
12
- <script src=game.js?192></script>
12
+ <script src=game.js?196></script>
@@ -95,6 +95,7 @@ function htmlBuildStep(filename)
95
95
 
96
96
  // create html file
97
97
  let buffer = '';
98
+ buffer += '<body>';
98
99
  buffer += '<script>';
99
100
  buffer += fs.readFileSync(filename);
100
101
  buffer += '</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?192></script>
5
- <script src=../../src/engineUtilities.js?192></script>
6
- <script src=../../src/engineSettings.js?192></script>
7
- <script src=../../src/engineObject.js?192></script>
8
- <script src=../../src/engineDraw.js?192></script>
9
- <script src=../../src/engineInput.js?192></script>
10
- <script src=../../src/engineAudio.js?192></script>
11
- <script src=../../src/engineTileLayer.js?192></script>
12
- <script src=../../src/engineParticles.js?192></script>
13
- <script src=../../src/engineMedals.js?192></script>
14
- <script src=../../src/engineWebGL.js?192></script>
15
- <script src=../../src/engine.js?192></script>
4
+ <script src=../../src/engineDebug.js?196></script>
5
+ <script src=../../src/engineUtilities.js?196></script>
6
+ <script src=../../src/engineSettings.js?196></script>
7
+ <script src=../../src/engineObject.js?196></script>
8
+ <script src=../../src/engineDraw.js?196></script>
9
+ <script src=../../src/engineInput.js?196></script>
10
+ <script src=../../src/engineAudio.js?196></script>
11
+ <script src=../../src/engineTileLayer.js?196></script>
12
+ <script src=../../src/engineParticles.js?196></script>
13
+ <script src=../../src/engineMedals.js?196></script>
14
+ <script src=../../src/engineWebGL.js?196></script>
15
+ <script src=../../src/engine.js?196></script>
16
16
 
17
17
  <!-- Add your game scripts here -->
18
- <script src=game.js?192></script>
18
+ <script src=game.js?196></script>
@@ -6,4 +6,4 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- Add your game scripts here -->
9
- <script src=game.js?192 type=module></script>
9
+ <script src=game.js?196 type=module></script>
@@ -9,7 +9,7 @@ button { margin:1px; }
9
9
  </style>
10
10
  </head><body>
11
11
 
12
- <script src=../../dist/littlejs.js?192></script>
12
+ <script src=../../dist/littlejs.js?196></script>
13
13
  <script>
14
14
 
15
15
  'use strict';
@@ -6,11 +6,11 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../dist/littlejs.js?192></script>
10
- <script src=gameObjects.js?192></script>
11
- <script src=gameCharacter.js?192></script>
12
- <script src=gamePlayer.js?192></script>
13
- <script src=gameEffects.js?192></script>
14
- <script src=gameLevel.js?192></script>
15
- <script src=gameLevelData.js?192></script>
16
- <script src=game.js?192></script>
9
+ <script src=../../dist/littlejs.js?196></script>
10
+ <script src=gameObjects.js?196></script>
11
+ <script src=gameCharacter.js?196></script>
12
+ <script src=gamePlayer.js?196></script>
13
+ <script src=gameEffects.js?196></script>
14
+ <script src=gameLevel.js?196></script>
15
+ <script src=gameLevelData.js?196></script>
16
+ <script src=game.js?196></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=../../dist/littlejs.js?192></script>
9
- <script src=game.js?192></script>
8
+ <script src=../../dist/littlejs.js?196></script>
9
+ <script src=game.js?196></script>
@@ -6,18 +6,18 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- LittleJS Engine -->
9
- <script src=../../src/engineDebug.js?192></script>
10
- <script src=../../src/engineUtilities.js?192></script>
11
- <script src=../../src/engineSettings.js?192></script>
12
- <script src=../../src/engineObject.js?192></script>
13
- <script src=../../src/engineDraw.js?192></script>
14
- <script src=../../src/engineInput.js?192></script>
15
- <script src=../../src/engineAudio.js?192></script>
16
- <script src=../../src/engineTileLayer.js?192></script>
17
- <script src=../../src/engineParticles.js?192></script>
18
- <script src=../../src/engineMedals.js?192></script>
19
- <script src=../../src/engineWebGL.js?192></script>
20
- <script src=../../src/engine.js?192></script>
9
+ <script src=../../src/engineDebug.js?196></script>
10
+ <script src=../../src/engineUtilities.js?196></script>
11
+ <script src=../../src/engineSettings.js?196></script>
12
+ <script src=../../src/engineObject.js?196></script>
13
+ <script src=../../src/engineDraw.js?196></script>
14
+ <script src=../../src/engineInput.js?196></script>
15
+ <script src=../../src/engineAudio.js?196></script>
16
+ <script src=../../src/engineTileLayer.js?196></script>
17
+ <script src=../../src/engineParticles.js?196></script>
18
+ <script src=../../src/engineMedals.js?196></script>
19
+ <script src=../../src/engineWebGL.js?196></script>
20
+ <script src=../../src/engine.js?196></script>
21
21
 
22
22
  <!-- Add your game scripts here -->
23
- <script src=game.js?192></script>
23
+ <script src=game.js?196></script>
@@ -6,7 +6,7 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- LittleJS Engine -->
9
- <script src=../../dist/littlejs.min.js?192></script>
9
+ <script src=../../dist/littlejs.min.js?196></script>
10
10
  <script>
11
11
 
12
12
  /*
@@ -6,4 +6,4 @@
6
6
  </head><body>
7
7
 
8
8
  <!-- Add your game scripts here -->
9
- <script src=game.js?192 type=module></script>
9
+ <script src=game.js?196 type=module></script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.9.5",
3
+ "version": "1.9.6",
4
4
  "description": "LittleJS - Tiny and Fast HTML5 Game Engine",
5
5
  "main": "dist/littlejs.esm.js",
6
6
  "types": "dist/littlejs.d.ts",
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.9.5';
33
+ const engineVersion = '1.9.6';
34
34
 
35
35
  /** Frames per second to update
36
36
  * @type {Number}
@@ -107,7 +107,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
107
107
  mainContext.imageSmoothingEnabled = !canvasPixelated;
108
108
 
109
109
  // setup gl rendering if enabled
110
- glEnable && glPreRender();
110
+ glPreRender();
111
111
  }
112
112
 
113
113
  // internal update loop for engine
@@ -126,11 +126,14 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
126
126
  frameTimeBufferMS += paused ? 0 : frameTimeDeltaMS;
127
127
  if (!debugSpeedUp)
128
128
  frameTimeBufferMS = min(frameTimeBufferMS, 50); // clamp in case of slow framerate
129
+
129
130
  updateCanvas();
130
131
 
131
132
  if (paused)
132
133
  {
133
- // do post update even when paused
134
+ // update object transforms even when paused
135
+ for (const o of engineObjects)
136
+ o.parent || o.updateTransforms();
134
137
  inputUpdate();
135
138
  debugUpdate();
136
139
  gameUpdatePost();
@@ -142,7 +145,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
142
145
  let deltaSmooth = 0;
143
146
  if (frameTimeBufferMS < 0 && frameTimeBufferMS > -9)
144
147
  {
145
- // force an update each frame if time is close enough (not just a fast refresh rate)
148
+ // force at least one update each frame since it is waiting for refresh
146
149
  deltaSmooth = frameTimeBufferMS;
147
150
  frameTimeBufferMS = 0;
148
151
  }
@@ -167,34 +170,37 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
167
170
  // add the time smoothing back in
168
171
  frameTimeBufferMS += deltaSmooth;
169
172
  }
170
-
171
- // render sort then render while removing destroyed objects
172
- enginePreRender();
173
- gameRender();
174
- engineObjects.sort((a,b)=> a.renderOrder - b.renderOrder);
175
- for (const o of engineObjects)
176
- o.destroyed || o.render();
177
- gameRenderPost();
178
- glRenderPostProcess();
179
- medalsRender();
180
- touchGamepadRender();
181
- debugRender();
182
- glEnable && glCopyToContext(mainContext);
183
-
184
- if (showWatermark)
173
+
174
+ if (!headlessMode)
185
175
  {
186
- // update fps
187
- overlayContext.textAlign = 'right';
188
- overlayContext.textBaseline = 'top';
189
- overlayContext.font = '1em monospace';
190
- overlayContext.fillStyle = '#000';
191
- const text = engineName + ' ' + 'v' + engineVersion + ' / '
192
- + drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
193
- + (glEnable ? ' GL' : ' 2D') ;
194
- overlayContext.fillText(text, mainCanvas.width-3, 3);
195
- overlayContext.fillStyle = '#fff';
196
- overlayContext.fillText(text, mainCanvas.width-2, 2);
197
- drawCount = 0;
176
+ // render sort then render while removing destroyed objects
177
+ enginePreRender();
178
+ gameRender();
179
+ engineObjects.sort((a,b)=> a.renderOrder - b.renderOrder);
180
+ for (const o of engineObjects)
181
+ o.destroyed || o.render();
182
+ gameRenderPost();
183
+ glRenderPostProcess();
184
+ medalsRender();
185
+ touchGamepadRender();
186
+ debugRender();
187
+ glCopyToContext(mainContext);
188
+
189
+ if (showWatermark)
190
+ {
191
+ // update fps
192
+ overlayContext.textAlign = 'right';
193
+ overlayContext.textBaseline = 'top';
194
+ overlayContext.font = '1em monospace';
195
+ overlayContext.fillStyle = '#000';
196
+ const text = engineName + ' ' + 'v' + engineVersion + ' / '
197
+ + drawCount + ' / ' + engineObjects.length + ' / ' + averageFPS.toFixed(1)
198
+ + (glEnable ? ' GL' : ' 2D') ;
199
+ overlayContext.fillText(text, mainCanvas.width-3, 3);
200
+ overlayContext.fillStyle = '#fff';
201
+ overlayContext.fillText(text, mainCanvas.width-2, 2);
202
+ drawCount = 0;
203
+ }
198
204
  }
199
205
 
200
206
  requestAnimationFrame(engineUpdate);
@@ -202,6 +208,8 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
202
208
 
203
209
  function updateCanvas()
204
210
  {
211
+ if (headlessMode) return;
212
+
205
213
  if (canvasFixedSize.x)
206
214
  {
207
215
  // clear canvas and set fixed size
@@ -229,8 +237,20 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
229
237
  mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
230
238
  }
231
239
 
240
+ function startEngine()
241
+ {
242
+ gameInit();
243
+ engineUpdate();
244
+ }
245
+
246
+ if (headlessMode)
247
+ {
248
+ startEngine();
249
+ return;
250
+ }
251
+
232
252
  // setup html
233
- const styleBody =
253
+ const styleBody =
234
254
  'margin:0;overflow:hidden;' + // fill the window
235
255
  'background:#000;' + // set background color
236
256
  'touch-action:none;' + // prevent mobile pinch to resize
@@ -242,8 +262,9 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
242
262
  mainContext = mainCanvas.getContext('2d');
243
263
 
244
264
  // init stuff and start engine
265
+ inputInit();
245
266
  debugInit();
246
- glEnable && glInit();
267
+ glInit();
247
268
 
248
269
  // create overlay canvas for hud to appear above gl canvas
249
270
  document.body.appendChild(overlayCanvas = document.createElement('canvas'));
@@ -284,12 +305,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
284
305
  }));
285
306
 
286
307
  // load all of the images
287
- Promise.all(promises).then(()=>
288
- {
289
- // start the engine
290
- gameInit();
291
- engineUpdate();
292
- });
308
+ Promise.all(promises).then(startEngine);
293
309
  }
294
310
 
295
311
  /** Update each engine object, remove destroyed objects, and update time
@@ -310,7 +326,14 @@ function engineObjectsUpdate()
310
326
  }
311
327
  }
312
328
  for (const o of engineObjects)
313
- o.parent || updateObject(o);
329
+ {
330
+ // update top level objects
331
+ if (!o.parent)
332
+ {
333
+ updateObject(o);
334
+ o.updateTransforms();
335
+ }
336
+ }
314
337
 
315
338
  // remove destroyed objects
316
339
  engineObjects = engineObjects.filter(o=>!o.destroyed);
@@ -31,7 +31,7 @@ class Sound
31
31
  */
32
32
  constructor(zzfxSound, range=soundDefaultRange, taper=soundDefaultTaper)
33
33
  {
34
- if (!soundEnable) return;
34
+ if (!soundEnable || headlessMode) return;
35
35
 
36
36
  /** @property {Number} - World space max range of sound, will not play if camera is farther away */
37
37
  this.range = range;
@@ -45,8 +45,8 @@ class Sound
45
45
  if (zzfxSound)
46
46
  {
47
47
  // generate zzfx sound now for fast playback
48
- this.randomness = zzfxSound[1] || 0;
49
- zzfxSound[1] = 0; // generate without randomness
48
+ const defaultRandomness = .05;
49
+ this.randomness = zzfxSound[1] || defaultRandomness;
50
50
  this.sampleChannels = [zzfxG(...zzfxSound)];
51
51
  this.sampleRate = zzfxR;
52
52
  }
@@ -62,7 +62,7 @@ class Sound
62
62
  */
63
63
  play(pos, volume=1, pitch=1, randomnessScale=1, loop=false)
64
64
  {
65
- if (!soundEnable || !this.sampleChannels) return;
65
+ if (!soundEnable || !this.sampleChannels || headlessMode) return;
66
66
 
67
67
  let pan;
68
68
  if (pos)
@@ -145,7 +145,9 @@ class SoundWave extends Sound
145
145
  super(undefined, range, taper);
146
146
  this.randomness = randomness;
147
147
 
148
- if (!soundEnable) return;
148
+ if (!soundEnable || headlessMode) return;
149
+ if (!audioContext)
150
+ audioContext = new AudioContext; // create audio context
149
151
 
150
152
  fetch(filename)
151
153
  .then(response => response.arrayBuffer())
@@ -199,7 +201,7 @@ class Music extends Sound
199
201
  {
200
202
  super(undefined);
201
203
 
202
- if (!soundEnable) return;
204
+ if (!soundEnable || headlessMode) return;
203
205
  this.randomness = 0;
204
206
  this.sampleChannels = zzfxM(...zzfxMusic);
205
207
  this.sampleRate = zzfxR;
@@ -222,7 +224,7 @@ class Music extends Sound
222
224
  * @memberof Audio */
223
225
  function playAudioFile(filename, volume=1, loop=false)
224
226
  {
225
- if (!soundEnable) return;
227
+ if (!soundEnable || headlessMode) return;
226
228
 
227
229
  const audio = new Audio(filename);
228
230
  audio.volume = soundVolume * volume;
@@ -241,7 +243,7 @@ function playAudioFile(filename, volume=1, loop=false)
241
243
  * @memberof Audio */
242
244
  function speak(text, language='', volume=1, rate=1, pitch=1)
243
245
  {
244
- if (!soundEnable || !speechSynthesis) return;
246
+ if (!soundEnable || !speechSynthesis || headlessMode) return;
245
247
 
246
248
  // common languages (not supported by all browsers)
247
249
  // en - english, it - italian, fr - french, de - german, es - spanish
@@ -274,7 +276,7 @@ function getNoteFrequency(semitoneOffset, rootFrequency=220)
274
276
  /** Audio context used by the engine
275
277
  * @type {AudioContext}
276
278
  * @memberof Audio */
277
- let audioContext = new AudioContext;
279
+ let audioContext;
278
280
 
279
281
  /** Keep track if audio was suspended when last sound was played
280
282
  * @type {Boolean}
@@ -292,7 +294,9 @@ let audioSuspended = false;
292
294
  * @memberof Audio */
293
295
  function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=false, sampleRate=zzfxR)
294
296
  {
295
- if (!soundEnable) return;
297
+ if (!soundEnable || headlessMode) return;
298
+ if (!audioContext)
299
+ audioContext = new AudioContext; // create audio context
296
300
 
297
301
  // prevent sounds from building up if they can't be played
298
302
  const audioWasSuspended = audioSuspended;
@@ -338,7 +342,7 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=false, sample
338
342
  * @param {Array} zzfxSound - Array of ZzFX parameters, ex. [.5,.5]
339
343
  * @return {AudioBufferSourceNode} - The audio node of the sound played
340
344
  * @memberof Audio */
341
- function zzfx(...zzfxSound) { return playSamples([zzfxG(...zzfxSound)]); }
345
+ function zzfx(...zzfxSound) { return new Sound(zzfxSound).play(); }
342
346
 
343
347
  /** Sample rate used for all ZzFX sounds
344
348
  * @default 44100
@@ -347,7 +351,7 @@ const zzfxR = 44100;
347
351
 
348
352
  /** Generate samples for a ZzFX sound
349
353
  * @param {Number} [volume] - Volume scale (percent)
350
- * @param {Number} [randomness] - How much to randomize frequency (percent Hz)
354
+ * @param {Number} [randomness] - Unused in this fuction, handled by Sound class
351
355
  * @param {Number} [frequency] - Frequency of sound (Hz)
352
356
  * @param {Number} [attack] - Attack time, how fast sound starts (seconds)
353
357
  * @param {Number} [sustain] - Sustain time, how long sound holds (seconds)
@@ -373,17 +377,18 @@ const zzfxR = 44100;
373
377
  function zzfxG
374
378
  (
375
379
  // parameters
376
- volume = 1, randomness = .05, frequency = 220, attack = 0, sustain = 0,
380
+ volume = 1, randomness = 0, frequency = 220, attack = 0, sustain = 0,
377
381
  release = .1, shape = 0, shapeCurve = 1, slide = 0, deltaSlide = 0,
378
382
  pitchJump = 0, pitchJumpTime = 0, repeatTime = 0, noise = 0, modulation = 0,
379
383
  bitCrush = 0, delay = 0, sustainVolume = 1, decay = 0, tremolo = 0, filter = 0
380
384
  )
381
385
  {
386
+ // LJS Note: ZZFX modded so randomness is handled by Sound class
387
+
382
388
  // init parameters
383
389
  let PI2 = PI*2, sampleRate = zzfxR,
384
390
  startSlide = slide *= 500 * PI2 / sampleRate / sampleRate,
385
- startFrequency = frequency *=
386
- rand(1 + randomness, 1-randomness) * PI2 / sampleRate,
391
+ startFrequency = frequency *= PI2 / sampleRate,
387
392
  b = [], t = 0, tm = 0, i = 0, j = 1, r = 0, c = 0, s = 0, f, length,
388
393
 
389
394
  // biquad LP/HP filter
@@ -405,7 +410,6 @@ function zzfxG
405
410
  pitchJump *= PI2 / sampleRate;
406
411
  pitchJumpTime *= sampleRate;
407
412
  repeatTime = repeatTime * sampleRate | 0;
408
- volume *= soundVolume;
409
413
 
410
414
  // generate waveform
411
415
  for(length = attack + decay + sustain + release + delay | 0;
@@ -149,7 +149,7 @@ function debugClear() { debugPrimitives = []; }
149
149
  * @param {String} [filename]
150
150
  * @param {String} [type]
151
151
  * @memberof Debug */
152
- function debugSaveCanvas(canvas, filename=engineName, type='image/png')
152
+ function debugSaveCanvas(canvas, filename='screenshot', type='image/png')
153
153
  { debugSaveDataURL(canvas.toDataURL(type), filename); }
154
154
 
155
155
  /** Save a text file to disk
@@ -157,7 +157,7 @@ function debugSaveCanvas(canvas, filename=engineName, type='image/png')
157
157
  * @param {String} [filename]
158
158
  * @param {String} [type]
159
159
  * @memberof Debug */
160
- function debugSaveText(text, filename=engineName, type='text/plain')
160
+ function debugSaveText(text, filename='text', type='text/plain')
161
161
  { debugSaveDataURL(URL.createObjectURL(new Blob([text], {'type':type})), filename); }
162
162
 
163
163
  /** Save a data url to disk
@@ -177,8 +177,7 @@ function debugSaveDataURL(dataURL, filename)
177
177
  function debugInit()
178
178
  {
179
179
  // create link for saving screenshots
180
- document.body.appendChild(downloadLink = document.createElement('a'));
181
- downloadLink.style.display = 'none';
180
+ downloadLink = document.createElement('a');
182
181
  }
183
182
 
184
183
  function debugUpdate()
package/src/engineDraw.js CHANGED
@@ -74,6 +74,9 @@ let drawCount;
74
74
  */
75
75
  function tile(pos=vec2(), size=tileSizeDefault, textureIndex=0)
76
76
  {
77
+ if (headlessMode)
78
+ return new TileInfo;
79
+
77
80
  // if size is a number, make it a vector
78
81
  if (typeof size === 'number')
79
82
  {
@@ -107,9 +110,9 @@ class TileInfo
107
110
  constructor(pos=vec2(), size=tileSizeDefault, textureIndex=0)
108
111
  {
109
112
  /** @property {Vector2} - Top left corner of tile in pixels */
110
- this.pos = pos;
113
+ this.pos = pos.copy();
111
114
  /** @property {Vector2} - Size of tile in pixels */
112
- this.size = size;
115
+ this.size = size.copy();
113
116
  /** @property {Number} - Texture index to use */
114
117
  this.textureIndex = textureIndex;
115
118
  }
@@ -201,7 +204,7 @@ function getCameraSize() { return mainCanvasSize.scale(1/cameraScale); }
201
204
  * @param {Color} [additiveColor=(0,0,0,0)] - Additive color to be applied
202
205
  * @param {Boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering
203
206
  * @param {Boolean} [screenSpace=false] - If true the pos and size are in screen space
204
- * @param {CanvasRenderingContext2D} [context] - Canvas 2D context to draw to
207
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context] - Canvas 2D context to draw to
205
208
  * @memberof Draw */
206
209
  function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
207
210
  angle=0, mirror, additiveColor=new Color(0,0,0,0), useWebGL=glEnable, screenSpace, context)
@@ -274,7 +277,7 @@ function drawTile(pos, size=vec2(1), tileInfo, color=new Color,
274
277
  * @param {Number} [angle]
275
278
  * @param {Boolean} [useWebGL=glEnable]
276
279
  * @param {Boolean} [screenSpace=false]
277
- * @param {CanvasRenderingContext2D} [context]
280
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
278
281
  * @memberof Draw */
279
282
  function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
280
283
  {
@@ -288,7 +291,7 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
288
291
  * @param {Color} [color=(1,1,1,1)]
289
292
  * @param {Boolean} [useWebGL=glEnable]
290
293
  * @param {Boolean} [screenSpace=false]
291
- * @param {CanvasRenderingContext2D} [context]
294
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
292
295
  * @memberof Draw */
293
296
  function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
294
297
  {
@@ -304,7 +307,7 @@ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, contex
304
307
  * @param {Boolean} mirror
305
308
  * @param {Function} drawFunction
306
309
  * @param {Boolean} [screenSpace=false]
307
- * @param {CanvasRenderingContext2D} [context=mainContext]
310
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
308
311
  * @memberof Draw */
309
312
  function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, context=mainContext)
310
313
  {
@@ -325,7 +328,7 @@ function drawCanvas2D(pos, size, angle, mirror, drawFunction, screenSpace, conte
325
328
  /** Enable normal or additive blend mode
326
329
  * @param {Boolean} [additive]
327
330
  * @param {Boolean} [useWebGL=glEnable]
328
- * @param {CanvasRenderingContext2D} [context=mainContext]
331
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=mainContext]
329
332
  * @memberof Draw */
330
333
  function setBlendMode(additive, useWebGL=glEnable, context)
331
334
  {
@@ -350,7 +353,7 @@ function setBlendMode(additive, useWebGL=glEnable, context)
350
353
  * @param {Color} [lineColor=(0,0,0,1)]
351
354
  * @param {CanvasTextAlign} [textAlign='center']
352
355
  * @param {String} [font=fontDefault]
353
- * @param {CanvasRenderingContext2D} [context=overlayContext]
356
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=overlayContext]
354
357
  * @memberof Draw */
355
358
  function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, font, context)
356
359
  {
@@ -367,7 +370,7 @@ function drawText(text, pos, size=1, color, lineWidth=0, lineColor, textAlign, f
367
370
  * @param {Color} [lineColor=(0,0,0,1)]
368
371
  * @param {CanvasTextAlign} [textAlign]
369
372
  * @param {String} [font=fontDefault]
370
- * @param {CanvasRenderingContext2D} [context=overlayContext]
373
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=overlayContext]
371
374
  * @memberof Draw */
372
375
  function drawTextScreen(text, pos, size=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), textAlign='center', font=fontDefault, context=overlayContext)
373
376
  {
@@ -410,7 +413,7 @@ class FontImage
410
413
  * @param {HTMLImageElement} [image] - Image for the font, if undefined default font is used
411
414
  * @param {Vector2} [tileSize=(8,8)] - Size of the font source tiles
412
415
  * @param {Vector2} [paddingSize=(0,1)] - How much extra space to add between characters
413
- * @param {CanvasRenderingContext2D} [context=overlayContext] - context to draw to
416
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=overlayContext] - context to draw to
414
417
  */
415
418
  constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1), context=overlayContext)
416
419
  {
@@ -45,6 +45,7 @@ export {
45
45
  canvasPixelated,
46
46
  fontDefault,
47
47
  showSplashScreen,
48
+ headlessMode,
48
49
  tileSizeDefault,
49
50
  tileFixBleedScale,
50
51
  enablePhysicsSolver,
@@ -83,6 +84,7 @@ export {
83
84
  setCanvasPixelated,
84
85
  setFontDefault,
85
86
  setShowSplashScreen,
87
+ setHeadlessMode,
86
88
  setGlEnable,
87
89
  setGlOverlay,
88
90
  setTileSizeDefault,