littlejsengine 1.14.2 → 1.14.5

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.
@@ -30,14 +30,14 @@
30
30
  </head><body>
31
31
 
32
32
  <!-- setup html menu system -->
33
- <div class="topDiv">
34
- <div id="menu" class="menuDiv">
35
- <b style="font-size:50px">Test Menu</b>
33
+ <div class=topDiv>
34
+ <div id=menu class=menuDiv>
35
+ <b style=font-size:50px>Test Menu</b>
36
36
  This is an example menu using html elements.
37
- <input id="input_test" value="Test Input">
38
- <input id="input_rangeTest" type="range">
39
- <button id="button_test">Test Button</button>
40
- <button id="button_exitMenu">Exit Menu</button>
37
+ <input id=input_test value='Test Input'>
38
+ <input id=input_rangeTest type=range>
39
+ <button id=button_test>Test Button</button>
40
+ <button id=button_exitMenu>Exit Menu</button>
41
41
  </div>
42
42
  </div>
43
43
 
@@ -3,7 +3,7 @@
3
3
  <link rel=icon type=image/png href=favicon.png>
4
4
  <link rel=stylesheet href=style.css?9>
5
5
  <meta charset=utf-8>
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta name='viewport' content='width=device-width, initial-scale=1.0'>
7
7
  </head><body>
8
8
  <div id=container1>
9
9
  <div id=container3>
@@ -35,7 +35,7 @@ Theme:
35
35
  <div id=iframeContainer></div>
36
36
  </div>
37
37
  <div>
38
- <input id=inputSearch placeholder='Search examples...' oninput=filterExamples() onkeydown='if(event.key==="Escape")filterExamples(1)'>
38
+ <input id=inputSearch placeholder='Search examples...' oninput=filterExamples() onkeydown='if(event.key===`Escape`)filterExamples(1)'>
39
39
  <button id=buttonRestart onclick=restartCode()>Restart</button>
40
40
  <button id=buttonPause>Pause</button>
41
41
  <span id=container4>
@@ -318,7 +318,7 @@ function filterExamples(reset=0)
318
318
  if (!selectExample.options.length)
319
319
  {
320
320
  // show a message if no matches
321
- const o = new Option('No examples found matching "' + searchTerm + '"');
321
+ const o = new Option(`No examples found matching '${searchTerm}'`);
322
322
  o.disabled = true;
323
323
  selectExample.add(o);
324
324
  }
