littlejsengine 1.10.2 → 1.10.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 (42) hide show
  1. package/README.md +7 -15
  2. package/dist/littlejs.d.ts +49 -1
  3. package/dist/littlejs.esm.js +60 -37
  4. package/dist/littlejs.esm.min.js +1 -1
  5. package/dist/littlejs.js +46 -37
  6. package/dist/littlejs.min.js +1 -1
  7. package/dist/littlejs.release.js +46 -37
  8. package/examples/box2d/game.js +3 -0
  9. package/examples/breakoutTutorial/README.md +9 -7
  10. package/examples/breakoutTutorial/game.js +6 -6
  11. package/examples/js13k/build/index.html +1 -0
  12. package/examples/js13k/build/index.js +1 -0
  13. package/examples/js13k/build/tiles.png +0 -0
  14. package/examples/js13k/game - Copy.zip +0 -0
  15. package/examples/js13k/game.zip +0 -0
  16. package/examples/platformer/game.js +6 -4
  17. package/examples/platformer/gameCharacter.js +12 -11
  18. package/examples/platformer/gameEffects.js +3 -4
  19. package/examples/platformer/gameLevel.js +17 -33
  20. package/examples/platformer/gameObjects.js +9 -14
  21. package/examples/starter/build/index.html +2 -0
  22. package/examples/starter/build/index.js +1 -0
  23. package/examples/starter/build/tiles.png +0 -0
  24. package/examples/starter/game.zip +0 -0
  25. package/examples/typescript/build/build/littlejs.esm.js +4327 -0
  26. package/examples/typescript/build/dist/littlejs.esm.js +4425 -0
  27. package/examples/typescript/build/examples/typescript/build.js +24 -0
  28. package/examples/typescript/build/examples/typescript/game.js +100 -0
  29. package/examples/typescript/build/examples/typescript/test/build/littlejs.esm.js +3934 -0
  30. package/examples/typescript/build/examples/typescript/test/examples/typescript/build.js +86 -0
  31. package/examples/typescript/build/examples/typescript/test/examples/typescript/game.js +92 -0
  32. package/examples/typescript/game.ts +1 -1
  33. package/package.json +1 -1
  34. package/plugins/postProcess.js +8 -1
  35. package/src/engine.js +5 -13
  36. package/src/engineDraw.js +19 -18
  37. package/src/engineExport.js +14 -0
  38. package/src/engineInput.js +1 -3
  39. package/src/engineObject.js +1 -0
  40. package/src/engineTileLayer.js +2 -1
  41. package/src/engineUtilities.js +1 -0
  42. package/src/engineWebGL.js +17 -2
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * LittleJS Build System
4
+ * - Combine input files
5
+ * - Run custom build steps
6
+ * - Check for errors
7
+ * - Output to build folder
8
+ * @namespace Build
9
+ */
10
+ const PROGRAM_NAME = 'game';
11
+ const BUILD_FOLDER = 'build';
12
+ const sourceFiles = [
13
+ '../../build/littlejs.release.js',
14
+ 'game.js',
15
+ // add your game's files here
16
+ ];
17
+ const dataFiles = [
18
+ 'tiles.png',
19
+ // add your game's data files here
20
+ ];
21
+ console.log(`Building ${PROGRAM_NAME}...`);
22
+ const startTime = Date.now();
23
+ const fs = require('node:fs');
24
+ const child_process = require('node:child_process');
25
+ // rebuild engine
26
+ child_process.execSync(`npm run build`, { stdio: 'inherit' });
27
+ console.log('');
28
+ // remove old files and setup build folder
29
+ fs.rmSync(BUILD_FOLDER, { recursive: true, force: true });
30
+ fs.rmSync(`${PROGRAM_NAME}.zip`, { force: true });
31
+ fs.mkdirSync(BUILD_FOLDER);
32
+ // copy data files
33
+ for (const file of dataFiles)
34
+ fs.copyFileSync(file, `${BUILD_FOLDER}/${file}`);
35
+ Build(`${BUILD_FOLDER}/index.js`, sourceFiles, [closureCompilerStep, uglifyBuildStep, roadrollerBuildStep, htmlBuildStep, zipBuildStep]);
36
+ console.log(`Build Completed in ${((Date.now() - startTime) / 1e3).toFixed(2)} seconds!`);
37
+ ///////////////////////////////////////////////////////////////////////////////
38
+ // A single build with its own source files, build steps, and output file
39
+ // - each build step is a callback that accepts a single filename
40
+ function Build(outputFile, files = [], buildSteps = []) {
41
+ // copy files into a buffer
42
+ let buffer = '';
43
+ for (const file of files)
44
+ buffer += fs.readFileSync(file) + '\n';
45
+ // output file
46
+ fs.writeFileSync(outputFile, buffer, { flag: 'w+' });
47
+ // execute build steps in order
48
+ for (const buildStep of buildSteps)
49
+ buildStep(outputFile);
50
+ }
51
+ function closureCompilerStep(filename) {
52
+ console.log(`Running closure compiler...`);
53
+ const filenameTemp = filename + '.tmp';
54
+ fs.copyFileSync(filename, filenameTemp);
55
+ child_process.execSync(`npx google-closure-compiler --js=${filenameTemp} --js_output_file=${filename} --compilation_level=ADVANCED --language_out=ECMASCRIPT_2021 --warning_level=VERBOSE --jscomp_off=* --assume_function_wrapper`, { stdio: 'inherit' });
56
+ fs.rmSync(filenameTemp);
57
+ }
58
+ ;
59
+ function uglifyBuildStep(filename) {
60
+ console.log(`Running uglify...`);
61
+ child_process.execSync(`npx uglifyjs ${filename} -c -m -o ${filename}`, { stdio: 'inherit' });
62
+ }
63
+ ;
64
+ function roadrollerBuildStep(filename) {
65
+ console.log(`Running roadroller...`);
66
+ child_process.execSync(`npx roadroller ${filename} -o ${filename}`, { stdio: 'inherit' });
67
+ }
68
+ ;
69
+ function htmlBuildStep(filename) {
70
+ console.log(`Building html...`);
71
+ // copy files into a buffer
72
+ let buffer = '';
73
+ buffer += '<script>';
74
+ buffer += fs.readFileSync(filename) + '\n';
75
+ buffer += '</script>';
76
+ // output html file
77
+ fs.writeFileSync(`${BUILD_FOLDER}/index.html`, buffer, { flag: 'w+' });
78
+ }
79
+ ;
80
+ function zipBuildStep(filename) {
81
+ console.log(`Zipping...`);
82
+ const ect = '../../../node_modules/ect-bin/vendor/win32/ect.exe';
83
+ const args = ['-9', '-strip', '-zip', `../${PROGRAM_NAME}.zip`, 'index.html', ...dataFiles];
84
+ child_process.spawnSync(ect, args, { stdio: 'inherit', cwd: BUILD_FOLDER });
85
+ }
86
+ ;
@@ -0,0 +1,92 @@
1
+ /*
2
+ LittleJS Hello World Starter Game
3
+ */
4
+ 'use strict';
5
+ // import module
6
+ import * as LittleJS from '../../build/littlejs.esm.js';
7
+ const { Vector2, Color, Timer, vec2 } = LittleJS;
8
+ // sound effects
9
+ const sound_click = new LittleJS.Sound([1, .5]);
10
+ // medals
11
+ const medal_example = new LittleJS.Medal(0, 'Example Medal', 'Welcome to LittleJS!');
12
+ LittleJS.medalsInit('Hello World');
13
+ // game variables
14
+ let particleEmitter;
15
+ let gameTimer = new Timer;
16
+ ///////////////////////////////////////////////////////////////////////////////
17
+ function gameInit() {
18
+ // create tile collision and visible tile layer
19
+ LittleJS.initTileCollision(vec2(32, 16));
20
+ const pos = new Vector2;
21
+ const tileLayer = new LittleJS.TileLayer(pos, LittleJS.tileCollisionSize);
22
+ // get level data from the tiles image
23
+ const imageLevelDataRow = 1;
24
+ const mainContext = LittleJS.mainContext;
25
+ mainContext.drawImage(LittleJS.tileImage, 0, 0);
26
+ for (pos.x = LittleJS.tileCollisionSize.x; pos.x--;)
27
+ for (pos.y = LittleJS.tileCollisionSize.y; pos.y--;) {
28
+ const imageData = mainContext.getImageData(pos.x, 16 * (imageLevelDataRow + 1) - pos.y - 1, 1, 1).data;
29
+ if (imageData[0]) {
30
+ const tileIndex = 1;
31
+ const direction = LittleJS.randInt(4);
32
+ const mirror = LittleJS.randInt(2) ? true : false;
33
+ const color = LittleJS.randColor();
34
+ const data = new LittleJS.TileLayerData(tileIndex, direction, mirror, color);
35
+ tileLayer.setData(pos, data);
36
+ LittleJS.setTileCollisionData(pos, 1);
37
+ }
38
+ }
39
+ tileLayer.redraw();
40
+ // move camera to center of collision
41
+ LittleJS.setCameraPos(LittleJS.tileCollisionSize.scale(.5));
42
+ // enable gravity
43
+ LittleJS.setGravity(-.01);
44
+ // create particle emitter
45
+ const center = LittleJS.tileCollisionSize.scale(.5).add(vec2(0, 9));
46
+ particleEmitter = new LittleJS.ParticleEmitter(center, 0, // emitPos, emitAngle
47
+ 1, 0, 500, Math.PI, // emitSize, emitTime, emitRate, emiteCone
48
+ 0, vec2(16), // tileIndex, tileSize
49
+ new Color(1, 1, 1), new Color(0, 0, 0), // colorStartA, colorStartB
50
+ new Color(1, 1, 1, 0), new Color(0, 0, 0, 0), // colorEndA, colorEndB
51
+ 2, .2, .2, .1, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
52
+ .99, 1, 1, Math.PI, // damping, angleDamping, gravityScale, cone
53
+ .05, .5, true, true // fadeRate, randomness, collide, additive
54
+ );
55
+ particleEmitter.elasticity = .3; // bounce when it collides
56
+ particleEmitter.trailScale = 2; // stretch in direction of motion
57
+ // start the game timer
58
+ gameTimer.set();
59
+ }
60
+ ///////////////////////////////////////////////////////////////////////////////
61
+ function gameUpdate() {
62
+ if (LittleJS.mouseWasPressed(0)) {
63
+ // play sound when mouse is pressed
64
+ sound_click.play(LittleJS.mousePos);
65
+ // change particle color and set to fade out
66
+ particleEmitter.colorStartA = new Color;
67
+ particleEmitter.colorStartB = LittleJS.randColor();
68
+ particleEmitter.colorEndA = particleEmitter.colorStartA.scale(1, 0);
69
+ particleEmitter.colorEndB = particleEmitter.colorStartB.scale(1, 0);
70
+ // unlock medals
71
+ medal_example.unlock();
72
+ }
73
+ // move particles to mouse location if on screen
74
+ if (LittleJS.mousePosScreen.x)
75
+ particleEmitter.pos = LittleJS.mousePos;
76
+ }
77
+ ///////////////////////////////////////////////////////////////////////////////
78
+ function gameUpdatePost() {
79
+ }
80
+ ///////////////////////////////////////////////////////////////////////////////
81
+ function gameRender() {
82
+ // draw a grey square in the background without using webgl
83
+ LittleJS.drawRect(LittleJS.cameraPos, LittleJS.tileCollisionSize.add(vec2(5)), new Color(.2, .2, .2), 0, false);
84
+ }
85
+ ///////////////////////////////////////////////////////////////////////////////
86
+ function gameRenderPost() {
87
+ // draw to overlay canvas for hud rendering
88
+ LittleJS.drawTextScreen('LittleJS with TypeScript', vec2(LittleJS.mainCanvasSize.x / 2, 80), 80);
89
+ }
90
+ ///////////////////////////////////////////////////////////////////////////////
91
+ // Startup LittleJS Engine
92
+ LittleJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, 'tiles.png');
@@ -128,4 +128,4 @@ function gameRenderPost()
128
128
 
