littlejsengine 1.8.5 â 1.8.8
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 +13 -3
- package/build/littlejs.d.ts +22 -15
- package/build/littlejs.esm.js +255 -55
- package/build/littlejs.esm.min.js +1 -1
- package/build/littlejs.js +253 -55
- package/build/littlejs.min.js +1 -1
- package/build/littlejs.release.js +253 -55
- package/examples/breakout/game.js +3 -0
- package/examples/breakout/index.html +3 -3
- package/examples/breakoutTutorial/index.html +2 -2
- package/examples/electron/game.js +3 -0
- package/examples/electron/index.html +2 -2
- package/examples/js13k/index.html +13 -13
- package/examples/logo.png +0 -0
- package/examples/module/game.js +3 -0
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +1 -1
- package/examples/platformer/game.js +3 -0
- package/examples/platformer/gamePlayer.js +1 -1
- package/examples/platformer/index.html +6 -6
- package/examples/puzzle/game.js +3 -0
- package/examples/puzzle/index.html +2 -2
- package/examples/starter/game.js +3 -0
- package/examples/starter/index.html +13 -13
- package/examples/stress/index.html +3 -1
- package/examples/typescript/game.js +3 -1
- package/examples/typescript/game.ts +3 -0
- package/examples/typescript/index.html +1 -1
- package/package.json +1 -1
- package/src/engine.js +186 -9
- package/src/engineAudio.js +1 -1
- package/src/engineDraw.js +1 -1
- package/src/engineExport.js +2 -0
- package/src/engineInput.js +24 -14
- package/src/engineObject.js +1 -1
- package/src/engineParticles.js +1 -1
- package/src/engineSettings.js +11 -0
- package/src/engineTileLayer.js +8 -8
- package/src/engineUtilities.js +5 -6
- package/src/engineWebGL.js +15 -14
package/README.md
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
#  LittleJS - The Tiny JavaScript Game Engine
|
|
1
|
+
#  LittleJS - The Tiny Fast JavaScript Game Engine
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+