@@ -184,13 +184,7 @@ export class Sky extends LJS.EngineObject
184
184
  {
185
185
  // fill background with a gradient
186
186
  const canvas = LJS.mainCanvas;
187
- const gradientDelta = 5;
188
- for (let y=0; y<canvas.height; y+=gradientDelta)
189
- {
190
- // draw horizontal lines to create a gradient
191
- const color = this.skyColor.lerp(this.horizonColor, y/canvas.height);
192
- LJS.drawRect(vec2(0,y), vec2(canvas.width*2, gradientDelta*2), color, 0, undefined, true)
193
- }
187
+ LJS.drawRectGradient(LJS.cameraPos, LJS.getCameraSize(), this.skyColor, this.horizonColor);
194
188
 
195
189
  // draw stars
196
190
  LJS.setBlendMode(true);
@@ -1,6 +1,6 @@
1
1
  // Music player variables
2
2
  let musicSound = new SoundWave('song.mp3');
3
- let musicVolume = .8;
3
+ let musicVolume = 1;
4
4
  let musicInstance;
5
5
 
6
6
  // UI elements
@@ -10,8 +10,8 @@ function gameInit()
10
10
  {
11
11
  // load ui system plugin
12
12
  new UISystemPlugin;
13
- uiSystem.defaultSoundPress = new Sound([.3,0,220]);
14
- uiSystem.defaultSoundClick = new Sound([.3,0,440]);
13
+ uiSystem.defaultSoundPress = new Sound([.5,0,220]);
14
+ uiSystem.defaultSoundClick = new Sound([.5,0,440]);
15
15
  uiSystem.defaultCornerRadius = 20;
16
16
 
17
17
  // setup music player UI
@@ -1,16 +1,18 @@
1
1
  function gameRender()
2
2
  {
3
- // polygon shapes
4
- for (let j=3; j<7; ++j)
5
- drawRegularPoly(vec2(j*4-18,0), vec2(1), j, hsl(j/4+time/9,1,.5), .2, WHITE, time);
6
-
7
3
  // circles and ellipses
8
- drawCircle(vec2(0,5), 1+wave(.5), hsl(.15,1,.5));
9
- drawEllipse(vec2(-5,5), vec2(2,1), hsl(0,1,.5));
10
- drawEllipse(vec2(5,5), vec2(.5,2), hsl(.55,1,.5), .5);
4
+ drawCircle(vec2(0,5), 1+wave(.5), RED);
5
+ drawEllipse(vec2(-6,5), vec2(1,1), YELLOW, .5);
6
+ drawEllipse(vec2(6,5), vec2(1,2), CLEAR_BLACK, .3, .5, CYAN)
7
+
8
+ // polygon shapes
9
+ drawRectGradient(vec2(-6,0), vec2(5,4), RED, BLUE)
10
+ drawRegularPoly(vec2(0,0), vec2(2), 3, PURPLE, .2, WHITE, time);
11
+ const starPath = [vec2(0,2), vec2(2,-2), vec2(-3,.5), vec2(3,.5), vec2(-2,-2), vec2(0,2)];
12
+ drawLineList(starPath, .2, MAGENTA, true, vec2(6, 0));
11
13
 
12
14
  // rects and lines
13
- drawRect(vec2(0,-5), vec2(4,3), hsl(.6,1,.5), time);
14
- drawLine(vec2(-5,-7), vec2(5,-3), 1, hsl(0,0,1, .5));
15
- drawLine(vec2(-5,-3), vec2(5,-7), .2, hsl(1,1,.5));
15
+ drawRect(vec2(0,-5), vec2(4,3), ORANGE, time);
16
+ drawLine(vec2(-5,-7), vec2(5,-3), 1, hsl(0,0,1,.5));
17
+ drawLineList([vec2(5,-3), vec2(-5,-3), vec2(5,-7), vec2(-5,-7)], .2, GREEN);
16
18
  }
@@ -21,7 +21,7 @@ import * as LJS from '../../dist/littlejs.esm.min.js';
21
21
  const {vec2, rgb} = LJS;
22
22
 
23
23
  // keep our own list of simple sprites and track fps
24
- let sprites, tileLayer, timeMS, fpsDisplay, statsDisplay, spriteColor, spriteAdditiveColor, musicInstance;
24
+ let sprites, tileLayer, timeMS, fpsDisplay, statsDisplay, spriteColor, spriteAdditiveColor, musicInstance, hasClicked;
25
25
 
26
26
  ///////////////////////////////////////////////////////////////////////////////
27
27
 
@@ -59,21 +59,14 @@ function gameInit()
59
59
  ///////////////////////////////////////////////////////////////////////////////
60
60
  function gameUpdate()
61
61
  {
62
- if (LJS.mouseWasPressed(0))
63
- {
64
- if (!musicInstance)
65
- musicInstance = music.play();
66
- else if (!musicInstance.isPlaying())
67
- musicInstance.start();
68
- }
69
-
70
62
  // mouse click = change color
71
63
  if (LJS.mouseWasPressed(0) || LJS.mouseIsDown(2))
72
64
  {
65
+ hasClicked = true;
73
66
  spriteColor = LJS.randColor();
74
67
  spriteAdditiveColor = LJS.randColor(rgb(.5,.5,.5, 0), rgb(0,0,0,0));
75
68
  }
76
-
69
+
77
70
  // right click = drop test object
78
71
  if (LJS.mouseIsDown(2))
79
72
  new TestObject(LJS.mousePos);
@@ -92,9 +85,18 @@ function gameUpdate()
92
85
  additiveColor:spriteAdditiveColor.rgbaInt()
93
86
  });
94
87
  }
95
-
88
+
96
89
  // mouse wheel = zoom
97
90
  LJS.setCameraScale(LJS.clamp(LJS.cameraScale*(1-LJS.mouseWheel/10), 1, 1e3));
91
+
92
+ // mouse click = play music
93
+ if (hasClicked)
94
+ {
95
+ if (!musicInstance)
96
+ musicInstance = music.play();
97
+ else if (!musicInstance.isPlaying())
98
+ musicInstance.start();
99
+ }
98
100
  }
99
101
 
100
102
  ///////////////////////////////////////////////////////////////////////////////
@@ -167,5 +169,5 @@ LJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost,
167
169
 
168
170
  ///////////////////////////////////////////////////////////////////////////////
169
171
  // music - Depp Loop