129
129
  ///////////////////////////////////////////////////////////////////////////////
130
130
  // Startup LittleJS Engine
131
- LittleJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost);
131
+ LittleJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.10.2",
3
+ "version": "1.10.4",
4
4
  "description": "LittleJS - Tiny and Fast HTML5 Game Engine",
5
5
  "main": "dist/littlejs.esm.js",
6
6
  "types": "dist/littlejs.d.ts",
@@ -98,4 +98,11 @@ function initPostProcess(shaderCode, includeOverlay=false)
98
98
  glContext.uniform3f(uniformLocation('iResolution'), mainCanvas.width, mainCanvas.height, 1);
99
99
  glContext.drawArrays(gl_TRIANGLE_STRIP, 0, 4);
100
100
  }
101
- }
101
+ }
102
+
103
+ export {
104
+ initPostProcess,
105
+ glPostShader,
106
+ glPostTexture,
107
+ glPostIncludeOverlay
108
+ };
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.10.2';
33
+ const engineVersion = '1.10.4';
34
34
 
35
35
  /** Frames per second to update
36
36
  * @type {Number}
@@ -74,13 +74,6 @@ let timeReal = 0;
74
74
  * @default false
75
75
  * @memberof Engine */
76
76
  let paused = false;
77
-
78
- /** The root element that engine is attached to
79
- * @type {HTMLElement}
80
- * @default document.body
81
- * @memberof Engine */
82
- let engineRoot;
83
-
84
77
  /** Set if game is paused
85
78
  * @param {Boolean} isPaused
86
79
  * @memberof Engine */