|
|
2
6
|
|
|
3
7
|
[![NPM Package][npm]][npm-url]
|
|
4
8
|
[![Build Size][build-size]][build-size-url]
|
|
@@ -6,12 +10,18 @@
|
|
|
6
10
|
[![DeepScan][deepscan]][deepscan-url]
|
|
7
11
|
[![Discord][discord]][discord-url]
|
|
8
12
|
|
|
13
|
+
</div>
|
|
14
|
+
|
|
9
15
|
## đ All aboard!
|
|
10
16
|
|
|
11
|
-
LittleJS is a lightweight open source HTML5 game engine for modern web development.
|
|
17
|
+
LittleJS is a fast lightweight open source HTML5 game engine for modern web development.
|
|
12
18
|
It's small footprint is packed with a comprehensive feature set including hybrid rendering, physics, particles, sound effects, music, and input handling.
|
|
13
19
|
The code is very clean and well documented with some fun examples to get you started. Choo-Choo! đ
|
|
14
20
|
|
|
21
|
+
### đ Join the First Ever LittleJS Game Jam
|
|
22
|
+
|
|
23
|
+
*The LittleJS Game Jam will take place From Nov 11 to Dec 12! Unleash your creativity and develop amazing games using the LittleJS game engine. đšī¸đŽ [Sign up today and get more info about the jam on itch.io!](https://itch.io/jam/littlejs-game-jam)*
|
|
24
|
+
|
|
15
25
|
<div align="center">
|
|
16
26
|
|
|
17
27
|
## [Demo](https://killedbyapixel.github.io/LittleJS/examples/starter/) | [Docs](https://killedbyapixel.github.io/LittleJS/docs) | [Trailer](https://youtu.be/chuBzGjv7Ms) | [Discord](https://discord.gg/zb7hcGkyZe) | [Tutorial](https://github.com/KilledByAPixel/LittleJS/blob/main/examples/breakoutTutorial/README.md)
|
|
@@ -27,7 +37,7 @@ LittleJS is a small but powerful game engine with many features and no dependenc
|
|
|
27
37
|
### ⨠Graphics
|
|
28
38
|
|
|
29
39
|
- Super fast sprite and tile map rendering engine with WebGL
|
|
30
|
-
- Update and render over 10,000
|
|
40
|
+
- Update and render well over 10,000 sprites at a solid 60fps
|
|
31
41
|
- Apply [Shadertoy](https://www.shadertoy.com) compatible shaders for post-processing effects
|
|
32
42
|
- Robust particle effect system and [effect design tool](https://killedbyapixel.github.io/LittleJS/examples/particles/)
|
|
33
43
|
|
package/build/littlejs.d.ts
CHANGED
|
@@ -204,6 +204,11 @@ declare module "littlejs.esm" {
|
|
|
204
204
|
* @default
|
|
205
205
|
* @memberof Settings */
|
|
206
206
|
export let fontDefault: string;
|
|
207
|
+
/** Enable to show the LittleJS splash screen be shown on startup
|
|
208
|
+
* @type {Boolean}
|
|
209
|
+
* @default
|
|
210
|
+
* @memberof Settings */
|
|
211
|
+
export let showSplashScreen: boolean;
|
|
207
212
|
/** Default size of tiles in pixels
|
|
208
213
|
* @type {Vector2}
|
|
209
214
|
* @default Vector2(16,16)
|
|
@@ -375,6 +380,10 @@ declare module "littlejs.esm" {
|
|
|
375
380
|
* @param {String} font
|
|
376
381
|
* @memberof Settings */
|
|
377
382
|
export function setFontDefault(font: string): void;
|
|
383
|
+
/** Set if the LittleJS splash screen be shown on startup
|
|
384
|
+
* @param {Boolean} show
|
|
385
|
+
* @memberof Settings */
|
|
386
|
+
export function setShowSplashScreen(show: boolean): void;
|
|
378
387
|
/** Set if webgl rendering is enabled
|
|
379
388
|
* @param {Boolean} enable
|
|
380
389
|
* @memberof Settings */
|
|
@@ -795,9 +804,9 @@ declare module "littlejs.esm" {
|
|
|
795
804
|
* @return {Boolean} */
|
|
796
805
|
arrayCheck(arraySize: Vector2): boolean;
|
|
797
806
|
/** Returns this vector expressed as a string
|
|
798
|
-
* @param {
|
|
807
|
+
* @param {Number} digits - precision to display
|
|
799
808
|
* @return {String} */
|
|
800
|
-
toString(digits?:
|
|
809
|
+
toString(digits?: number): string;
|
|
801
810
|
}
|
|
802
811
|
/**
|
|
803
812
|
* Color object (red, green, blue, alpha) with some helpful functions
|
|
@@ -1225,7 +1234,7 @@ declare module "littlejs.esm" {
|
|
|
1225
1234
|
* @return {WebGLProgram}
|
|
1226
1235
|
* @memberof WebGL */
|
|
1227
1236
|
export function glCreateProgram(vsSource: WebGLShader, fsSource: WebGLShader): WebGLProgram;
|
|
1228
|
-
/** Create WebGL texture from an image and
|
|
1237
|
+
/** Create WebGL texture from an image and init the texture settings
|
|
1229
1238
|
* @param {Image} image
|
|
1230
1239
|
* @return {WebGLTexture}
|
|
1231
1240
|
* @memberof WebGL */
|
|
@@ -1475,7 +1484,7 @@ declare module "littlejs.esm" {
|
|
|
1475
1484
|
* @param {Boolean} [loop=1] - True if the music should loop
|
|
1476
1485
|
* @return {AudioBufferSourceNode} - The audio source node
|
|
1477
1486
|
*/
|
|
1478
|
-
|
|
1487
|
+
playMusic(volume?: number, loop?: boolean): AudioBufferSourceNode;
|
|
1479
1488
|
}
|
|
1480
1489
|
/** Play an mp3, ogg, or wav audio from a local file or url
|
|
1481
1490
|
* @param {String} url - Location of sound file to play
|
|
@@ -1590,7 +1599,7 @@ declare module "littlejs.esm" {
|
|
|
1590
1599
|
angleVelocity: number;
|
|
1591
1600
|
spawnTime: number;
|
|
1592
1601
|
children: any[];
|
|
1593
|
-
collideTiles:
|
|
1602
|
+
collideTiles: boolean;
|
|
1594
1603
|
/** Update the object transform and physics, called automatically by engine once each frame */
|
|
1595
1604
|
update(): void;
|
|
1596
1605
|
groundObject: any;
|
|
@@ -1775,17 +1784,17 @@ declare module "littlejs.esm" {
|
|
|
1775
1784
|
/** Draw directly to the 2D canvas in world space (bipass webgl)
|
|
1776
1785
|
* @param {Vector2} pos
|
|
1777
1786
|
* @param {Vector2} size
|
|
1778
|
-
* @param {Number}
|
|
1779
|
-
* @param {Boolean}
|
|
1787
|
+
* @param {Number} angle
|
|
1788
|
+
* @param {Boolean} mirror
|
|
1780
1789
|
* @param {Function} drawFunction */
|
|
1781
|
-
drawCanvas2D(pos: Vector2, size: Vector2, angle
|
|
1790
|
+
drawCanvas2D(pos: Vector2, size: Vector2, angle: number, mirror: boolean, drawFunction: Function): void;
|
|
1782
1791
|
/** Draw a tile directly onto the layer canvas
|
|
1783
|
-
* @param {Vector2}
|
|
1784
|
-
* @param {Vector2}
|
|
1792
|
+
* @param {Vector2} pos
|
|
1793
|
+
* @param {Vector2} [size=Vector2(1,1)]
|
|
1785
1794
|
* @param {TileInfo} [tileInfo]
|
|
1786
|
-
* @param {Color}
|
|
1787
|
-
* @param {Number}
|
|
1788
|
-
* @param {Boolean}
|
|
1795
|
+
* @param {Color} [color=Color()]
|
|
1796
|
+
* @param {Number} [angle=0]
|
|
1797
|
+
* @param {Boolean} [mirror=0] */
|
|
1789
1798
|
drawTile(pos: Vector2, size?: Vector2, tileInfo?: TileInfo, color?: Color, angle?: number, mirror?: boolean): void;
|
|
1790
1799
|
/** Draw a rectangle directly onto the layer canvas
|
|
1791
1800
|
* @param {Vector2} pos
|
|
@@ -1879,8 +1888,6 @@ declare module "littlejs.esm" {
|
|
|
1879
1888
|
fadeRate: number;
|
|
1880
1889
|
/** @property {Number} - Apply extra randomness percent */
|
|
1881
1890
|
randomness: number;
|
|
1882
|
-
/** @property {Number} - Do particles collide against tiles */
|
|
1883
|
-
collideTiles: boolean;
|
|
1884
1891
|
/** @property {Number} - Should particles use addtive blend */
|
|
1885
1892
|
additive: boolean;
|
|
1886
1893
|
/** @property {Boolean} - Should it be in local space of emitter */
|
package/build/littlejs.esm.js
CHANGED
|
@@ -819,7 +819,7 @@ class Vector2
|
|
|
819
819
|
arrayCheck(arraySize) { return this.x >= 0 && this.y >= 0 && this.x < arraySize.x && this.y < arraySize.y; }
|
|
820
820
|
|
|
821
821
|
/** Returns this vector expressed as a string
|
|
822
|
-
* @param {
|
|
822
|
+
* @param {Number} digits - precision to display
|
|
823
823
|
* @return {String} */
|
|
824
824
|
toString(digits=3)
|
|
825
825
|
{ if (debug) { return `(${(this.x<0?'':' ') + this.x.toFixed(digits)},${(this.y<0?'':' ') + this.y.toFixed(digits)} )`; }}
|
|
@@ -1008,11 +1008,10 @@ class Color
|
|
|
1008
1008
|
* @return {Number} */
|
|
1009
1009
|
rgbaInt()
|
|
1010
1010
|
{
|
|
1011
|
-
const
|
|
1012
|
-
const
|
|
1013
|
-
const
|
|
1014
|
-
const
|
|
1015
|
-
const a = toByte(this.a)<<24;
|
|
1011
|
+
const r = clamp(this.r)*255|0;
|
|
1012
|
+
const g = clamp(this.g)*255<<8;
|
|
1013
|
+
const b = clamp(this.b)*255<<16;
|
|
1014
|
+
const a = clamp(this.a)*255<<24;
|
|
1016
1015
|
return r + g + b + a;
|
|
1017
1016
|
}
|
|
1018
1017
|
}
|
|
@@ -1120,6 +1119,12 @@ let canvasPixelated = 1;
|
|
|
1120
1119
|
* @memberof Settings */
|
|
1121
1120
|
let fontDefault = 'arial';
|
|
1122
1121
|
|
|
1122
|
+
/** Enable to show the LittleJS splash screen be shown on startup
|
|
1123
|
+
* @type {Boolean}
|
|
1124
|
+
* @default
|
|
1125
|
+
* @memberof Settings */
|
|
1126
|
+
let showSplashScreen = 0;
|
|
1127
|
+
|
|
1123
1128
|
///////////////////////////////////////////////////////////////////////////////
|
|
1124
1129
|
// WebGL settings
|
|
1125
1130
|
|
|
@@ -1353,6 +1358,11 @@ function setCanvasPixelated(pixelated) { canvasPixelated = pixelated; }
|
|
|
1353
1358
|
* @memberof Settings */
|
|
1354
1359
|
function setFontDefault(font) { fontDefault = font; }
|
|
1355
1360
|
|
|
1361
|
+
/** Set if the LittleJS splash screen be shown on startup
|
|
1362
|
+
* @param {Boolean} show
|
|
1363
|
+
* @memberof Settings */
|
|
1364
|
+
function setShowSplashScreen(show) { showSplashScreen = show; }
|
|
1365
|
+
|
|
1356
1366
|
/** Set if webgl rendering is enabled
|
|
1357
1367
|
* @param {Boolean} enable
|
|
1358
1368
|
* @memberof Settings */
|
|
@@ -1599,7 +1609,7 @@ class EngineObject
|
|
|
1599
1609
|
// init other internal object stuff
|
|
1600
1610
|
this.spawnTime = time;
|
|
1601
1611
|
this.children = [];
|
|
1602
|
-
this.collideTiles =
|
|
1612
|
+
this.collideTiles = false;
|
|
1603
1613
|
|
|
1604
1614
|
// add to list of objects
|
|
1605
1615
|
engineObjects.push(this);
|
|
@@ -1944,7 +1954,7 @@ let mainCanvasSize = vec2();
|
|
|
1944
1954
|
* @memberof Draw */
|
|
1945
1955
|
let textureInfos = [];
|
|
1946
1956
|
|
|
1947
|
-
//
|
|
1957
|
+
// Keep track of how many draw calls there were each frame for debugging
|
|
1948
1958
|
let drawCount;
|
|
1949
1959
|
|
|
1950
1960
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -2547,23 +2557,33 @@ function inputUpdatePost()
|
|
|
2547
2557
|
///////////////////////////////////////////////////////////////////////////////
|
|
2548
2558
|
// Keyboard event handlers
|
|
2549
2559
|
|
|
2550
|
-
onkeydown = (e)=>
|
|
2551
2560
|
{
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2561
|
+
onkeydown = (e)=>
|
|
2562
|
+
{
|
|
2563
|
+
if (debug && e.target != document.body) return;
|
|
2564
|
+
if (!e.repeat)
|
|
2565
|
+
{
|
|
2566
|
+
inputData[isUsingGamepad = 0][e.which] = 3;
|
|
2567
|
+
if (inputWASDEmulateDirection)
|
|
2568
|
+
inputData[0][remapKey(e.which)] = 3;
|
|
2569
|
+
}
|
|
2570
|
+
preventDefaultInput && e.preventDefault();
|
|
2571
|
+
}
|
|
2556
2572
|
|
|
2557
|
-
onkeyup = (e)=>
|
|
2558
|
-
{
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2573
|
+
onkeyup = (e)=>
|
|
2574
|
+
{
|
|
2575
|
+
if (debug && e.target != document.body) return;
|
|
2576
|
+
inputData[0][e.which] = 4;
|
|
2577
|
+
if (inputWASDEmulateDirection)
|
|
2578
|
+
inputData[0][remapKey(e.which)] = 4;
|
|
2579
|
+
}
|
|
2562
2580
|
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2581
|
+
// handle remapping wasd keys to directions
|
|
2582
|
+
function remapKey(c)
|
|
2583
|
+
{
|
|
2584
|
+
return inputWASDEmulateDirection ?
|
|
2585
|
+
c==87?38 : c==83?40 : c==65?37 : c==68?39 : c : c;
|
|
2586
|
+
}
|
|
2567
2587
|
}
|
|
2568
2588
|
|
|
2569
2589
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -3062,7 +3082,7 @@ class Music extends Sound
|
|
|
3062
3082
|
* @param {Boolean} [loop=1] - True if the music should loop
|
|
3063
3083
|
* @return {AudioBufferSourceNode} - The audio source node
|
|
3064
3084
|
*/
|
|
3065
|
-
|
|
3085
|
+
playMusic(volume, loop = 1)
|
|
3066
3086
|
{ return super.play(0, volume, 1, 1, loop); }
|
|
3067
3087
|
}
|
|
3068
3088
|
|
|
@@ -3709,10 +3729,10 @@ constructor(pos, size=tileCollisionSize, tileInfo=tile(), scale=vec2(1), renderO
|
|
|
3709
3729
|
/** Draw directly to the 2D canvas in world space (bipass webgl)
|
|
3710
3730
|
* @param {Vector2} pos
|
|
3711
3731
|
* @param {Vector2} size
|
|
3712
|
-
* @param {Number}
|
|
3713
|
-
* @param {Boolean}
|
|
3732
|
+
* @param {Number} angle
|
|
3733
|
+
* @param {Boolean} mirror
|
|
3714
3734
|
* @param {Function} drawFunction */
|
|
3715
|
-
drawCanvas2D(pos, size, angle
|
|
3735
|
+
drawCanvas2D(pos, size, angle, mirror, drawFunction)
|
|
3716
3736
|
{
|
|
3717
3737
|
const context = this.context;
|
|
3718
3738
|
context.save();
|
|
@@ -3726,12 +3746,12 @@ constructor(pos, size=tileCollisionSize, tileInfo=tile(), scale=vec2(1), renderO
|
|
|
3726
3746
|
}
|
|
3727
3747
|
|
|
3728
3748
|
/** Draw a tile directly onto the layer canvas
|
|
3729
|
-
* @param {Vector2}
|
|
3730
|
-
* @param {Vector2}
|
|
3749
|
+
* @param {Vector2} pos
|
|
3750
|
+
* @param {Vector2} [size=Vector2(1,1)]
|
|
3731
3751
|
* @param {TileInfo} [tileInfo]
|
|
3732
|
-
* @param {Color}
|
|
3733
|
-
* @param {Number}
|
|
3734
|
-
* @param {Boolean}
|
|
3752
|
+
* @param {Color} [color=Color()]
|
|
3753
|
+
* @param {Number} [angle=0]
|
|
3754
|
+
* @param {Boolean} [mirror=0] */
|
|
3735
3755
|
drawTile(pos, size=vec2(1), tileInfo, color=new Color, angle, mirror)
|
|
3736
3756
|
{
|
|
3737
3757
|
this.drawCanvas2D(pos, size, angle, mirror, (context)=>
|
|
@@ -3894,7 +3914,7 @@ class ParticleEmitter extends EngineObject
|
|
|
3894
3914
|
this.fadeRate = fadeRate;
|
|
3895
3915
|
/** @property {Number} - Apply extra randomness percent */
|
|
3896
3916
|
this.randomness = randomness;
|
|
3897
|
-
/** @property {
|
|
3917
|
+
/** @property {Boolean} - Do particles collide against tiles */
|
|
3898
3918
|
this.collideTiles = collideTiles;
|
|
3899
3919
|
/** @property {Number} - Should particles use addtive blend */
|
|
3900
3920
|
this.additive = additive;
|
|
@@ -4382,7 +4402,7 @@ let glCanvas;
|
|
|
4382
4402
|
let glContext;
|
|
4383
4403
|
|
|
4384
4404
|
// WebGL internal variables not exposed to documentation
|
|
4385
|
-
let glActiveTexture, glShader, glArrayBuffer, glPositionData, glColorData, glBatchCount, glBatchAdditive, glAdditive;
|
|
4405
|
+
let glActiveTexture, glShader, glArrayBuffer, glVertexData, glPositionData, glColorData, glBatchCount, glBatchAdditive, glAdditive;
|
|
4386
4406
|
|
|
4387
4407
|
///////////////////////////////////////////////////////////////////////////////
|
|
4388
4408
|
|
|
@@ -4419,10 +4439,10 @@ function glInit()
|
|
|
4419
4439
|
);
|
|
4420
4440
|
|
|
4421
4441
|
// init buffers
|
|
4422
|
-
|
|
4442
|
+
glVertexData = new ArrayBuffer(gl_VERTEX_BUFFER_SIZE);
|
|
4443
|
+
glPositionData = new Float32Array(glVertexData);
|
|
4444
|
+
glColorData = new Uint32Array(glVertexData);
|
|
4423
4445
|
glArrayBuffer = glContext.createBuffer();
|
|
4424
|
-
glPositionData = new Float32Array(vertexData);
|
|
4425
|
-
glColorData = new Uint32Array(vertexData);
|
|
4426
4446
|
glBatchCount = 0;
|
|
4427
4447
|
}
|
|
4428
4448
|
|
|
@@ -4450,7 +4470,7 @@ function glPreRender()
|
|
|
4450
4470
|
glContext.vertexAttribPointer(location, size, type, normalize, gl_VERTEX_BYTE_STRIDE, offset);
|
|
4451
4471
|
offset += size*typeSize;
|
|
4452
4472
|
}
|
|
4453
|
-
initVertexAttribArray('p', gl_FLOAT, 4, 4); // position & texture
|
|
4473
|
+
initVertexAttribArray('p', gl_FLOAT, 4, 4); // position & texture
|
|
4454
4474
|
initVertexAttribArray('c', gl_UNSIGNED_BYTE, 1, 4, 1); // color
|
|
4455
4475
|
initVertexAttribArray('a', gl_UNSIGNED_BYTE, 1, 4, 1); // additiveColor
|
|
4456
4476
|
|
|
@@ -4520,7 +4540,7 @@ function glCreateProgram(vsSource, fsSource)
|
|
|
4520
4540
|
return program;
|
|
4521
4541
|
}
|
|
4522
4542
|
|
|
4523
|
-
/** Create WebGL texture from an image and
|
|
4543
|
+
/** Create WebGL texture from an image and init the texture settings
|
|
4524
4544
|
* @param {Image} image
|
|
4525
4545
|
* @return {WebGLTexture}
|
|
4526
4546
|
* @memberof WebGL */
|
|
@@ -4529,7 +4549,8 @@ function glCreateTexture(image)
|
|
|
4529
4549
|
// build the texture
|
|
4530
4550
|
const texture = glContext.createTexture();
|
|
4531
4551
|
glContext.bindTexture(gl_TEXTURE_2D, texture);
|
|
4532
|
-
|
|
4552
|
+
if (image)
|
|
4553
|
+
glContext.texImage2D(gl_TEXTURE_2D, 0, gl_RGBA, gl_RGBA, gl_UNSIGNED_BYTE, image);
|
|
4533
4554
|
|
|
4534
4555
|
// use point filtering for pixelated rendering
|
|
4535
4556
|
const filter = canvasPixelated ? gl_NEAREST : gl_LINEAR;
|
|
@@ -4537,6 +4558,7 @@ function glCreateTexture(image)
|
|
|
4537
4558
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, filter);
|
|
4538
4559
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE);
|
|
4539
4560
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE);
|
|
4561
|
+
|
|
4540
4562
|
return texture;
|
|
4541
4563
|
}
|
|
4542
4564
|
|
|
@@ -4551,8 +4573,7 @@ function glFlush()
|
|
|
4551
4573
|
glContext.enable(gl_BLEND);
|
|
4552
4574
|
|
|
4553
4575
|
// draw all the sprites in the batch and reset the buffer
|
|
4554
|
-
glContext.bufferSubData(gl_ARRAY_BUFFER, 0,
|
|
4555
|
-
glPositionData.subarray(0, glBatchCount * gl_INDICIES_PER_VERT));
|
|
4576
|
+
glContext.bufferSubData(gl_ARRAY_BUFFER, 0, glVertexData);
|
|
4556
4577
|
glContext.drawArrays(gl_TRIANGLE_STRIP, 0, glBatchCount);
|
|
4557
4578
|
glBatchCount = 0;
|
|
4558
4579
|
glBatchAdditive = glAdditive;
|
|
@@ -4607,11 +4628,11 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
|
|
|
4607
4628
|
// setup 2 triangle strip quad
|
|
4608
4629
|
for(let i = vertCount, offset = glBatchCount * gl_INDICIES_PER_VERT; i--;)
|
|
4609
4630
|
{
|
|
4610
|
-
|
|
4611
|
-
glPositionData[offset++] = positionData[j
|
|
4612
|
-
glPositionData[offset++] = positionData[j
|
|
4613
|
-
glPositionData[offset++] = positionData[j
|
|
4614
|
-
glPositionData[offset++] = positionData[j
|
|
4631
|
+
const j = clamp(i-1, 0, 3)*4; // degenerate tri at ends
|
|
4632
|
+
glPositionData[offset++] = positionData[j+0];
|
|
4633
|
+
glPositionData[offset++] = positionData[j+1];
|
|
4634
|
+
glPositionData[offset++] = positionData[j+2];
|
|
4635
|
+
glPositionData[offset++] = positionData[j+3];
|
|
4615
4636
|
glColorData[offset++] = rgba;
|
|
4616
4637
|
glColorData[offset++] = rgbaAdditive;
|
|
4617
4638
|
}
|
|
@@ -4812,7 +4833,7 @@ const engineName = 'LittleJS';
|
|
|
4812
4833
|
* @type {String}
|
|
4813
4834
|
* @default
|
|
4814
4835
|
* @memberof Engine */
|
|
4815
|
-
const engineVersion = '1.8.
|
|
4836
|
+
const engineVersion = '1.8.8';
|
|
4816
4837
|
|
|
4817
4838
|
/** Frames per second to update objects
|
|
4818
4839
|
* @type {Number}
|
|
@@ -4995,7 +5016,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
4995
5016
|
}
|
|
4996
5017
|
|
|
4997
5018
|
// setup html
|
|
4998
|
-
|
|
5019
|
+
const styleBody =
|
|
4999
5020
|
'margin:0;overflow:hidden;' + // fill the window
|
|
5000
5021
|
'background:#000;' + // set background color
|
|
5001
5022
|
'touch-action:none;' + // prevent mobile pinch to resize
|
|
@@ -5016,14 +5037,13 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
5016
5037
|
|
|
5017
5038
|
// set canvas style
|
|
5018
5039
|
const styleCanvas =
|
|
5019
|
-
'position:absolute;' +
|
|
5020
|
-
'top:50%;left:50%;transform:translate(-50%,-50%);
|
|
5021
|
-
(canvasPixelated?'image-rendering:pixelated':''); // pixelated rendering
|
|
5040
|
+
'position:absolute;' + // position
|
|
5041
|
+
'top:50%;left:50%;transform:translate(-50%,-50%)'; // center
|
|
5022
5042
|
(glCanvas||mainCanvas).style = mainCanvas.style = overlayCanvas.style = styleCanvas;
|
|
5023
5043
|
|
|
5024
|
-
//
|
|
5025
|
-
|
|
5026
|
-
new Promise(
|
|
5044
|
+
// create promises for loading images
|
|
5045
|
+
const promises = imageSources.map((src, textureIndex)=>
|
|
5046
|
+
new Promise(resolve =>
|
|
5027
5047
|
{
|
|
5028
5048
|
const image = new Image;
|
|
5029
5049
|
image.onerror = image.onload = ()=>
|
|
@@ -5033,7 +5053,24 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
5033
5053
|
}
|
|
5034
5054
|
image.src = src;
|
|
5035
5055
|
})
|
|
5036
|
-
)
|
|
5056
|
+
)
|
|
5057
|
+
|
|
5058
|
+
// draw splash screen
|
|
5059
|
+
showSplashScreen && promises.push(new Promise(resolve =>
|
|
5060
|
+
{
|
|
5061
|
+
let t = 0;
|
|
5062
|
+
console.log(`LittleJS Engine v${engineVersion}`);
|
|
5063
|
+
updateSplash();
|
|
5064
|
+
function updateSplash()
|
|
5065
|
+
{
|
|
5066
|
+
clearInput();
|
|
5067
|
+
drawEngineSplashScreen(t+=.01);
|
|
5068
|
+
t>1 ? resolve() : setTimeout(updateSplash,16);
|
|
5069
|
+
}
|
|
5070
|
+
}));
|
|
5071
|
+
|
|
5072
|
+
// load all of the images
|
|
5073
|
+
Promise.all(promises).then(()=>
|
|
5037
5074
|
{
|
|
5038
5075
|
// start the engine
|
|
5039
5076
|
gameInit();
|
|
@@ -5111,6 +5148,167 @@ function engineObjectsCallback(pos, size, callbackFunction, objects=engineObject
|
|
|
5111
5148
|
for (const o of objects)
|
|
5112
5149
|
pos.distanceSquared(o.pos) < sizeSquared && callbackFunction(o);
|
|
5113
5150
|
}
|
|
5151
|
+
}
|
|
5152
|
+
|
|
5153
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
5154
|
+
// LittleJS splash screen and logo
|
|
5155
|
+
|
|
5156
|
+
function drawEngineSplashScreen(t)
|
|
5157
|
+
{
|
|
5158
|
+
// background
|
|
5159
|
+
const grayscale = 0;
|
|
5160
|
+
const x = mainContext;
|
|
5161
|
+
const w = mainCanvas.width = innerWidth;
|
|
5162
|
+
const h = mainCanvas.height = innerHeight;
|
|
5163
|
+
const p3 = percent(t, 1, .8);
|
|
5164
|
+
const p4 = percent(t, 0, .5);
|
|
5165
|
+
const g = x.createRadialGradient(w/2,h/2,0,w/2,h/2,Math.hypot(w,h)*.7);
|
|
5166
|
+
g.addColorStop(0,hsl(0,0,lerp(p4,0,p3/2),p3));
|
|
5167
|
+
g.addColorStop(1,hsl(0,0,0,p3));
|
|
5168
|
+
x.save();
|
|
5169
|
+
x.fillStyle = g;
|
|
5170
|
+
x.fillRect(0,0,w,h);
|
|
5171
|
+
|
|
5172
|
+
// logo - fade in and out
|
|
5173
|
+
const rect = (X, Y, W, H, C)=>
|
|
5174
|
+
{
|
|
5175
|
+
x.beginPath();
|
|
5176
|
+
x.rect(X,Y,W,C?H*p:H);
|
|
5177
|
+
x.fillStyle = C;
|
|
5178
|
+
C ? x.fill() : x.stroke();
|
|
5179
|
+
};
|
|
5180
|
+
const line = (X, Y, Z, W)=>
|
|
5181
|
+
{
|
|
5182
|
+
x.beginPath();
|
|
5183
|
+
x.lineTo(X,Y);
|
|
5184
|
+
x.lineTo(Z,W);
|
|
5185
|
+
x.stroke();
|
|
5186
|
+
};
|
|
5187
|
+
const circle = (X, Y, R, A=0, B=2*PI, C, F)=>
|
|
5188
|
+
{
|
|
5189
|
+
const D = (A+B)/2, E = p*(B-A)/2;
|
|
5190
|
+
x.beginPath();
|
|
5191
|
+
F && x.lineTo(X,Y);
|
|
5192
|
+
x.arc(X,Y,R,D-E,D+E);
|
|
5193
|
+
x.fillStyle = C;
|
|
5194
|
+
C ? x.fill() : x.stroke();
|
|
5195
|
+
};
|
|
5196
|
+
const color = (c=0, l=0) =>
|
|
5197
|
+
hsl([.98,.3,.57,.14][c%4]-10,grayscale?0:.8,[0,.3,.5,.8,.9][l]);
|
|
5198
|
+
const alpha = wave(1,1,t);
|
|
5199
|
+
const p = percent(alpha, .1, .5);
|
|
5200
|
+
|
|
5201
|
+
// setup
|
|
5202
|
+
x.translate(w/2,h/2);
|
|
5203
|
+
const size = min(6, min(w,h)/99); // fit to screen
|
|
5204
|
+
x.scale(size,size);
|
|
5205
|
+
x.translate(-40,-35);
|
|
5206
|
+
x.lineJoin = x.lineCap = 'round';
|
|
5207
|
+
x.lineWidth = 1+p;
|
|
5208
|
+
|
|
5209
|
+
// drawing effect
|
|
5210
|
+
const p2 = percent(alpha,.1,1);
|
|
5211
|
+
x.setLineDash([99*p2,99]);
|
|
5212
|
+
|
|
5213
|
+
// cab top
|
|
5214
|
+
rect(7,17,18,-8,color(2,2));
|
|
5215
|
+
rect(7,9,18,4,color(2,3));
|
|
5216
|
+
rect(25,9,8,8,color(2,1));
|
|
5217
|
+
rect(25,9,-18,8);
|
|
5218
|
+
rect(25,9,8,8);
|
|
5219
|
+
|
|
5220
|
+
// cab
|
|
5221
|
+
rect(25,17,7,22,color());
|
|
5222
|
+
rect(11,40,14,-23,color(1,1));
|
|
5223
|
+
rect(11,17,14,17,color(1,2));
|
|
5224
|
+
rect(11,17,14,9,color(1,3));
|
|
5225
|
+
rect(15,31,6,-9,color(2,2));
|
|
5226
|
+
circle(15,23,5,0,PI/2,color(2,4),1);
|
|
5227
|
+
rect(25,17,-14,23);
|
|
5228
|
+
rect(21,22,-6,9);
|
|
5229
|
+
|
|
5230
|
+
// little stack
|
|
5231
|
+
rect(37,14,9,6,color(3,2));
|
|
5232
|
+
rect(37,14,4,6,color(3,3));
|
|
5233
|
+
rect(37,14,9,6);
|
|
5234
|
+
|
|
5235
|
+
// big stack
|
|
5236
|
+
rect(50,20,10,-10,color(0,1));
|
|
5237
|
+
rect(50,20,6,-10,color(0,2));
|
|
5238
|
+
rect(50,20,3,-10,color(0,3));
|
|
5239
|
+
rect(50,10,10,10);
|
|
5240
|
+
circle(55,2,11,.5,PI-.5,color(3,3));
|
|
5241
|
+
circle(55,2,11,.5,PI/2,color(3,2),1);
|
|
5242
|
+
circle(55,2,11,.5,PI-.5);
|
|
5243
|
+
rect(45,7,20,-7,color(0,2));
|
|
5244
|
+
rect(45,0,20,3,color(0,3));
|
|
5245
|
+
rect(45,0,20,7);
|
|
5246
|
+
|
|
5247
|
+
// engine
|
|
5248
|
+
for (let i=5; i--;)
|
|
5249
|
+
{
|
|
5250
|
+
// stagger radius to fix slight seam
|
|
5251
|
+
circle(60-i*6,30, 9.9,0,2*PI,color(i+2,3));
|
|
5252
|
+
circle(60-i*6,30,10.0,-.5,PI+.5,color(i+2,2));
|
|
5253
|
+
circle(60-i*6,30,10.1,.5,PI-.5,color(i+2,1));
|
|
5254
|
+
}
|
|
5255
|
+
|
|
5256
|
+
// engine outline
|
|
5257
|
+
circle(36,30,10,PI/2,PI*3/2);
|
|
5258
|
+
circle(47,30,10,PI/2,PI*3/2);
|
|
5259
|
+
circle(60,30,10);
|
|
5260
|
+
line(36,20,60,20);
|
|
5261
|
+
|
|
5262
|
+
// engine front light
|
|
5263
|
+
circle(60,30,4,PI,3*PI,color(3,2));
|
|
5264
|
+
circle(60,30,4,PI,2*PI,color(3,3));
|
|
5265
|
+
circle(60,30,4,PI,3*PI);
|
|
5266
|
+
|
|
5267
|
+
// front brush
|
|
5268
|
+
for (let i=6; i--;)
|
|
5269
|
+
{
|
|
5270
|
+
x.beginPath();
|
|
5271
|
+
x.lineTo(53,54);
|
|
5272
|
+
x.lineTo(53,40);
|
|
5273
|
+
x.lineTo(53+(1+i*2.9)*p,40);
|
|
5274
|
+
x.lineTo(53+(4+i*3.5)*p,54);
|
|
5275
|
+
x.fillStyle = color(0,i%2+2);
|
|
5276
|
+
x.fill() || i%2 && x.stroke();
|
|
5277
|
+
}
|
|
5278
|
+
|
|
5279
|
+
// wheels
|
|
5280
|
+
rect(5,40,9,6,color());
|
|
5281
|
+
rect(15,54,38,-14,color())
|
|
5282
|
+
for (let i=3; i--;)
|
|
5283
|
+
for (let j=2; j--;)
|
|
5284
|
+
{
|
|
5285
|
+
circle(15*i+15,47,j?7:1,PI,3*PI,color(i,3));
|
|
5286
|
+
x.stroke();
|
|
5287
|
+
circle(15*i+15,47,j?7:1,0,PI,color(i,2));
|
|
5288
|
+
x.stroke();
|
|
5289
|
+
}
|
|
5290
|
+
line(6,40,68,40) // center
|
|
5291
|
+
line(77,54,4,54) // bottom
|
|
5292
|
+
|
|
5293
|
+
// text
|
|
5294
|
+
const s = engineName;
|
|
5295
|
+
x.font = '900 16px arial';
|
|
5296
|
+
x.textAlign = 'center';
|
|
5297
|
+
x.textBaseline = 'top';
|
|
5298
|
+
x.lineWidth = 1+p*3
|
|
5299
|
+
let w2 = 0;
|
|
5300
|
+
for (let i=0; i<s.length; ++i)
|
|
5301
|
+
w2 += x.measureText(s[i]).width;
|
|
5302
|
+
for (let j=2; j--;)
|
|
5303
|
+
for (let i=0, X=41-w2/2; i<s.length; ++i)
|
|
5304
|
+
{
|
|
5305
|
+
x.fillStyle = color(i,grayscale?3:2);
|
|
5306
|
+
const w = x.measureText(s[i]).width;
|
|
5307
|
+
x[j?'strokeText':'fillText'](s[i],X+w/2,55.5,17*p);
|
|
5308
|
+
X += w;
|
|
5309
|
+
}
|
|
5310
|
+
|
|
5311
|
+
x.restore();
|
|
5114
5312
|
}
|
|
5115
5313
|
|
|
5116
5314
|
/**
|
|
@@ -5158,6 +5356,7 @@ export {
|
|
|
5158
5356
|
canvasFixedSize,
|
|
5159
5357
|
canvasPixelated,
|
|
5160
5358
|
fontDefault,
|
|
5359
|
+
showSplashScreen,
|
|
5161
5360
|
tileSizeDefault,
|
|
5162
5361
|
tileFixBleedScale,
|
|
5163
5362
|
enablePhysicsSolver,
|
|
@@ -5195,6 +5394,7 @@ export {
|
|
|
5195
5394
|
setCanvasFixedSize,
|
|
5196
5395
|
setCanvasPixelated,
|
|
5197
5396
|
setFontDefault,
|
|
5397
|
+
setShowSplashScreen,
|
|
5198
5398
|
setGlEnable,
|
|
5199
5399
|
setGlOverlay,
|
|
5200
5400
|
setTileSizeDefault,
|