170
- const music = new LJS.ZzFXMusic([[[.6,0,43,,,1,1,.5,,,,,.1,,,.05,,.5,.4,.2],[,0,43,.01,,.2,2,,,,,,,,,,.01],[,0,170,.003,,.008,,.97,-35,53,,,,,,.1],[.8,0,270,,,.12,3,1.65,-2,,,,,4.5,,.02],[,0,86,,,.1,,.7,,,,.5,,6.7,1,.05],[,0,41,,.05,.4,2,0,,,9,.01,,,,.08,.02],[,0,2200,,,.04,3,2,,,800,.02,,4.8,,.01,.1],[.3,0,16,,,.3,3]],[[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,22,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,24,,,,,,,,,,,,,,,,,,,,,,,,22,,22,,22,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,24,,,,,,,,27,,,,,,,,,,,,,,,,27,,,,24,,,,24,,,,,,,,27,,,,,,,,,,,,,,,,24,,24,,24,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[6,1,,,34,34,34,,,,,,34,34,,,,,34,,,,34,34,,,,,34,,,,34,,,,34,34,34,,,,,,34,,,,,,34,34,,,34,34,,,,,,,,,34,34],[4,1,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,23,23,35,23,23,36,23,23,35,23,23,36,23,23,35,35,23,23,35,23,23,35,23,23,36,23,23,35,23,23,36,36],[5,-1,21,,,19,,,21,,,,,,,,,,21,,,19,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,],[3,1,24,,,24,,,24,,,,,,,,,,24,,,24,,,24,,,,24.75,24.5,24.26,24.01,24.01,24.01,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[4,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,24.75,24.5,24.26,24.01,24.01,24.01,24.01,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,,21,23,,35,,23,,21,23,,35,,35,,23,,21,23,,35,,21,23,,35,,21,23,,,],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,36,34,,33,34,34,36,31,36,34,,31,34,32,,33,36,34,,31,34,34,36,33,36,33,,31,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,21,,19,21,,33,,21,,19,21,,33,,33,,21,,19,21,,33,,21,,19,21,,33,,33,,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29],[2,1,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,],[6,1,,,36,,,,,,36,,36,,,,,,,,36,,,,,,36,,36,,,,,,,,36,,,,,,,,,,,,,,,,36,,,,,,36,,36,,,,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,25,,,25,,,,,,,,25,,,,,,,,25,25,25,25]],[[1,-1,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,19,19,31,19,19,31,19,19,31,19,19,31,19,19,31,31],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,36,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,19,,19,19,31,19,19,31,19,,19,19,31,19,19,31],[2,1,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,,,,,,34,,34,,,,,,,,34,,,,,,34,,34,,,,,,]]],[0,1,1,2,3,4,4]]);
172
+ const music = new LJS.ZzFXMusic([[[.6,0,77,,,1,1,.5,,,,,.1,,,.05,,.5,.4,.2],[,0,43,.01,,.2,2,,,,,,,,,,.01],[,0,170,.003,,.008,,.97,-35,53,,,,,,.1],[.8,0,270,,,.12,3,1.65,-2,,,,,4.5,,.02],[,0,86,,,.1,,.7,,,,.5,,6.7,1,.05],[,0,41,,.05,.4,2,0,,,9,.01,,,,.08,.02],[,0,2200,,,.04,3,2,,,800,.02,,4.8,,.01,.1],[.3,0,16,,,.3,3]],[[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,22,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,24,,,,,,,,,,,,,,,,,,,,,,,,22,,22,,22,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,24,,,,,,,,27,,,,,,,,,,,,,,,,27,,,,24,,,,24,,,,,,,,27,,,,,,,,,,,,,,,,24,,24,,24,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[6,1,,,34,34,34,,,,,,34,34,,,,,34,,,,34,34,,,,,34,,,,34,,,,34,34,34,,,,,,34,,,,,,34,34,,,34,34,,,,,,,,,34,34],[4,1,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,23,23,35,23,23,36,23,23,35,23,23,36,23,23,35,35,23,23,35,23,23,35,23,23,36,23,23,35,23,23,36,36],[5,-1,21,,,19,,,21,,,,,,,,,,21,,,19,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,],[3,1,24,,,24,,,24,,,,,,,,,,24,,,24,,,24,,,,24.75,24.5,24.26,24.01,24.01,24.01,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[4,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,24.75,24.5,24.26,24.01,24.01,24.01,24.01,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,,21,23,,35,,23,,21,23,,35,,35,,23,,21,23,,35,,21,23,,35,,21,23,,,],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,36,34,,33,34,34,36,31,36,34,,31,34,32,,33,36,34,,31,34,34,36,33,36,33,,31,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,21,,19,21,,33,,21,,19,21,,33,,33,,21,,19,21,,33,,21,,19,21,,33,,33,,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29],[2,1,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,],[6,1,,,36,,,,,,36,,36,,,,,,,,36,,,,,,36,,36,,,,,,,,36,,,,,,,,,,,,,,,,36,,,,,,36,,36,,,,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,25,,,25,,,,,,,,25,,,,,,,,25,25,25,25]],[[1,-1,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,19,19,31,19,19,31,19,19,31,19,19,31,19,19,31,31],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,36,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,19,,19,19,31,19,19,31,19,,19,19,31,19,19,31],[2,1,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,,,,,,34,,34,,,,,,,,34,,,,,,34,,34,,,,,,]]],[0,1,1,2,3,4,4]]);
171
173
  </script>