@@ -113,7 +106,7 @@ function engineAddPlugin(updateFunction, renderFunction)
113
106
  * @param {Function} gameUpdatePost - Called after physics and objects are updated, setup camera and prepare for render
114
107
  * @param {Function} gameRender - Called before objects are rendered, draw any background effects that appear behind objects
115
108
  * @param {Function} gameRenderPost - Called after objects are rendered, draw effects or hud that appear above all objects
116
- * @param {Array} [imageSources=['tiles.png']] - Image to load
109
+ * @param {Array} [imageSources=[]] - Image to load
117
110
  * @param {HTMLElement} [rootElement] - Root element to attach to, the document body by default
118
111
  * @memberof Engine */
119
112
  function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
@@ -287,9 +280,8 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
287
280
  (!touchInputEnable ? '' : // no touch css setttings
288
281
  'touch-action:none;' + // prevent mobile pinch to resize
289
282
  '-webkit-touch-callout:none');// compatibility for ios
290
- engineRoot = rootElement;
291
- engineRoot.style.cssText = styleRoot;
292
- engineRoot.appendChild(mainCanvas = document.createElement('canvas'));
283
+ rootElement.style.cssText = styleRoot;
284
+ rootElement.appendChild(mainCanvas = document.createElement('canvas'));
293
285
  mainContext = mainCanvas.getContext('2d');
