littlejsengine 1.13.4 → 1.14.2
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.
- package/README.md +2 -1
- package/copyToGithub.bat +28 -0
- package/dist/littlejs.d.ts +346 -240
- package/dist/littlejs.esm.js +1370 -723
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +1350 -709
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +1333 -692
- package/examples/box2d/game.js +1 -1
- package/examples/box2d/gameObjects.js +1 -1
- package/examples/breakout/game.js +30 -25
- package/examples/electron/index.html +2 -2
- package/examples/index.html +207 -96
- package/examples/platformer/gameEffects.js +19 -18
- package/examples/platformer/gameLevel.js +6 -1
- package/examples/shorts/base.html +1 -1
- package/examples/shorts/flappyGame.js +2 -1
- package/examples/shorts/helloWorld.js +1 -1
- package/examples/shorts/music.js +106 -0
- package/examples/shorts/parallax.js +71 -0
- package/examples/shorts/piano.js +7 -8
- package/examples/shorts/postProcess.js +25 -8
- package/examples/shorts/shapes.js +1 -9
- package/examples/shorts/song.mp3 +0 -0
- package/examples/shorts/uiSystem.js +15 -8
- package/examples/starter/index.html +2 -2
- package/examples/stress/index.html +8 -3
- package/examples/style.css +14 -4
- package/examples/uiSystem/game.js +11 -11
- package/package.json +1 -1
- package/plugins/box2d.js +10 -8
- package/plugins/drawUtilities.js +5 -5
- package/plugins/newgrounds.js +6 -6
- package/plugins/pluginExport.js +1 -1
- package/plugins/uiSystem.js +103 -79
- package/plugins/zzfxm.js +10 -10
- package/reference.md +90 -54
- package/src/engine.js +22 -22
- package/src/engineAudio.js +284 -109
- package/src/engineBuild.js +9 -9
- package/src/engineDebug.js +26 -26
- package/src/engineDraw.js +148 -97
- package/src/engineExport.js +22 -16
- package/src/engineInput.js +57 -67
- package/src/engineMedals.js +25 -25
- package/src/engineObject.js +25 -22
- package/src/engineParticles.js +59 -59
- package/src/engineRelease.js +1 -1
- package/src/engineSettings.js +20 -13
- package/src/engineTileLayer.js +34 -34
- package/src/engineUtilities.js +62 -55
- package/src/engineWebGL.js +447 -65
- /package/examples/shorts/{playSound.js → sound.js} +0 -0
package/src/engineDraw.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
2
|
* LittleJS Drawing System
|
|
3
3
|
* - Hybrid system with both Canvas2D and WebGL available
|
|
4
4
|
* - Super fast tile sheet rendering with WebGL
|
|
5
5
|
* - Can apply rotation, mirror, color and additive color
|
|
6
6
|
* - Font rendering system with built in engine font
|
|
7
7
|
* - Many useful utility functions
|
|
8
|
-
*
|
|
8
|
+
*
|
|
9
9
|
* LittleJS uses a hybrid rendering solution with the best of both Canvas2D and WebGL.
|
|
10
10
|
* There are 3 canvas/contexts available to draw to...
|
|
11
11
|
* mainCanvas - 2D background canvas, non WebGL stuff like tile layers are drawn here.
|
|
12
12
|
* glCanvas - Used by the accelerated WebGL batch rendering system.
|
|
13
13
|
* overlayCanvas - Another 2D canvas that appears on top of the other 2 canvases.
|
|
14
|
-
*
|
|
14
|
+
*
|
|
15
15
|
* The WebGL rendering system is very fast with some caveats...
|
|
16
16
|
* - Switching blend modes (additive) or textures causes another draw call which is expensive in excess
|
|
17
17
|
* - Group additive rendering together using renderOrder to mitigate this issue
|
|
18
|
-
*
|
|
18
|
+
*
|
|
19
19
|
* The LittleJS rendering solution is intentionally simple, feel free to adjust it for your needs!
|
|
20
20
|
* @namespace Draw
|
|
21
21
|
*/
|
|
@@ -62,7 +62,7 @@ let workCanvas;
|
|
|
62
62
|
* @memberof Draw */
|
|
63
63
|
let workContext;
|
|
64
64
|
|
|
65
|
-
/** The size of the main canvas (and other secondary canvases)
|
|
65
|
+
/** The size of the main canvas (and other secondary canvases)
|
|
66
66
|
* @type {Vector2}
|
|
67
67
|
* @memberof Draw */
|
|
68
68
|
let mainCanvasSize = vec2();
|
|
@@ -77,7 +77,7 @@ let drawCount;
|
|
|
77
77
|
|
|
78
78
|
///////////////////////////////////////////////////////////////////////////////
|
|
79
79
|
|
|
80
|
-
/**
|
|
80
|
+
/**
|
|
81
81
|
* Create a tile info object using a grid based system
|
|
82
82
|
* - This can take vecs or floats for easier use and conversion
|
|
83
83
|
* - If an index is passed in, the tile size and index will determine the position
|
|
@@ -91,15 +91,14 @@ let drawCount;
|
|
|
91
91
|
* tile(5, 8) // a tile at index 5 using a tile size of 8
|
|
92
92
|
* tile(1, 16, 3) // a tile at index 1 of size 16 on texture 3
|
|
93
93
|
* tile(vec2(4,8), vec2(30,10)) // a tile at index (4,8) with a size of (30,10)
|
|
94
|
-
* @memberof Draw
|
|
95
|
-
*/
|
|
94
|
+
* @memberof Draw */
|
|
96
95
|
function tile(pos=new Vector2, size=tileSizeDefault, textureIndex=0, padding=0)
|
|
97
96
|
{
|
|
98
97
|
if (headlessMode)
|
|
99
98
|
return new TileInfo;
|
|
100
99
|
|
|
101
100
|
// if size is a number, make it a vector
|
|
102
|
-
if (typeof size
|
|
101
|
+
if (typeof size === 'number')
|
|
103
102
|
{
|
|
104
103
|
ASSERT(size > 0);
|
|
105
104
|
size = new Vector2(size, size);
|
|
@@ -108,24 +107,24 @@ function tile(pos=new Vector2, size=tileSizeDefault, textureIndex=0, padding=0)
|
|
|
108
107
|
// create tile info object
|
|
109
108
|
const tileInfo = new TileInfo(new Vector2, size, textureIndex, padding);
|
|
110
109
|
|
|
111
|
-
//
|
|
110
|
+
// get the position of the tile
|
|
112
111
|
const textureInfo = textureInfos[textureIndex];
|
|
113
112
|
ASSERT(!!textureInfo, 'Texture not loaded');
|
|
114
113
|
const sizePaddedX = size.x + padding*2;
|
|
115
114
|
const sizePaddedY = size.y + padding*2;
|
|
116
|
-
if (typeof pos
|
|
115
|
+
if (typeof pos === 'number')
|
|
117
116
|
{
|
|
118
117
|
const cols = textureInfo.size.x / sizePaddedX |0;
|
|
119
|
-
ASSERT(cols>0, 'Tile size is too big for texture');
|
|
118
|
+
ASSERT(cols > 0, 'Tile size is too big for texture');
|
|
120
119
|
const posX = pos % cols, posY = (pos / cols) |0;
|
|
121
120
|
tileInfo.pos.set(posX*sizePaddedX+padding, posY*sizePaddedY+padding);
|
|
122
121
|
}
|
|
123
122
|
else
|
|
124
123
|
tileInfo.pos.set(pos.x*sizePaddedX+padding, pos.y*sizePaddedY+padding);
|
|
125
|
-
return tileInfo;
|
|
124
|
+
return tileInfo;
|
|
126
125
|
}
|
|
127
126
|
|
|
128
|
-
/**
|
|
127
|
+
/**
|
|
129
128
|
* Tile Info - Stores info about how to draw a tile
|
|
130
129
|
*/
|
|
131
130
|
class TileInfo
|
|
@@ -163,14 +162,14 @@ class TileInfo
|
|
|
163
162
|
*/
|
|
164
163
|
frame(frame)
|
|
165
164
|
{
|
|
166
|
-
ASSERT(typeof frame
|
|
165
|
+
ASSERT(typeof frame === 'number');
|
|
167
166
|
return this.offset(new Vector2(frame*(this.size.x+this.padding*2), 0));
|
|
168
167
|
}
|
|
169
168
|
|
|
170
169
|
/**
|
|
171
170
|
* Set this tile to use a full image
|
|
172
171
|
* @param {HTMLImageElement|OffscreenCanvas} image
|
|
173
|
-
* @param {WebGLTexture} [glTexture] -
|
|
172
|
+
* @param {WebGLTexture} [glTexture] - WebGL texture
|
|
174
173
|
* @return {TileInfo}
|
|
175
174
|
*/
|
|
176
175
|
setFullImage(image, glTexture)
|
|
@@ -188,7 +187,7 @@ class TextureInfo
|
|
|
188
187
|
/**
|
|
189
188
|
* Create a TextureInfo, called automatically by the engine
|
|
190
189
|
* @param {HTMLImageElement|OffscreenCanvas} image
|
|
191
|
-
* @param {WebGLTexture} [glTexture] -
|
|
190
|
+
* @param {WebGLTexture} [glTexture] - WebGL texture
|
|
192
191
|
*/
|
|
193
192
|
constructor(image, glTexture)
|
|
194
193
|
{
|
|
@@ -198,7 +197,7 @@ class TextureInfo
|
|
|
198
197
|
this.size = vec2(image.width, image.height);
|
|
199
198
|
/** @property {Vector2} - inverse of the size, cached for rendering */
|
|
200
199
|
this.sizeInverse = vec2(1/image.width, 1/image.height);
|
|
201
|
-
/** @property {WebGLTexture} -
|
|
200
|
+
/** @property {WebGLTexture} - WebGL texture */
|
|
202
201
|
this.glTexture = glTexture;
|
|
203
202
|
}
|
|
204
203
|
|
|
@@ -214,28 +213,25 @@ class TextureInfo
|
|
|
214
213
|
// Drawing functions
|
|
215
214
|
|
|
216
215
|
/** Draw textured tile centered in world space, with color applied if using WebGL
|
|
217
|
-
* @param {Vector2}
|
|
218
|
-
* @param {Vector2}
|
|
219
|
-
* @param {TileInfo}[tileInfo]
|
|
220
|
-
* @param {Color}
|
|
221
|
-
* @param {number}
|
|
222
|
-
* @param {boolean}
|
|
223
|
-
* @param {Color}
|
|
224
|
-
* @param {boolean}
|
|
225
|
-
* @param {boolean}
|
|
216
|
+
* @param {Vector2} pos - Center of the tile in world space
|
|
217
|
+
* @param {Vector2} [size=(1,1)] - Size of the tile in world space
|
|
218
|
+
* @param {TileInfo} [tileInfo] - Tile info to use, untextured if undefined
|
|
219
|
+
* @param {Color} [color=(1,1,1,1)] - Color to modulate with
|
|
220
|
+
* @param {number} [angle] - Angle to rotate by
|
|
221
|
+
* @param {boolean} [mirror] - Is image flipped along the Y axis?
|
|
222
|
+
* @param {Color} [additiveColor] - Additive color to be applied if any
|
|
223
|
+
* @param {boolean} [useWebGL=glEnable] - Use accelerated WebGL rendering?
|
|
224
|
+
* @param {boolean} [screenSpace=false] - Are the pos and size are in screen space?
|
|
226
225
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context] - Canvas 2D context to draw to
|
|
227
226
|
* @memberof Draw */
|
|
228
|
-
function drawTile(pos, size=new Vector2(1), tileInfo, color=
|
|
227
|
+
function drawTile(pos, size=new Vector2(1), tileInfo, color=WHITE,
|
|
229
228
|
angle=0, mirror, additiveColor, useWebGL=glEnable, screenSpace, context)
|
|
230
229
|
{
|
|
231
|
-
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
232
230
|
ASSERT(isVector2(pos) && pos.isValid(), 'drawTile pos should be a vec2');
|
|
233
231
|
ASSERT(isVector2(size) && size.isValid(), 'drawTile size should be a vec2');
|
|
234
232
|
ASSERT(isColor(color) && (!additiveColor || isColor(additiveColor)), 'drawTile color is invalid');
|
|
235
233
|
ASSERT(isNumber(angle), 'drawTile angle should be a number');
|
|
236
|
-
|
|
237
|
-
if (color.a <= 0 && (!additiveColor || additiveColor.a <= 0) || !size.x || !size.y)
|
|
238
|
-
return; // completely invisible, skip render
|
|
234
|
+
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
239
235
|
|
|
240
236
|
const textureInfo = tileInfo && tileInfo.textureInfo;
|
|
241
237
|
if (useWebGL)
|
|
@@ -259,22 +255,22 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=new Color,
|
|
|
259
255
|
{
|
|
260
256
|
const tileImageFixBleedX = sizeInverse.x*tileFixBleedScale;
|
|
261
257
|
const tileImageFixBleedY = sizeInverse.y*tileFixBleedScale;
|
|
262
|
-
glDraw(pos.x, pos.y, mirror ? -size.x : size.x, size.y, angle,
|
|
263
|
-
x + tileImageFixBleedX, y + tileImageFixBleedY,
|
|
264
|
-
x - tileImageFixBleedX + w, y - tileImageFixBleedY + h,
|
|
265
|
-
color.rgbaInt(), additiveColor && additiveColor.rgbaInt());
|
|
258
|
+
glDraw(pos.x, pos.y, mirror ? -size.x : size.x, size.y, angle,
|
|
259
|
+
x + tileImageFixBleedX, y + tileImageFixBleedY,
|
|
260
|
+
x - tileImageFixBleedX + w, y - tileImageFixBleedY + h,
|
|
261
|
+
color.rgbaInt(), additiveColor && additiveColor.rgbaInt());
|
|
266
262
|
}
|
|
267
263
|
else
|
|
268
264
|
{
|
|
269
|
-
glDraw(pos.x, pos.y, mirror ? -size.x : size.x, size.y, angle,
|
|
270
|
-
x, y, x + w, y + h,
|
|
271
|
-
color.rgbaInt(), additiveColor && additiveColor.rgbaInt());
|
|
265
|
+
glDraw(pos.x, pos.y, mirror ? -size.x : size.x, size.y, angle,
|
|
266
|
+
x, y, x + w, y + h,
|
|
267
|
+
color.rgbaInt(), additiveColor && additiveColor.rgbaInt());
|
|
272
268
|
}
|
|
273
269
|
}
|
|
274
270
|
else
|
|
275
271
|
{
|
|
276
272
|
// if no tile info, force untextured
|
|
277
|
-
glDraw(pos.x, pos.y, size.x, size.y, angle, 0, 0, 0, 0, 0, color.rgbaInt());
|
|
273
|
+
glDraw(pos.x, pos.y, size.x, size.y, angle, 0, 0, 0, 0, 0, color.rgbaInt());
|
|
278
274
|
}
|
|
279
275
|
}
|
|
280
276
|
else
|
|
@@ -312,8 +308,8 @@ function drawTile(pos, size=new Vector2(1), tileInfo, color=new Color,
|
|
|
312
308
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
313
309
|
* @memberof Draw */
|
|
314
310
|
function drawRect(pos, size, color, angle, useWebGL, screenSpace, context)
|
|
315
|
-
{
|
|
316
|
-
drawTile(pos, size, undefined, color, angle, false, undefined, useWebGL, screenSpace, context);
|
|
311
|
+
{
|
|
312
|
+
drawTile(pos, size, undefined, color, angle, false, undefined, useWebGL, screenSpace, context);
|
|
317
313
|
}
|
|
318
314
|
|
|
319
315
|
/** Draw colored line between two points
|
|
@@ -336,6 +332,30 @@ function drawLine(posA, posB, thickness=.1, color, pos=vec2(), angle=0, useWebGL
|
|
|
336
332
|
drawRect(pos, size, color, angle, useWebGL, screenSpace, context);
|
|
337
333
|
}
|
|
338
334
|
|
|
335
|
+
/** Draw colored regular polygon using passed in number of sides
|
|
336
|
+
* @param {Vector2} pos
|
|
337
|
+
* @param {Vector2} [size=(1,1)]
|
|
338
|
+
* @param {number} [sides]
|
|
339
|
+
* @param {Color} [color=(1,1,1,1)]
|
|
340
|
+
* @param {number} [angle]
|
|
341
|
+
* @param {number} [lineWidth]
|
|
342
|
+
* @param {Color} [lineColor=(0,0,0,1)]
|
|
343
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
344
|
+
* @param {boolean} [screenSpace]
|
|
345
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
346
|
+
* @memberof Draw */
|
|
347
|
+
function drawRegularPoly(pos, size=vec2(1), sides=3, color=WHITE, lineWidth=0, lineColor=BLACK, angle=0, useWebGL=glEnable, screenSpace=false, context)
|
|
348
|
+
{
|
|
349
|
+
// build regular polygon points
|
|
350
|
+
const points = [];
|
|
351
|
+
for (let i=sides; i--;)
|
|
352
|
+
{
|
|
353
|
+
const a = (i/sides)*PI*2;
|
|
354
|
+
points.push(vec2(Math.sin(a)*size.x, Math.cos(a)*size.y));
|
|
355
|
+
}
|
|
356
|
+
drawPoly(points, color, lineWidth, lineColor, pos, angle, useWebGL, screenSpace, context);
|
|
357
|
+
}
|
|
358
|
+
|
|
339
359
|
/** Draw colored polygon using passed in points
|
|
340
360
|
* @param {Array<Vector2>} points - Array of Vector2 points
|
|
341
361
|
* @param {Color} [color=(1,1,1,1)]
|
|
@@ -343,33 +363,49 @@ function drawLine(posA, posB, thickness=.1, color, pos=vec2(), angle=0, useWebGL
|
|
|
343
363
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
344
364
|
* @param {Vector2} [pos=(0,0)] - Offset to apply
|
|
345
365
|
* @param {number} [angle] - Angle to rotate by
|
|
346
|
-
* @param {boolean} [useWebGL]
|
|
366
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
347
367
|
* @param {boolean} [screenSpace]
|
|
348
|
-
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context
|
|
368
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
349
369
|
* @memberof Draw */
|
|
350
|
-
function drawPoly(points, color=
|
|
370
|
+
function drawPoly(points, color=WHITE, lineWidth=0, lineColor=BLACK, pos=vec2(), angle=0, useWebGL=glEnable, screenSpace=false, context=undefined)
|
|
351
371
|
{
|
|
352
372
|
ASSERT(isVector2(pos) && pos.isValid(), 'drawPoly pos should be a vec2');
|
|
353
373
|
ASSERT(Array.isArray(points), 'drawPoly points should be an array');
|
|
354
374
|
ASSERT(isColor(color) && isColor(lineColor), 'drawPoly color is invalid');
|
|
355
375
|
ASSERT(isNumber(lineWidth), 'drawPoly lineWidth should be a number');
|
|
356
376
|
ASSERT(isNumber(angle), 'drawPoly angle should be a number');
|
|
357
|
-
ASSERT(!useWebGL, '
|
|
358
|
-
|
|
377
|
+
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
378
|
+
if (useWebGL)
|
|
359
379
|
{
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
context.lineTo(point.x, point.y);
|
|
363
|
-
context.closePath();
|
|
364
|
-
context.fillStyle = color.toString();
|
|
365
|
-
context.fill();
|
|
366
|
-
if (lineWidth)
|
|
380
|
+
let scale = 1;
|
|
381
|
+
if (screenSpace)
|
|
367
382
|
{
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
383
|
+
// convert to world space
|
|
384
|
+
pos = screenToWorld(pos);
|
|
385
|
+
scale = 1/cameraScale;
|
|
371
386
|
}
|
|
372
|
-
|
|
387
|
+
glDrawPointsTransform(points, color.rgbaInt(), pos.x, pos.y, scale, scale, angle);
|
|
388
|
+
if (lineWidth > 0)
|
|
389
|
+
glDrawOutlineTransform(points, lineColor.rgbaInt(), lineWidth, pos.x, pos.y, scale, scale, angle);
|
|
390
|
+
}
|
|
391
|
+
else
|
|
392
|
+
{
|
|
393
|
+
drawCanvas2D(pos, vec2(1), angle, false, context=>
|
|
394
|
+
{
|
|
395
|
+
context.fillStyle = color.toString();
|
|
396
|
+
context.beginPath();
|
|
397
|
+
for (const point of points)
|
|
398
|
+
context.lineTo(point.x, point.y);
|
|
399
|
+
context.closePath();
|
|
400
|
+
context.fill();
|
|
401
|
+
if (lineWidth)
|
|
402
|
+
{
|
|
403
|
+
context.strokeStyle = lineColor.toString();
|
|
404
|
+
context.lineWidth = lineWidth;
|
|
405
|
+
context.stroke();
|
|
406
|
+
}
|
|
407
|
+
}, screenSpace, context);
|
|
408
|
+
}
|
|
373
409
|
}
|
|
374
410
|
|
|
375
411
|
/** Draw colored ellipse using passed in point
|
|
@@ -379,32 +415,41 @@ function drawPoly(points, color=new Color, lineWidth=0, lineColor=BLACK, pos=vec
|
|
|
379
415
|
* @param {number} [angle]
|
|
380
416
|
* @param {number} [lineWidth]
|
|
381
417
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
382
|
-
* @param {boolean} [useWebGL]
|
|
418
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
383
419
|
* @param {boolean} [screenSpace]
|
|
384
|
-
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context
|
|
420
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
385
421
|
* @memberof Draw */
|
|
386
|
-
function drawEllipse(pos, size=vec2(1), color=
|
|
422
|
+
function drawEllipse(pos, size=vec2(1), color=WHITE, angle=0, lineWidth=0, lineColor=BLACK, useWebGL=glEnable, screenSpace=false, context)
|
|
387
423
|
{
|
|
388
424
|
ASSERT(isVector2(pos) && pos.isValid(), 'drawEllipse pos should be a vec2');
|
|
389
425
|
ASSERT(isVector2(size) && size.isValid(), 'drawEllipse size should be a vec2');
|
|
390
426
|
ASSERT(isColor(color) && isColor(lineColor), 'drawEllipse color is invalid');
|
|
391
427
|
ASSERT(isNumber(angle), 'drawEllipse angle should be a number');
|
|
392
428
|
ASSERT(isNumber(lineWidth), 'drawEllipse lineWidth should be a number');
|
|
393
|
-
ASSERT(lineWidth>=0 && lineWidth < size.x && lineWidth < size.y, 'drawEllipse invalid lineWidth');
|
|
394
|
-
ASSERT(!useWebGL, '
|
|
395
|
-
|
|
429
|
+
ASSERT(lineWidth >= 0 && lineWidth < size.x && lineWidth < size.y, 'drawEllipse invalid lineWidth');
|
|
430
|
+
ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode');
|
|
431
|
+
if (useWebGL)
|
|
396
432
|
{
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
433
|
+
// draw as a regular polygon
|
|
434
|
+
const sides = glCircleSides;
|
|
435
|
+
drawRegularPoly(pos, size, sides, color, lineWidth, lineColor, angle, useWebGL, screenSpace, context);
|
|
436
|
+
}
|
|
437
|
+
else
|
|
438
|
+
{
|
|
439
|
+
drawCanvas2D(pos, vec2(1), angle, false, context=>
|
|
402
440
|
{
|
|
403
|
-
context.
|
|
404
|
-
context.
|
|
405
|
-
context.
|
|
406
|
-
|
|
407
|
-
|
|
441
|
+
context.fillStyle = color.toString();
|
|
442
|
+
context.beginPath();
|
|
443
|
+
context.ellipse(0, 0, size.x, size.y, 0, 0, 9);
|
|
444
|
+
context.fill();
|
|
445
|
+
if (lineWidth)
|
|
446
|
+
{
|
|
447
|
+
context.strokeStyle = lineColor.toString();
|
|
448
|
+
context.lineWidth = lineWidth;
|
|
449
|
+
context.stroke();
|
|
450
|
+
}
|
|
451
|
+
}, screenSpace, context);
|
|
452
|
+
}
|
|
408
453
|
}
|
|
409
454
|
|
|
410
455
|
/** Draw colored circle using passed in point
|
|
@@ -413,11 +458,11 @@ function drawEllipse(pos, size=vec2(1), color=new Color, angle=0, lineWidth=0, l
|
|
|
413
458
|
* @param {Color} [color=(1,1,1,1)]
|
|
414
459
|
* @param {number} [lineWidth=0]
|
|
415
460
|
* @param {Color} [lineColor=(0,0,0,1)]
|
|
416
|
-
* @param {boolean} [useWebGL]
|
|
417
|
-
* @param {boolean} [screenSpace
|
|
418
|
-
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context
|
|
461
|
+
* @param {boolean} [useWebGL=glEnable]
|
|
462
|
+
* @param {boolean} [screenSpace]
|
|
463
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context]
|
|
419
464
|
* @memberof Draw */
|
|
420
|
-
function drawCircle(pos, radius=1, color=
|
|
465
|
+
function drawCircle(pos, radius=1, color=WHITE, lineWidth=0, lineColor=BLACK, useWebGL=glEnable, screenSpace=false, context)
|
|
421
466
|
{ drawEllipse(pos, vec2(radius), color, 0, lineWidth, lineColor, useWebGL, screenSpace, context); }
|
|
422
467
|
|
|
423
468
|
/** Draw directly to a 2d canvas context in world space
|
|
@@ -426,7 +471,7 @@ function drawCircle(pos, radius=1, color=new Color, lineWidth=0, lineColor=BLACK
|
|
|
426
471
|
* @param {number} angle
|
|
427
472
|
* @param {boolean} [mirror]
|
|
428
473
|
* @param {Function} [drawFunction]
|
|
429
|
-
* @param {boolean}
|
|
474
|
+
* @param {boolean} [screenSpace=false]
|
|
430
475
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=drawContext]
|
|
431
476
|
* @memberof Draw */
|
|
432
477
|
function drawCanvas2D(pos, size, angle=0, mirror=false, drawFunction, screenSpace=false, context=drawContext)
|
|
@@ -496,7 +541,7 @@ function drawTextOverlay(text, pos, size=1, color, lineWidth=0, lineColor, textA
|
|
|
496
541
|
* @param {number} [maxWidth]
|
|
497
542
|
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=overlayContext]
|
|
498
543
|
* @memberof Draw */
|
|
499
|
-
function drawTextScreen(text, pos, size=1, color=
|
|
544
|
+
function drawTextScreen(text, pos, size=1, color=WHITE, lineWidth=0, lineColor=BLACK, textAlign='center', font=fontDefault, maxWidth, context=overlayContext)
|
|
500
545
|
{
|
|
501
546
|
context.fillStyle = color.toString();
|
|
502
547
|
context.strokeStyle = lineColor.toString();
|
|
@@ -528,7 +573,7 @@ function screenToWorld(screenPos)
|
|
|
528
573
|
{
|
|
529
574
|
let cameraPosRelativeX = (screenPos.x - mainCanvasSize.x/2 + .5) / cameraScale;
|
|
530
575
|
let cameraPosRelativeY = (screenPos.y - mainCanvasSize.y/2 + .5) / -cameraScale;
|
|
531
|
-
if (cameraAngle)
|
|
576
|
+
if (cameraAngle)
|
|
532
577
|
{
|
|
533
578
|
// apply camera rotation
|
|
534
579
|
const cos = Math.cos(-cameraAngle), sin = Math.sin(-cameraAngle);
|
|
@@ -621,7 +666,7 @@ function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth,
|
|
|
621
666
|
{
|
|
622
667
|
// white texture with no additive alpha, no need to tint
|
|
623
668
|
context.globalAlpha = color.a;
|
|
624
|
-
context.drawImage(image, sx+sx2, sy+sy2, sWidth2, sHeight2, dx, dy, dWidth, dHeight);
|
|
669
|
+
context.drawImage(image, sx+sx2, sy+sy2, sWidth2, sHeight2, dx, dy, dWidth, dHeight);
|
|
625
670
|
context.globalAlpha = 1;
|
|
626
671
|
}
|
|
627
672
|
else
|
|
@@ -642,7 +687,7 @@ function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth,
|
|
|
642
687
|
for (let i = 0; i < data.length; ++i)
|
|
643
688
|
data[i] = data[i] * colorMultiply[i&3] + colorAdd[i&3] |0;
|
|
644
689
|
workContext.putImageData(imageData, 0, 0);
|
|
645
|
-
context.drawImage(workCanvas, sx2, sy2, sWidth2, sHeight2, dx, dy, dWidth, dHeight);
|
|
690
|
+
context.drawImage(workCanvas, sx2, sy2, sWidth2, sHeight2, dx, dy, dWidth, dHeight);
|
|
646
691
|
}
|
|
647
692
|
else
|
|
648
693
|
{
|
|
@@ -655,7 +700,7 @@ function drawImageColor(context, image, sx, sy, sWidth, sHeight, dx, dy, dWidth,
|
|
|
655
700
|
}
|
|
656
701
|
workContext.putImageData(imageData, 0, 0);
|
|
657
702
|
context.globalAlpha = color.a;
|
|
658
|
-
context.drawImage(workCanvas, sx2, sy2, sWidth2, sHeight2, dx, dy, dWidth, dHeight);
|
|
703
|
+
context.drawImage(workCanvas, sx2, sy2, sWidth2, sHeight2, dx, dy, dWidth, dHeight);
|
|
659
704
|
context.globalAlpha = 1;
|
|
660
705
|
}
|
|
661
706
|
}
|
|
@@ -682,7 +727,7 @@ function toggleFullscreen()
|
|
|
682
727
|
}
|
|
683
728
|
|
|
684
729
|
/** Set the cursor style
|
|
685
|
-
* @param {string} cursorStyle - CSS cursor style (auto, none, crosshair, etc)
|
|
730
|
+
* @param {string} [cursorStyle] - CSS cursor style (auto, none, crosshair, etc)
|
|
686
731
|
* @memberof Draw */
|
|
687
732
|
function setCursor(cursorStyle = 'auto')
|
|
688
733
|
{
|
|
@@ -694,7 +739,7 @@ function setCursor(cursorStyle = 'auto')
|
|
|
694
739
|
|
|
695
740
|
let engineFontImage;
|
|
696
741
|
|
|
697
|
-
/**
|
|
742
|
+
/**
|
|
698
743
|
* Font Image Object - Draw text on a 2D canvas by using characters in an image
|
|
699
744
|
* - 96 characters (from space to tilde) are stored in an image
|
|
700
745
|
* - Uses a default 8x8 font if none is supplied
|
|
@@ -702,7 +747,7 @@ let engineFontImage;
|
|
|
702
747
|
* @example
|
|
703
748
|
* // use built in font
|
|
704
749
|
* const font = new FontImage;
|
|
705
|
-
*
|
|
750
|
+
*
|
|
706
751
|
* // draw text
|
|
707
752
|
* font.drawTextScreen("LittleJS\nHello World!", vec2(200, 50));
|
|
708
753
|
*/
|
|
@@ -712,7 +757,6 @@ class FontImage
|
|
|
712
757
|
* @param {HTMLImageElement} [image] - Image for the font, if undefined default font is used
|
|
713
758
|
* @param {Vector2} [tileSize=(8,8)] - Size of the font source tiles
|
|
714
759
|
* @param {Vector2} [paddingSize=(0,1)] - How much extra space to add between characters
|
|
715
|
-
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=overlayContext] - context to draw to
|
|
716
760
|
*/
|
|
717
761
|
constructor(image, tileSize=vec2(8), paddingSize=vec2(0,1), context=overlayContext)
|
|
718
762
|
{
|
|
@@ -726,7 +770,6 @@ class FontImage
|
|
|
726
770
|
this.image = image || engineFontImage;
|
|
727
771
|
this.tileSize = tileSize;
|
|
728
772
|
this.paddingSize = paddingSize;
|
|
729
|
-
this.context = context;
|
|
730
773
|
}
|
|
731
774
|
|
|
732
775
|
/** Draw text in world space using the image font
|
|
@@ -734,23 +777,32 @@ class FontImage
|
|
|
734
777
|
* @param {Vector2} pos
|
|
735
778
|
* @param {number} [scale=.25]
|
|
736
779
|
* @param {boolean} [center]
|
|
780
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D}[context=drawContext]
|
|
737
781
|
*/
|
|
738
|
-
drawText(text, pos, scale=1, center)
|
|
782
|
+
drawText(text, pos, scale=1, center, context=drawContext)
|
|
739
783
|
{
|
|
740
|
-
this.drawTextScreen(text, worldToScreen(pos).floor(), scale*cameraScale|0, center);
|
|
784
|
+
this.drawTextScreen(text, worldToScreen(pos).floor(), scale*cameraScale|0, center, context);
|
|
741
785
|
}
|
|
742
786
|
|
|
743
|
-
/** Draw text in
|
|
787
|
+
/** Draw text on overlay canvas in world space using the image font
|
|
788
|
+
* @param {string} text
|
|
789
|
+
* @param {Vector2} pos
|
|
790
|
+
* @param {number} [scale]
|
|
791
|
+
* @param {boolean} [center]
|
|
792
|
+
*/
|
|
793
|
+
drawTextOverlay(text, pos, scale=4, center)
|
|
794
|
+
{ this.drawText(text, pos, scale, center, overlayContext); }
|
|
795
|
+
|
|
796
|
+
/** Draw text on overlay canvas in screen space using the image font
|
|
744
797
|
* @param {string} text
|
|
745
798
|
* @param {Vector2} pos
|
|
746
799
|
* @param {number} [scale]
|
|
747
800
|
* @param {boolean} [center]
|
|
801
|
+
* @param {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} [context=drawContext]
|
|
748
802
|
*/
|
|
749
|
-
drawTextScreen(text, pos, scale=4, center)
|
|
803
|
+
drawTextScreen(text, pos, scale=4, center, context=overlayContext)
|
|
750
804
|
{
|
|
751
|
-
const context = this.context;
|
|
752
805
|
context.save();
|
|
753
|
-
|
|
754
806
|
const size = this.tileSize;
|
|
755
807
|
const drawSize = size.add(this.paddingSize).scale(scale);
|
|
756
808
|
const cols = this.image.width / this.tileSize.x |0;
|
|
@@ -769,11 +821,10 @@ class FontImage
|
|
|
769
821
|
const x = tile % cols;
|
|
770
822
|
const y = tile / cols |0;
|
|
771
823
|
const drawPos = pos.add(vec2(j,i).multiply(drawSize));
|
|
772
|
-
context.drawImage(this.image, x * size.x, y * size.y, size.x, size.y,
|
|
824
|
+
context.drawImage(this.image, x * size.x, y * size.y, size.x, size.y,
|
|
773
825
|
drawPos.x - centerOffset, drawPos.y, size.x * scale, size.y * scale);
|
|
774
826
|
}
|
|
775
827
|
});
|
|
776
|
-
|
|
777
828
|
context.restore();
|
|
778
829
|
}
|
|
779
830
|
}
|
package/src/engineExport.js
CHANGED
|
@@ -225,27 +225,32 @@ export
|
|
|
225
225
|
// WebGL
|
|
226
226
|
glCanvas,
|
|
227
227
|
glContext,
|
|
228
|
+
glClearCanvas,
|
|
229
|
+
glSetTexture,
|
|
228
230
|
glCompileShader,
|
|
229
|
-
glCopyToContext,
|
|
230
231
|
glCreateProgram,
|
|
231
232
|
glCreateTexture,
|
|
232
233
|
glDeleteTexture,
|
|
233
234
|
glSetTextureData,
|
|
234
|
-
glDraw,
|
|
235
235
|
glFlush,
|
|
236
|
-
|
|
236
|
+
glCopyToContext,
|
|
237
237
|
glSetAntialias,
|
|
238
|
-
|
|
238
|
+
glDraw,
|
|
239
|
+
glDrawPointsTransform,
|
|
240
|
+
glDrawOutlineTransform,
|
|
241
|
+
glDrawPoints,
|
|
239
242
|
glAntialias,
|
|
240
|
-
glShader,
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
glPositionData,
|
|
245
|
-
glColorData,
|
|
246
|
-
glInstanceCount,
|
|
247
|
-
glAdditive,
|
|
243
|
+
glShader,
|
|
244
|
+
glPolyShader,
|
|
245
|
+
glPolyMode,
|
|
246
|
+
glAdditive,
|
|
248
247
|
glBatchAdditive,
|
|
248
|
+
glActiveTexture,
|
|
249
|
+
glArrayBuffer,
|
|
250
|
+
glGeometryBuffer,
|
|
251
|
+
glPositionData,
|
|
252
|
+
glColorData,
|
|
253
|
+
glBatchCount,
|
|
249
254
|
|
|
250
255
|
// Input
|
|
251
256
|
keyIsDown,
|
|
@@ -278,17 +283,18 @@ export
|
|
|
278
283
|
pointerLockIsActive,
|
|
279
284
|
|
|
280
285
|
// Audio
|
|
286
|
+
audioContext,
|
|
287
|
+
audioMasterGain,
|
|
288
|
+
audioDefaultSampleRate,
|
|
281
289
|
Sound,
|
|
282
290
|
SoundWave,
|
|
283
|
-
|
|
291
|
+
SoundInstance,
|
|
284
292
|
speak,
|
|
285
293
|
speakStop,
|
|
286
294
|
getNoteFrequency,
|
|
287
295
|
playSamples,
|
|
288
296
|
zzfx,
|
|
289
297
|
zzfxG,
|
|
290
|
-
zzfxR,
|
|
291
|
-
audioContext,
|
|
292
298
|
|
|
293
299
|
// Base Object
|
|
294
300
|
EngineObject,
|
|
@@ -313,4 +319,4 @@ export
|
|
|
313
319
|
medalsPreventUnlock,
|
|
314
320
|
medalsInit,
|
|
315
321
|
Medal,
|
|
316
|
-
}
|
|
322
|
+
}
|