@@ -23,7 +23,7 @@ fs.rmSync(BUILD_FOLDER, { recursive: true, force: true });
23
23
  console.log(`Compiling TypeScript...`);
24
24
  // Compile all TypeScript files at once
25
25
  const tsFiles = tsSourceFiles.join(' ');
26
- child_process.execSync(`npx tsc ${tsFiles} --outDir "./${BUILD_FOLDER}" --target es2020 --module es2020`, {stdio: 'inherit'});
26
+ child_process.execSync(`npx tsc ${tsFiles} --outDir './${BUILD_FOLDER}' --target es2020 --module es2020`, {stdio: 'inherit'});
27
27
  console.log(`TypeScript built in ${((Date.now() - startTime)/1e3).toFixed(2)} seconds!`);
28
28
 
29
29
  console.log(`Moving js files back to root...`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.14.2",
3
+ "version": "1.14.5",
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/plugins/box2d.js CHANGED
@@ -1608,7 +1608,7 @@ class Box2dPlugin
1608
1608
  case box2d.instance.b2Shape.e_circle:
1609
1609
  {
1610
1610
  const radius = shape.get_m_radius();
1611
- drawCircle(pos, radius, color, lineWidth, lineColor);
1611
+ drawCircle(pos, radius*2, color, lineWidth, lineColor);
1612
1612
  break;
1613
1613
  }
1614
1614
  case box2d.instance.b2Shape.e_edge:
@@ -1759,14 +1759,14 @@ async function box2dInit()
1759
1759
  {
1760
1760
  color = getDebugColor(color);
1761
1761
  center = box2d.vec2FromPointer(center);
1762
- drawCircle(center, radius, CLEAR_WHITE, debugLineWidth, color, false, false, overlayContext);
1762
+ drawCircle(center, radius*2, CLEAR_WHITE, debugLineWidth, color, false, false, overlayContext);
1763
1763
  };
1764
1764
  debugDraw.DrawSolidCircle = function(center, radius, axis, color)
1765
1765
  {
1766
1766
  color = getDebugColor(color);
1767
1767
  center = box2d.vec2FromPointer(center);
1768
1768
  axis = box2d.vec2FromPointer(axis).scale(radius);
1769
- drawCircle(center, radius, color, debugLineWidth, color, false, false, overlayContext);
1769
+ drawCircle(center, radius*2, color, debugLineWidth, color, false, false, overlayContext);
1770
1770
  drawLine(vec2(), axis, debugLineWidth, color, center, 0, false, false, overlayContext);
1771
1771
  };
1772
1772
  debugDraw.DrawTransform = function(transform)
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
@@ -135,11 +135,13 @@ Timer.valueOf() // Get how long since elapsed, 0 if not set
135
135
  // Drawing functions
136
136
  drawTile(pos, size, tileInfo, color=WHITE, angle=0, mirror, additiveColor)
137
137
  drawRect(pos, size, color=WHITE, angle=0)
138
- drawLine(posA, posB, thickness=.1, color=WHITE, pos=(0,0), 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)
139
141
  drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos, angle=0)
140
- drawRegularPoly(pos, size=(1,1), sides=3, color=WHITE)
141
- drawEllipse(pos, size, color=WHITE, angle=0, lineWidth=0, lineColor=BLACK)
142
- drawCircle(pos, radius=1, color=WHITE, lineWidth=0, lineColor=BLACK)
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)
143
145
  drawCanvas2D(pos, size, angle=0, mirror, drawFunction, screenSpace, context)
144
146
 
145
147
  // Text functions