294
286
 
295
287
  // init stuff and start engine
@@ -299,7 +291,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
299
291
  glInit();
300
292
 
301
293
  // create overlay canvas for hud to appear above gl canvas
302
- engineRoot.appendChild(overlayCanvas = document.createElement('canvas'));
294
+ rootElement.appendChild(overlayCanvas = document.createElement('canvas'));
303
295
  overlayContext = overlayCanvas.getContext('2d');
304
296
 
305
297
  // set canvas style
package/src/engineDraw.js CHANGED
@@ -288,6 +288,22 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
288
288
  drawTile(pos, size, undefined, color, angle, false, undefined, useWebGL, screenSpace, context);
289
289
  }
290
290
 
291
+ /** Draw colored line between two points
292
+ * @param {Vector2} posA
293
+ * @param {Vector2} posB
294
+ * @param {Number} [thickness]
295
+ * @param {Color} [color=(1,1,1,1)]
296
+ * @param {Boolean} [useWebGL=glEnable]
297
+ * @param {Boolean} [screenSpace=false]
298
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
299
+ * @memberof Draw */
300
+ function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
301
+ {
302
+ const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
303
+ const size = vec2(thickness, halfDelta.length()*2);
304
+ drawRect(posA.add(halfDelta), size, color, halfDelta.angle(), useWebGL, screenSpace, context);
305
+ }
306
+
291
307
  /** Draw colored polygon using passed in points
292
308
  * @param {Array} points - Array of Vector2 points
293
309
  * @param {Color} [color=(1,1,1,1)]
@@ -356,22 +372,6 @@ function drawEllipse(pos, width=1, height=1, angle=0, color=new Color, lineWidth
356
372
  function drawCircle(pos, radius=1, color=new Color, lineWidth=0, lineColor=new Color(0,0,0), screenSpace, context=mainContext)
357
373
  { drawEllipse(pos, radius, radius, 0, color, lineWidth, lineColor, screenSpace, context); }
358
374
 
359
- /** Draw colored line between two points
360
- * @param {Vector2} posA
361
- * @param {Vector2} posB
362
- * @param {Number} [thickness]
363
- * @param {Color} [color=(1,1,1,1)]
364
- * @param {Boolean} [useWebGL=glEnable]
365
- * @param {Boolean} [screenSpace=false]
366
- * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
367
- * @memberof Draw */
368
- function drawLine(posA, posB, thickness=.1, color, useWebGL, screenSpace, context)
369
- {
370
- const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
371
- const size = vec2(thickness, halfDelta.length()*2);
372
- drawRect(posA.add(halfDelta), size, color, halfDelta.angle(), useWebGL, screenSpace, context);
373
- }
374
-
375
375
  /** Draw directly to a 2d canvas context in world space
376
376
  * @param {Vector2} pos
377
377
  * @param {Vector2} size
@@ -563,11 +563,12 @@ function isFullscreen() { return !!document.fullscreenElement; }
563
563
  * @memberof Draw */