@@ -424,9 +426,9 @@ particleEmitRateScale = 1 // Scales particles emit rate
424
426
  ```javascript
425
427
  ASSERT(assert, output) // Asserts if the expression is false
426
428
  debugRect(pos, size, color='#fff', time=0, angle=0, fill) // Draw debug rectangle
427
- debugCircle(pos, radius, color='#fff', time=0, fill) // Draw debug circle
429
+ debugCircle(pos, size, color='#fff', time=0, fill) // Draw debug circle
428
430
  debugPoint(pos, color, time, angle) // Draw debug point
429
- debugLine(posA, posB, color, thickness=.1, time) // Draw debug line
431
+ debugLine(posA, posB, color, width=.1, time) // Draw debug line
430
432
  debugText(text, pos, size=1, color='#fff', time=0, angle=0) // Draw debug text
431
433
  debugAABB(pA, sA, pB, sB, color) // Draw a debug axis aligned box
432
434
  debugClear() // Clear all debug primitives
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.14.2';
33
+ const engineVersion = '1.14.5';
34
34
 
35
35
  /** Frames per second to update
36
36
  * @type {number}
@@ -246,8 +246,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
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
  }
@@ -281,6 +280,11 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
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
@@ -144,7 +144,7 @@ function Build(message, outputFile, files=[], buildSteps=[], isPrimaryBuild)
144
144
  {
145
145
  // add license and strict mode to top
146
146
  buffer += license;
147
- buffer += "'use strict';\n\n";
147
+ buffer += `'use strict';\n\n`;
148
148
  }
149
149
 
150
150
  for (const file of files)
@@ -212,7 +212,7 @@ function typeScriptBuildStep(filename)
212
212
  const tsFilename = `${BUILD_FOLDER}/${ENGINE_NAME}.d.ts`
213
213
  child_process.execSync(`npx tsc ${filename} --declaration --allowJs --emitDeclarationOnly --outFile ${tsFilename}`);
214
214
 
215
- // Make declare module part use the package name "littlejsengine"
215
+ // Make declare module part use the package name littlejsengine
216
216
  let fileContent = fs.readFileSync(tsFilename, 'utf8');
217
217
  fileContent = fileContent.replace(`${ENGINE_NAME}\.esm`, 'littlejsengine')
218
218
  fs.writeFileSync(tsFilename, fileContent);
@@ -94,15 +94,15 @@ function debugPoly(pos, points, color='#fff', time=0, angle=0, fill=false)
94
94
 
95
95
  /** Draw a debug circle in world space
96
96
  * @param {Vector2} pos
97
- * @param {number} [radius]
97
+ * @param {number} [size] - diameter
98
98
  * @param {string} [color]
99
99
  * @param {number} [time]
100
100
  * @param {boolean} [fill]
101
101
  * @memberof Debug */
102
- function debugCircle(pos, radius=0, color='#fff', time=0, fill=false)
102
+ function debugCircle(pos, size=0, color='#fff', time=0, fill=false)
103
103
  {
104
104
  ASSERT(typeof color === 'string', 'pass in css color strings');
105
- debugPrimitives.push({pos, size:radius, color, time:new Timer(time), angle:0, fill});
105
+ debugPrimitives.push({pos, size, color, time:new Timer(time), angle:0, fill});
106
106
  }
107
107
 
108
108
  /** Draw a debug point in world space
@@ -121,13 +121,13 @@ function debugPoint(pos, color, time, angle)
121
121
  * @param {Vector2} posA
122
122
  * @param {Vector2} posB
123
123
  * @param {string} [color]
124
- * @param {number} [thickness]
124
+ * @param {number} [width]
125
125
  * @param {number} [time]
126
126
  * @memberof Debug */
127
- function debugLine(posA, posB, color, thickness=.1, time)
127
+ function debugLine(posA, posB, color, width=.1, time)
128
128
  {
129
129
  const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
130
- const size = vec2(thickness, halfDelta.length()*2);
130
+ const size = vec2(width, halfDelta.length()*2);
131
131
  debugRect(posA.add(halfDelta), size, color, time, halfDelta.angle(), true);
132
132
  }
133
133
 
@@ -302,7 +302,7 @@ function debugRender()
302
302
  {
303
303
  const drawPos = centerPos.add(vec2(j*stickScale*2, i*stickScale*3));
304
304
  const stickPos = drawPos.add(sticks[j].scale(stickScale));
305
- debugCircle(drawPos, stickScale, '#fff7',0,true);
305
+ debugCircle(drawPos, stickScale*2, '#fff7',0,true);
306
306
  debugLine(drawPos, stickPos, '#f00');
307
307
  debugPoint(stickPos, '#f00');
308
308
  }
@@ -310,7 +310,7 @@ function debugRender()
310
310
  {
311
311
  const drawPos = centerPos.add(vec2(j*buttonScale*2, i*stickScale*3-stickScale-buttonScale));
312
312
  const pressed = gamepad.buttons[j].pressed;
313
- debugCircle(drawPos, buttonScale, pressed ? '#f00' : '#fff7', 0, true);
313
+ debugCircle(drawPos, buttonScale*2, pressed ? '#f00' : '#fff7', 0, true);
314
314
  debugText(''+j, drawPos, .2);
315
315
  }
316
316
  }
@@ -410,7 +410,7 @@ function debugRender()
410
410
  {
411
411
  // circle
412
412
  overlayContext.beginPath();
413
- overlayContext.arc(0, 0, p.size*cameraScale, 0, 9);
413
+ overlayContext.arc(0, 0, p.size*cameraScale/2, 0, 9);
414
414
  p.fill && overlayContext.fill();
415
415
  overlayContext.stroke();
416
416
  }
package/src/engineDraw.js CHANGED
@@ -72,7 +72,9 @@ let mainCanvasSize = vec2();
72
72
  * @memberof Draw */
73
73
  let textureInfos = [];
74
74
 
75
- // Keep track of how many draw calls there were each frame for debugging
75
+ /** Keeps track of how many draw calls there were each frame for debugging
76
+ * @type {number}
77
+ * @memberof Draw */
76
78
  let drawCount;
77
79
 
78
80
  ///////////////////////////////////////////////////////////////////////////////
@@ -227,8 +229,8 @@ class TextureInfo
227
229
  function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
228
230
  angle=0, mirror, additiveColor, useWebGL=glEnable, screenSpace, context)
229
231
  {
230
- ASSERT(isVector2(pos) && pos.isValid(), 'drawTile pos should be a vec2');
231
- ASSERT(isVector2(size) && size.isValid(), 'drawTile size should be a vec2');
232
+ ASSERT(isVector2(pos), 'drawTile pos should be a vec2');
233
+ ASSERT(isVector2(size), 'drawTile size should be a vec2');
232
234
  ASSERT(isColor(color) && (!additiveColor || isColor(additiveColor)), 'drawTile color is invalid');
233
235
  ASSERT(isNumber(angle), 'drawTile angle should be a number');
234
236
  ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
@@ -276,7 +278,7 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
276
278
  else
277
279
  {
278
280
  // normal canvas 2D rendering method (slower)
279
- showWatermark && ++drawCount;
281
+ ++drawCount;
280
282
  size = new Vector2(size.x, -size.y); // fix upside down sprites
281
283
  drawCanvas2D(pos, size, angle, mirror, (context)=>
282
284
  {
@@ -312,10 +314,124 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
312
314
  drawTile(pos, size, undefined, color, angle, false, undefined, useWebGL, screenSpace, context);
313
315
  }
314
316
 
317
+ /** Draw a rect centered on pos with a gradient from top to bottom
318
+ * @param {Vector2} pos
319
+ * @param {Vector2} [size=(1,1)]
320
+ * @param {Color} [colorTop=(1,1,1,1)]
321
+ * @param {Color} [colorBottom=(0,0,0,1)]
322
+ * @param {number} [angle]
323
+ * @param {boolean} [useWebGL=glEnable]
324
+ * @param {boolean} [screenSpace]
325
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
326
+ * @memberof Draw */
327
+ function drawRectGradient(pos, size, colorTop=WHITE, colorBottom=BLACK, angle=0, useWebGL=glEnable, screenSpace=false, context)
328
+ {
329
+ ASSERT(isVector2(pos), 'drawRectGradient pos should be a vec2');
330
+ ASSERT(isVector2(size), 'drawRectGradient size should be a vec2');
331
+ ASSERT(isColor(colorTop) && isColor(colorBottom), 'drawRectGradient color is invalid');
332
+ ASSERT(isNumber(angle), 'drawRectGradient angle should be a number');
333
+ ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
334
+ if (useWebGL)
335
+ {
336
+ if (screenSpace)
337
+ {
338
+ // convert to world space
339
+ pos = screenToWorld(pos);
340
+ size = size.scale(1/cameraScale);
341
+ }
342
+ // build 4 corner points for the rectangle
343
+ const points = [], colors = [];
344
+ const halfSizeX = size.x/2, halfSizeY = size.y/2;
345
+ const colorTopInt = colorTop.rgbaInt();
346
+ const colorBottomInt = colorBottom.rgbaInt();
347
+ const c = Math.cos(-angle), s = Math.sin(-angle);
348
+ for (let i=4; i--;)
349
+ {
350
+ const x = i & 1 ? halfSizeX : -halfSizeX;
351
+ const y = i & 2 ? halfSizeY : -halfSizeY;
352
+ const rx = x * c - y * s;
353
+ const ry = x * s + y * c;
354
+ const color = i & 2 ? colorTopInt : colorBottomInt;
355
+ points.push(vec2(pos.x + rx, pos.y + ry));
356
+ colors.push(color);
357
+ }
358
+ glDrawColoredPoints(points, colors);
359
+ }
360
+ else
361
+ {
362
+ // normal canvas 2D rendering method (slower)
363
+ ++drawCount;
364
+ size = new Vector2(size.x, -size.y); // fix upside down sprites
365
+ drawCanvas2D(pos, size, angle, false, (context)=>
366
+ {
367
+ // if no tile info, use untextured rect
368
+ const gradient = context.createLinearGradient(0, -.5, 0, .5);
369
+ gradient.addColorStop(0, colorTop.toString());
370
+ gradient.addColorStop(1, colorBottom.toString());
371
+ context.fillStyle = gradient;
372
+ context.fillRect(-.5, -.5, 1, 1);
373
+ }, screenSpace, context);
374
+ }
375
+ }
376
+
377
+ /** Draw connected lines between a series of points
378
+ * @param {Array<Vector2>} points
379
+ * @param {number} [width]
380
+ * @param {Color} [color=(1,1,1,1)]
381
+ * @param {boolean} [wrap] - Should the last point connect to the first?
382
+ * @param {Vector2} [pos=(0,0)] - Offset to apply
383
+ * @param {number} [angle] - Angle to rotate by
384
+ * @param {boolean} [useWebGL=glEnable]
385
+ * @param {boolean} [screenSpace]
386
+ * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
387
+ * @memberof Draw */
388
+ function drawLineList(points, width=.1, color, wrap=false, pos=vec2(), angle=0, useWebGL=glEnable, screenSpace, context)
389
+ {
390
+ ASSERT(Array.isArray(points), 'drawLineList points should be an array');
391
+ ASSERT(isNumber(width), 'drawLineList width should be a number');
392
+ ASSERT(isColor(color), 'drawLineList color is invalid');
393
+ ASSERT(isVector2(pos), 'drawLineList pos should be a vec2');
394
+ ASSERT(isNumber(angle), 'drawLineList angle should be a number');
395
+ ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
396
+ if (useWebGL)
397
+ {
398
+ let scale = 1;
399
+ if (screenSpace)
400
+ {
401
+ // convert to world space
402
+ pos = screenToWorld(pos);
403
+ scale = 1/cameraScale;
404
+ }
405
+ glDrawOutlineTransform(points, color.rgbaInt(), width, pos.x, pos.y, scale, scale, angle, wrap);
406
+ }
407
+ else
408
+ {
409
+ // normal canvas 2D rendering method (slower)
410
+ ++drawCount;
411
+ drawCanvas2D(pos, vec2(1), angle, false, (context)=>
412
+ {
413
+ context.strokeStyle = color.toString();
414
+ context.lineWidth = width;
415
+ context.beginPath();
416
+ for (let i=0; i<points.length; ++i)
417
+ {
418
+ const point = points[i];
419
+ if (i)
420
+ context.lineTo(point.x, point.y);
421
+ else
422
+ context.moveTo(point.x, point.y);
423
+ }
424
+ if (wrap)
425
+ context.closePath();
426
+ context.stroke();
427
+ }, screenSpace, context);
428
+ }
429
+ }
430
+
315
431
  /** Draw colored line between two points
316
432
  * @param {Vector2} posA
317
433
  * @param {Vector2} posB
318
- * @param {number} [thickness]
434
+ * @param {number} [width]
319
435
  * @param {Color} [color=(1,1,1,1)]
320
436
  * @param {Vector2} [pos=(0,0)] - Offset to apply
321
437
  * @param {number} [angle] - Angle to rotate by
@@ -323,10 +439,10 @@ function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
323
439
  * @param {boolean} [screenSpace]
324
440
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
325
441
  * @memberof Draw */
326
- function drawLine(posA, posB, thickness=.1, color, pos=vec2(), angle=0, useWebGL, screenSpace, context)
442
+ function drawLine(posA, posB, width=.1, color, pos=vec2(), angle=0, useWebGL, screenSpace, context)
327
443
  {
328
444
  const halfDelta = vec2((posB.x - posA.x)/2, (posB.y - posA.y)/2);
329
- const size = vec2(thickness, halfDelta.length()*2);
445
+ const size = vec2(width, halfDelta.length()*2);
330
446
  pos = pos.add(posA.add(halfDelta));
331
447
  angle += halfDelta.angle();
332
448
  drawRect(pos, size, color, angle, useWebGL, screenSpace, context);
@@ -346,12 +462,16 @@ function drawLine(posA, posB, thickness=.1, color, pos=vec2(), angle=0, useWebGL
346
462
  * @memberof Draw */
347
463
  function drawRegularPoly(pos, size=vec2(1), sides=3, color=WHITE, lineWidth=0, lineColor=BLACK, angle=0, useWebGL=glEnable, screenSpace=false, context)
348
464
  {
465
+ ASSERT(isVector2(size), 'drawRegularPoly size should be a vec2');
466
+ ASSERT(isNumber(sides), 'drawRegularPoly sides should be a number');
467
+
349
468
  // build regular polygon points
350
469
  const points = [];
470
+ const sizeX = size.x/2, sizeY = size.y/2;
351
471
  for (let i=sides; i--;)
352
472
  {
353
473
  const a = (i/sides)*PI*2;
354
- points.push(vec2(Math.sin(a)*size.x, Math.cos(a)*size.y));
474
+ points.push(vec2(Math.sin(a)*sizeX, Math.cos(a)*sizeY));
355
475
  }
356
476
  drawPoly(points, color, lineWidth, lineColor, pos, angle, useWebGL, screenSpace, context);
357
477
  }
@@ -369,7 +489,7 @@ function drawRegularPoly(pos, size=vec2(1), sides=3, color=WHITE, lineWidth=0, l
369
489
  * @memberof Draw */
370
490
  function drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos=vec2(), angle=0, useWebGL=glEnable, screenSpace=false, context=undefined)
371
491
  {
372
- ASSERT(isVector2(pos) && pos.isValid(), 'drawPoly pos should be a vec2');
492
+ ASSERT(isVector2(pos), 'drawPoly pos should be a vec2');
373
493
  ASSERT(Array.isArray(points), 'drawPoly points should be an array');
374
494
  ASSERT(isColor(color) && isColor(lineColor), 'drawPoly color is invalid');
375
495
  ASSERT(isNumber(lineWidth), 'drawPoly lineWidth should be a number');
@@ -410,7 +530,7 @@ function drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos=vec2(),
410
530
 
411
531
  /** Draw colored ellipse using passed in point
412
532
  * @param {Vector2} pos
413
- * @param {Vector2} [size=(1,1)]
533
+ * @param {Vector2} [size=(1,1)] - Width and height diameter
414
534
  * @param {Color} [color=(1,1,1,1)]
415
535
  * @param {number} [angle]
416
536
  * @param {number} [lineWidth]
@@ -421,8 +541,8 @@ function drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos=vec2(),
421
541
  * @memberof Draw */
422
542
  function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineColor=BLACK, useWebGL=glEnable, screenSpace=false, context)
423
543
  {
424
- ASSERT(isVector2(pos) && pos.isValid(), 'drawEllipse pos should be a vec2');
425
- ASSERT(isVector2(size) && size.isValid(), 'drawEllipse size should be a vec2');
544
+ ASSERT(isVector2(pos), 'drawEllipse pos should be a vec2');
545
+ ASSERT(isVector2(size), 'drawEllipse size should be a vec2');
426
546
  ASSERT(isColor(color) && isColor(lineColor), 'drawEllipse color is invalid');
427
547
  ASSERT(isNumber(angle), 'drawEllipse angle should be a number');
428
548
  ASSERT(isNumber(lineWidth), 'drawEllipse lineWidth should be a number');
@@ -440,7 +560,7 @@ function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineC
440
560
  {
441
561
  context.fillStyle = color.toString();
442
562
  context.beginPath();
443
- context.ellipse(0, 0, size.x, size.y, 0, 0, 9);
563
+ context.ellipse(0, 0, size.x/2, size.y/2, 0, 0, 9);
444
564
  context.fill();
445
565
  if (lineWidth)
446
566
  {
@@ -454,7 +574,7 @@ function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineC
454
574
 
455
575
  /** Draw colored circle using passed in point
456
576
  * @param {Vector2} pos
457
- * @param {number} [radius=1]
577
+ * @param {number} [size=1] - Diameter
458
578
  * @param {Color} [color=(1,1,1,1)]
459
579
  * @param {number} [lineWidth=0]
460
580
  * @param {Color} [lineColor=(0,0,0,1)]
@@ -462,8 +582,11 @@ function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineC
462
582
  * @param {boolean} [screenSpace]
463
583
  * @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
464
584
  * @memberof Draw */
465
- function drawCircle(pos, radius=1, color=WHITE, lineWidth=0, lineColor=BLACK, useWebGL=glEnable, screenSpace=false, context)
466
- { drawEllipse(pos, vec2(radius), color, 0, lineWidth, lineColor, useWebGL, screenSpace, context); }
585
+ function drawCircle(pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK, useWebGL=glEnable, screenSpace=false, context)
586
+ {
587
+ ASSERT(isNumber(size), 'drawCircle size should be a number');
588
+ drawEllipse(pos, vec2(size), color, 0, lineWidth, lineColor, useWebGL, screenSpace, context);
589
+ }
467
590
 
468
591
  /** Draw directly to a 2d canvas context in world space
469
592
  * @param {Vector2} pos
@@ -549,7 +672,6 @@ function drawTextScreen(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=B
549
672
  context.textAlign = textAlign;
550
673
  context.font = size + 'px '+ font;
551
674
  context.textBaseline = 'middle';
552
- context.lineJoin = 'round';
553
675
 
554
676
  const lines = (text+'').split('\n');
555
677
  let posY = pos.y;
@@ -749,7 +871,7 @@ let engineFontImage;
749
871
  * const font = new FontImage;
750
872
  *
751
873
  * // draw text
752
- * font.drawTextScreen("LittleJS\nHello World!", vec2(200, 50));
874
+ * font.drawTextScreen('LittleJS\nHello World!', vec2(200, 50));
753
875
  */
754
876
  class FontImage
755
877
  {