564
564
  function toggleFullscreen()
565
565
  {
566
+ const rootElement = mainCanvas.parentElement;
566
567
  if (isFullscreen())
567
568
  {
568
569
  if (document.exitFullscreen)
569
570
  document.exitFullscreen();
570
571
  }
571
- else if (engineRoot.requestFullscreen)
572
- engineRoot.requestFullscreen();
572
+ else if (rootElement.requestFullscreen)
573
+ rootElement.requestFullscreen();
573
574
  }
@@ -191,6 +191,9 @@ export {
191
191
  drawTile,
192
192
  drawRect,
193
193
  drawLine,
194
+ drawPoly,
195
+ drawEllipse,
196
+ drawCircle,
194
197
  drawCanvas2D,
195
198
  setBlendMode,
196
199
  drawTextScreen,
@@ -211,6 +214,17 @@ export {
211
214
  glDraw,
212
215
  glFlush,
213
216
  glSetTexture,
217
+ glSetAntialias,
218
+ glAntialias,
219
+ glShader,
220
+ glActiveTexture,
221
+ glArrayBuffer,
222
+ glGeometryBuffer,
223
+ glPositionData,
224
+ glColorData,
225
+ glInstanceCount,
226
+ glAdditive,
227
+ glBatchAdditive,
214
228
 
215
229
  // Input
216
230
  keyIsDown,
@@ -167,7 +167,6 @@ function inputInit()
167
167
 
168
168
  onkeydown = (e)=>
169
169
  {
170
- if (debug && e.target != engineRoot) return;
171
170
  if (!e.repeat)
172
171
  {
173
172
  isUsingGamepad = false;
@@ -180,7 +179,6 @@ function inputInit()
180
179
 
181
180
  onkeyup = (e)=>
182
181
  {
183
- if (debug && e.target != engineRoot) return;
184
182
  inputData[0][e.code] = 4;
185
183
  if (inputWASDEmulateDirection)
186
184
  inputData[0][remapKey(e.code)] = 4;
@@ -382,7 +380,7 @@ function touchInputInit()
382
380
  // set event pos and pass it along
383
381
  const p = vec2(e.touches[0].clientX, e.touches[0].clientY);
384
382
  mousePosScreen = mouseToScreen(p);
385
- wasTouching ? isUsingGamepad = false : inputData[0][button] = 3;
383
+ wasTouching ? isUsingGamepad = touchGamepadEnable : inputData[0][button] = 3;
386
384
  }
387
385
  else if (wasTouching)
388
386
  inputData[0][button] = inputData[0][button] & 2 | 4;
@@ -307,6 +307,7 @@ class EngineObject
307
307
  this.pos.x = oldPos.x;
308
308
  this.velocity.x *= -this.elasticity;
309
309
  }
310
+ debugOverlay && debugPhysics && debugRect(this.pos, this.size, '#f00');
310
311
  }
311
312
  }
312
313
  }
@@ -70,6 +70,7 @@ function tileCollisionTest(pos, size=vec2(), object)
70
70
  if (tileData && (!object || object.collideWithTile(tileData, vec2(x, y))))
71
71
  return true;
72
72
  }
73
+ return false;
73
74
  }
74
75
 
75
76
  /** Return the center of first tile hit (does not return the exact intersection)
@@ -93,7 +94,7 @@ function tileCollisionRaycast(posStart, posEnd, object)
93
94
  let xi = unit.x * (delta.x < 0 ? posStart.x - pos.x : pos.x - posStart.x + 1);
94
95
  let yi = unit.y * (delta.y < 0 ? posStart.y - pos.y : pos.y - posStart.y + 1);
95
96
 
96
- while (1)
97
+ while (true)
97
98
  {
98
99
  // check for tile collision
99
100
  const tileData = getTileCollisionData(pos);
@@ -483,6 +483,7 @@ class Vector2
483
483
  * @param {Number} [length] */
484
484
  setDirection(direction, length=1)
485
485
  {
486
+ direction = mod(direction, 4);
486
487
  ASSERT(direction==0 || direction==1 || direction==2 || direction==3);
487
488
  return vec2(direction%2 ? direction-1 ? -length : length : 0,
488
489
  direction%2 ? 0 : direction ? -length : length);
@@ -22,6 +22,11 @@ let glCanvas;
22
22
  * @memberof WebGL */
23
23
  let glContext;
24
24
 
25
+ /** Shoule webgl be setup with antialiasing, must be set before calling engineInit
26
+ * @type {Boolean}
27
+ * @memberof WebGL */
28
+ let glAntialias = true;
29
+
25
30
  // WebGL internal variables not exposed to documentation
26
31
  let glShader, glActiveTexture, glArrayBuffer, glGeometryBuffer, glPositionData, glColorData, glInstanceCount, glAdditive, glBatchAdditive;
27
32
 
@@ -34,10 +39,11 @@ function glInit()
34
39
 
35
40
  // create the canvas and textures
36
41
  glCanvas = document.createElement('canvas');
37
- glContext = glCanvas.getContext('webgl2', {antialias:!canvasPixelated});
42
+ glContext = glCanvas.getContext('webgl2', {antialias:glAntialias});
38
43
 
39
44
  // some browsers are much faster without copying the gl buffer so we just overlay it instead
40
- glOverlay && engineRoot.appendChild(glCanvas);
45
+ const rootElement = mainCanvas.parentElement;
46
+ glOverlay && rootElement.appendChild(glCanvas);
41
47
 
42
48
  // setup vertex and fragment shaders
43
49
  glShader = glCreateProgram(
@@ -241,6 +247,15 @@ function glCopyToContext(context, forceDraw=false)
241
247
  context.drawImage(glCanvas, 0, 0);
242
248
  }
243
249
 
250
+ /** Set antialiasing for webgl canvas
251
+ * @param {Boolean} [antialias]
252
+ * @memberof WebGL */
253
+ function glSetAntialias(antialias=true)
254
+ {
255
+ ASSERT(!glCanvas, 'must be called before engineInit');
256
+ glAntialias = antialias;
257
+ }
258
+
244
259
  /** Add a sprite to the gl draw list, used by all gl draw functions
245
260
  * @param {Number} x
246
261
  * @param {Number} y