littlejsengine 1.9.2 → 1.9.3
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 +4 -2
- package/dist/littlejs.d.ts +23 -23
- package/dist/littlejs.esm.js +97 -87
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +97 -87
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +96 -86
- package/examples/logo.png +0 -0
- package/examples/platformer/data/{gameTileData.tmx → gameLevelData.tmx} +3 -3
- package/examples/platformer/game.js +31 -10
- package/examples/platformer/gameCharacter.js +8 -6
- package/examples/platformer/gameEffects.js +77 -68
- package/examples/platformer/gameLevel.js +33 -16
- package/examples/platformer/{gameTileData.js → gameLevelData.js} +3 -3
- package/examples/platformer/gameObjects.js +14 -14
- package/examples/platformer/index.html +1 -1
- package/examples/platformer/tiles.png +0 -0
- package/examples/screenshot.jpg +0 -0
- package/examples/stress/index.html +1 -1
- package/package.json +1 -1
- package/reference.md +409 -0
- package/src/engine.js +46 -41
- package/src/engineAudio.js +18 -9
- package/src/engineDebug.js +1 -1
- package/src/engineDraw.js +8 -7
- package/src/engineInput.js +1 -1
- package/src/engineMedals.js +1 -1
- package/src/engineObject.js +2 -2
- package/src/engineParticles.js +11 -10
- package/src/engineSettings.js +3 -3
- package/src/engineTileLayer.js +2 -2
- package/src/engineUtilities.js +3 -3
- package/src/engineWebGL.js +1 -7
- /package/examples/platformer/data/{gameTileData.tsx → gameLevelData.tsx} +0 -0
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
## 🚂 All aboard!
|
|
16
16
|
|
|
17
17
|
LittleJS is a fast lightweight open source HTML5 game engine for modern web development.
|
|
18
|
-
|
|
18
|
+
Its small footprint is packed with a comprehensive feature set including hybrid rendering, physics, particles, sound effects, music, and input handling.
|
|
19
19
|
The code is very clean and well documented with some fun examples to get you started. Choo-Choo!
|
|
20
20
|
|
|
21
21
|
### 🚀 Join the First Ever LittleJS Game Jam
|
|
@@ -24,7 +24,7 @@ The code is very clean and well documented with some fun examples to get you sta
|
|
|
24
24
|
|
|
25
25
|
<div align="center">
|
|
26
26
|
|
|
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
|
+
## [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) | [Quick Reference](https://github.com/KilledByAPixel/LittleJS/blob/main/reference.md)
|
|
28
28
|
|
|
29
29
|
</div>
|
|
30
30
|
|
|
@@ -80,6 +80,8 @@ To get started download the latest LittleJS package from GitHub or install via n
|
|
|
80
80
|
|
|
81
81
|
Learn how to make a simple game from scratch with [The Breakout Tutorial.](https://github.com/KilledByAPixel/LittleJS/tree/main/examples/breakoutTutorial)
|
|
82
82
|
|
|
83
|
+
[LittleJS Engine Quick Reference Sheet](https://github.com/KilledByAPixel/LittleJS/blob/main/reference.md) - This cheat sheet can help you get started.
|
|
84
|
+
|
|
83
85
|
[Watch this GitNation talk](https://youtu.be/_dXKU0WgAj8?si=ZDXLYAFDWp54hrGT) to hear more about LittleJS works and get some tips on how to use it.
|
|
84
86
|
|
|
85
87
|
Join our vibrant community on [Discord](https://discord.gg/zb7hcGkyZe) to get help, share your projects, and collaborate with others!
|
package/dist/littlejs.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
declare module "littlejs.esm" {
|
|
2
2
|
/**
|
|
3
|
-
* LittleJS - The Tiny JavaScript Game Engine
|
|
3
|
+
* LittleJS - The Tiny Fast JavaScript Game Engine
|
|
4
4
|
* MIT License - Copyright 2021 Frank Force
|
|
5
5
|
*
|
|
6
6
|
* Engine Features
|
|
@@ -28,7 +28,7 @@ declare module "littlejs.esm" {
|
|
|
28
28
|
* @default
|
|
29
29
|
* @memberof Engine */
|
|
30
30
|
export const engineVersion: string;
|
|
31
|
-
/** Frames per second to update
|
|
31
|
+
/** Frames per second to update
|
|
32
32
|
* @type {Number}
|
|
33
33
|
* @default
|
|
34
34
|
* @memberof Engine */
|
|
@@ -46,7 +46,7 @@ declare module "littlejs.esm" {
|
|
|
46
46
|
* @type {Number}
|
|
47
47
|
* @memberof Engine */
|
|
48
48
|
export let frame: number;
|
|
49
|
-
/** Current engine time since start in seconds
|
|
49
|
+
/** Current engine time since start in seconds
|
|
50
50
|
* @type {Number}
|
|
51
51
|
* @memberof Engine */
|
|
52
52
|
export let time: number;
|
|
@@ -63,12 +63,12 @@ declare module "littlejs.esm" {
|
|
|
63
63
|
* @param {Boolean} isPaused
|
|
64
64
|
* @memberof Engine */
|
|
65
65
|
export function setPaused(isPaused: boolean): void;
|
|
66
|
-
/**
|
|
67
|
-
* @param {Function} gameInit
|
|
68
|
-
* @param {Function} gameUpdate
|
|
69
|
-
* @param {Function} gameUpdatePost
|
|
70
|
-
* @param {Function} gameRender
|
|
71
|
-
* @param {Function} gameRenderPost
|
|
66
|
+
/** Startup LittleJS engine with your callback functions
|
|
67
|
+
* @param {Function} gameInit - Called once after the engine starts up, setup the game
|
|
68
|
+
* @param {Function} gameUpdate - Called every frame at 60 frames per second, handle input and update the game state
|
|
69
|
+
* @param {Function} gameUpdatePost - Called after physics and objects are updated, setup camera and prepare for render
|
|
70
|
+
* @param {Function} gameRender - Called before objects are rendered, draw any background effects that appear behind objects
|
|
71
|
+
* @param {Function} gameRenderPost - Called after objects are rendered, draw effects or hud that appear above all objects
|
|
72
72
|
* @param {Array} [imageSources=['tiles.png']] - Image to load
|
|
73
73
|
* @memberof Engine */
|
|
74
74
|
export function engineInit(gameInit: Function, gameUpdate: Function, gameUpdatePost: Function, gameRender: Function, gameRenderPost: Function, imageSources?: any[]): void;
|
|
@@ -109,7 +109,7 @@ declare module "littlejs.esm" {
|
|
|
109
109
|
* @default
|
|
110
110
|
* @memberof Debug */
|
|
111
111
|
export let showWatermark: boolean;
|
|
112
|
-
/** Asserts if the
|
|
112
|
+
/** Asserts if the expression is false, does not do anything in release builds
|
|
113
113
|
* @param {Boolean} assert
|
|
114
114
|
* @param {Object} [output]
|
|
115
115
|
* @memberof Debug */
|
|
@@ -229,7 +229,7 @@ declare module "littlejs.esm" {
|
|
|
229
229
|
* @default
|
|
230
230
|
* @memberof Settings */
|
|
231
231
|
export let enablePhysicsSolver: boolean;
|
|
232
|
-
/** Default object mass for
|
|
232
|
+
/** Default object mass for collision calcuations (how heavy objects are)
|
|
233
233
|
* @type {Number}
|
|
234
234
|
* @default
|
|
235
235
|
* @memberof Settings */
|
|
@@ -306,7 +306,7 @@ declare module "littlejs.esm" {
|
|
|
306
306
|
* @default
|
|
307
307
|
* @memberof Settings */
|
|
308
308
|
export let touchGamepadAnalog: boolean;
|
|
309
|
-
/** Size of
|
|
309
|
+
/** Size of virtual gamepad for touch devices in pixels
|
|
310
310
|
* @type {Number}
|
|
311
311
|
* @default
|
|
312
312
|
* @memberof Settings */
|
|
@@ -548,7 +548,7 @@ declare module "littlejs.esm" {
|
|
|
548
548
|
* @return {Number}
|
|
549
549
|
* @memberof Utilities */
|
|
550
550
|
export function max(valueA: number, valueB: number): number;
|
|
551
|
-
/** Returns the sign of value passed in
|
|
551
|
+
/** Returns the sign of value passed in
|
|
552
552
|
* @param {Number} value
|
|
553
553
|
* @return {Number}
|
|
554
554
|
* @memberof Utilities */
|
|
@@ -580,7 +580,7 @@ declare module "littlejs.esm" {
|
|
|
580
580
|
* @returns {Number}
|
|
581
581
|
* @memberof Utilities */
|
|
582
582
|
export function distanceWrap(valueA: number, valueB: number, wrapSize?: number): number;
|
|
583
|
-
/** Linearly interpolates between values passed in with
|
|
583
|
+
/** Linearly interpolates between values passed in with wrapping
|
|
584
584
|
* @param {Number} percent
|
|
585
585
|
* @param {Number} valueA
|
|
586
586
|
* @param {Number} valueB
|
|
@@ -594,7 +594,7 @@ declare module "littlejs.esm" {
|
|
|
594
594
|
* @returns {Number}
|
|
595
595
|
* @memberof Utilities */
|
|
596
596
|
export function distanceAngle(angleA: number, angleB: number): number;
|
|
597
|
-
/** Linearly interpolates between the angles passed in with
|
|
597
|
+
/** Linearly interpolates between the angles passed in with wrapping
|
|
598
598
|
* @param {Number} percent
|
|
599
599
|
* @param {Number} angleA
|
|
600
600
|
* @param {Number} angleB
|
|
@@ -1378,7 +1378,7 @@ declare module "littlejs.esm" {
|
|
|
1378
1378
|
* @namespace Audio
|
|
1379
1379
|
*/
|
|
1380
1380
|
/**
|
|
1381
|
-
* Sound Object - Stores a
|
|
1381
|
+
* Sound Object - Stores a sound for later use and can be played positionally
|
|
1382
1382
|
*
|
|
1383
1383
|
* <a href=https://killedbyapixel.github.io/ZzFX/>Create sounds using the ZzFX Sound Designer.</a>
|
|
1384
1384
|
* @example
|
|
@@ -1392,7 +1392,7 @@ declare module "littlejs.esm" {
|
|
|
1392
1392
|
/** Create a sound object and cache the zzfx samples for later use
|
|
1393
1393
|
* @param {Array} zzfxSound - Array of zzfx parameters, ex. [.5,.5]
|
|
1394
1394
|
* @param {Number} [range=soundDefaultRange] - World space max range of sound, will not play if camera is farther away
|
|
1395
|
-
* @param {Number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
|
|
1395
|
+
* @param {Number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
|
|
1396
1396
|
*/
|
|
1397
1397
|
constructor(zzfxSound: any[], range?: number, taper?: number);
|
|
1398
1398
|
/** @property {Number} - World space max range of sound, will not play if camera is farther away */
|
|
@@ -1493,18 +1493,18 @@ declare module "littlejs.esm" {
|
|
|
1493
1493
|
sampleChannels: any[];
|
|
1494
1494
|
/** Play the music
|
|
1495
1495
|
* @param {Number} [volume=1] - How much to scale volume by
|
|
1496
|
-
* @param {Boolean} [loop
|
|
1496
|
+
* @param {Boolean} [loop] - True if the music should loop
|
|
1497
1497
|
* @return {AudioBufferSourceNode} - The audio source node
|
|
1498
1498
|
*/
|
|
1499
1499
|
playMusic(volume?: number, loop?: boolean): AudioBufferSourceNode;
|
|
1500
1500
|
}
|
|
1501
1501
|
/** Play an mp3, ogg, or wav audio from a local file or url
|
|
1502
|
-
* @param {String}
|
|
1502
|
+
* @param {String} filename - Location of sound file to play
|
|
1503
1503
|
* @param {Number} [volume] - How much to scale volume by
|
|
1504
1504
|
* @param {Boolean} [loop] - True if the music should loop
|
|
1505
1505
|
* @return {HTMLAudioElement} - The audio element for this sound
|
|
1506
1506
|
* @memberof Audio */
|
|
1507
|
-
export function playAudioFile(
|
|
1507
|
+
export function playAudioFile(filename: string, volume?: number, loop?: boolean): HTMLAudioElement;
|
|
1508
1508
|
/** Speak text with passed in settings
|
|
1509
1509
|
* @param {String} text - The text to speak
|
|
1510
1510
|
* @param {String} [language] - The language/accent to use (examples: en, it, ru, ja, zh)
|
|
@@ -1553,7 +1553,7 @@ declare module "littlejs.esm" {
|
|
|
1553
1553
|
* - Automatically adds self to object list
|
|
1554
1554
|
* - Will be updated and rendered each frame
|
|
1555
1555
|
* - Renders as a sprite from a tilesheet by default
|
|
1556
|
-
* - Can have color and
|
|
1556
|
+
* - Can have color and additive color applied
|
|
1557
1557
|
* - 2D Physics and collision system
|
|
1558
1558
|
* - Sorted by renderOrder
|
|
1559
1559
|
* - Objects can have children attached
|
|
@@ -1687,7 +1687,7 @@ declare module "littlejs.esm" {
|
|
|
1687
1687
|
/**
|
|
1688
1688
|
* LittleJS Tile Layer System
|
|
1689
1689
|
* - Caches arrays of tiles to off screen canvas for fast rendering
|
|
1690
|
-
* -
|
|
1690
|
+
* - Unlimited numbers of layers, allocates canvases as needed
|
|
1691
1691
|
* - Interfaces with EngineObject for collision
|
|
1692
1692
|
* - Collision layer is separate from visible layers
|
|
1693
1693
|
* - It is recommended to have a visible layer that matches the collision
|
|
@@ -1719,7 +1719,7 @@ declare module "littlejs.esm" {
|
|
|
1719
1719
|
export function getTileCollisionData(pos: Vector2): number;
|
|
1720
1720
|
/** Check if collision with another object should occur
|
|
1721
1721
|
* @param {Vector2} pos
|
|
1722
|
-
* @param {Vector2} [size=(
|
|
1722
|
+
* @param {Vector2} [size=(0,0)]
|
|
1723
1723
|
* @param {EngineObject} [object]
|
|
1724
1724
|
* @return {Boolean}
|
|
1725
1725
|
* @memberof TileCollision */
|
package/dist/littlejs.esm.js
CHANGED
|
@@ -56,7 +56,7 @@ let debugPrimitives = [], debugPhysics = false, debugRaycast = false, debugParti
|
|
|
56
56
|
///////////////////////////////////////////////////////////////////////////////
|
|
57
57
|
// Debug helper functions
|
|
58
58
|
|
|
59
|
-
/** Asserts if the
|
|
59
|
+
/** Asserts if the expression is false, does not do anything in release builds
|
|
60
60
|
* @param {Boolean} assert
|
|
61
61
|
* @param {Object} [output]
|
|
62
62
|
* @memberof Debug */
|
|
@@ -453,7 +453,7 @@ function min(valueA, valueB) { return Math.min(valueA, valueB); }
|
|
|
453
453
|
* @memberof Utilities */
|
|
454
454
|
function max(valueA, valueB) { return Math.max(valueA, valueB); }
|
|
455
455
|
|
|
456
|
-
/** Returns the sign of value passed in
|
|
456
|
+
/** Returns the sign of value passed in
|
|
457
457
|
* @param {Number} value
|
|
458
458
|
* @return {Number}
|
|
459
459
|
* @memberof Utilities */
|
|
@@ -500,7 +500,7 @@ function lerp(percent, valueA, valueB) { return valueA + clamp(percent) * (value
|
|
|
500
500
|
function distanceWrap(valueA, valueB, wrapSize=1)
|
|
501
501
|
{ const d = (valueA - valueB) % wrapSize; return d*2 % wrapSize - d; }
|
|
502
502
|
|
|
503
|
-
/** Linearly interpolates between values passed in with
|
|
503
|
+
/** Linearly interpolates between values passed in with wrapping
|
|
504
504
|
* @param {Number} percent
|
|
505
505
|
* @param {Number} valueA
|
|
506
506
|
* @param {Number} valueB
|
|
@@ -517,7 +517,7 @@ function lerpWrap(percent, valueA, valueB, wrapSize=1)
|
|
|
517
517
|
* @memberof Utilities */
|
|
518
518
|
function distanceAngle(angleA, angleB) { return distanceWrap(angleA, angleB, 2*PI); }
|
|
519
519
|
|
|
520
|
-
/** Linearly interpolates between the angles passed in with
|
|
520
|
+
/** Linearly interpolates between the angles passed in with wrapping
|
|
521
521
|
* @param {Number} percent
|
|
522
522
|
* @param {Number} angleA
|
|
523
523
|
* @param {Number} angleB
|
|
@@ -1259,7 +1259,7 @@ let tileSizeDefault = vec2(16);
|
|
|
1259
1259
|
* @type {Number}
|
|
1260
1260
|
* @default
|
|
1261
1261
|
* @memberof Settings */
|
|
1262
|
-
let tileFixBleedScale = .
|
|
1262
|
+
let tileFixBleedScale = .1;
|
|
1263
1263
|
|
|
1264
1264
|
///////////////////////////////////////////////////////////////////////////////
|
|
1265
1265
|
// Object settings
|
|
@@ -1270,7 +1270,7 @@ let tileFixBleedScale = .3;
|
|
|
1270
1270
|
* @memberof Settings */
|
|
1271
1271
|
let enablePhysicsSolver = true;
|
|
1272
1272
|
|
|
1273
|
-
/** Default object mass for
|
|
1273
|
+
/** Default object mass for collision calcuations (how heavy objects are)
|
|
1274
1274
|
* @type {Number}
|
|
1275
1275
|
* @default
|
|
1276
1276
|
* @memberof Settings */
|
|
@@ -1353,7 +1353,7 @@ let touchGamepadEnable = false;
|
|
|
1353
1353
|
* @memberof Settings */
|
|
1354
1354
|
let touchGamepadAnalog = true;
|
|
1355
1355
|
|
|
1356
|
-
/** Size of
|
|
1356
|
+
/** Size of virtual gamepad for touch devices in pixels
|
|
1357
1357
|
* @type {Number}
|
|
1358
1358
|
* @default
|
|
1359
1359
|
* @memberof Settings */
|
|
@@ -1640,7 +1640,7 @@ function setDebugKey(key) { debugKey = key; }
|
|
|
1640
1640
|
* - Automatically adds self to object list
|
|
1641
1641
|
* - Will be updated and rendered each frame
|
|
1642
1642
|
* - Renders as a sprite from a tilesheet by default
|
|
1643
|
-
* - Can have color and
|
|
1643
|
+
* - Can have color and additive color applied
|
|
1644
1644
|
* - 2D Physics and collision system
|
|
1645
1645
|
* - Sorted by renderOrder
|
|
1646
1646
|
* - Objects can have children attached
|
|
@@ -1919,7 +1919,7 @@ class EngineObject
|
|
|
1919
1919
|
}
|
|
1920
1920
|
|
|
1921
1921
|
/** Destroy this object, destroy it's children, detach it's parent, and mark it for removal */
|
|
1922
|
-
destroy()
|
|
1922
|
+
destroy()
|
|
1923
1923
|
{
|
|
1924
1924
|
if (this.destroyed)
|
|
1925
1925
|
return;
|
|
@@ -2108,13 +2108,9 @@ function tile(pos=vec2(), size=tileSizeDefault, textureIndex=0)
|
|
|
2108
2108
|
if (typeof pos === 'number')
|
|
2109
2109
|
{
|
|
2110
2110
|
const textureInfo = textureInfos[textureIndex];
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
pos = vec2((pos%cols)*size.x, (pos/cols|0)*size.y);
|
|
2115
|
-
}
|
|
2116
|
-
else
|
|
2117
|
-
pos = vec2();
|
|
2111
|
+
ASSERT(textureInfo, 'Texture not loaded');
|
|
2112
|
+
const cols = textureInfo.size.x / size.x |0;
|
|
2113
|
+
pos = vec2((pos%cols)*size.x, (pos/cols|0)*size.y);
|
|
2118
2114
|
}
|
|
2119
2115
|
|
|
2120
2116
|
// return a tile info object
|
|
@@ -2203,6 +2199,11 @@ function worldToScreen(worldPos)
|
|
|
2203
2199
|
);
|
|
2204
2200
|
}
|
|
2205
2201
|
|
|
2202
|
+
/** Get the camera's visible area in world space
|
|
2203
|
+
* @return {Vector2}
|
|
2204
|
+
* @memberof Draw */
|
|
2205
|
+
function getCameraSize() { return mainCanvasSize.scale(1/cameraScale); }
|
|
2206
|
+
|
|
2206
2207
|
/** Draw textured tile centered in world space, with color applied if using WebGL
|
|
2207
2208
|
* @param {Vector2} pos - Center of the tile in world space
|
|
2208
2209
|
* @param {Vector2} [size=(1,1)] - Size of the tile in world space
|
|
@@ -2880,7 +2881,7 @@ function createTouchGamepad()
|
|
|
2880
2881
|
touchGamepadStick = vec2();
|
|
2881
2882
|
|
|
2882
2883
|
const touchHandler = ontouchstart;
|
|
2883
|
-
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
2884
|
+
ontouchstart = ontouchmove = ontouchend = (e)=>
|
|
2884
2885
|
{
|
|
2885
2886
|
// clear touch gamepad input
|
|
2886
2887
|
touchGamepadStick = vec2();
|
|
@@ -3010,7 +3011,7 @@ function touchGamepadRender()
|
|
|
3010
3011
|
|
|
3011
3012
|
|
|
3012
3013
|
/**
|
|
3013
|
-
* Sound Object - Stores a
|
|
3014
|
+
* Sound Object - Stores a sound for later use and can be played positionally
|
|
3014
3015
|
*
|
|
3015
3016
|
* <a href=https://killedbyapixel.github.io/ZzFX/>Create sounds using the ZzFX Sound Designer.</a>
|
|
3016
3017
|
* @example
|
|
@@ -3025,7 +3026,7 @@ class Sound
|
|
|
3025
3026
|
/** Create a sound object and cache the zzfx samples for later use
|
|
3026
3027
|
* @param {Array} zzfxSound - Array of zzfx parameters, ex. [.5,.5]
|
|
3027
3028
|
* @param {Number} [range=soundDefaultRange] - World space max range of sound, will not play if camera is farther away
|
|
3028
|
-
* @param {Number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
|
|
3029
|
+
* @param {Number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
|
|
3029
3030
|
*/
|
|
3030
3031
|
constructor(zzfxSound, range=soundDefaultRange, taper=soundDefaultTaper)
|
|
3031
3032
|
{
|
|
@@ -3205,24 +3206,24 @@ class Music extends Sound
|
|
|
3205
3206
|
|
|
3206
3207
|
/** Play the music
|
|
3207
3208
|
* @param {Number} [volume=1] - How much to scale volume by
|
|
3208
|
-
* @param {Boolean} [loop
|
|
3209
|
+
* @param {Boolean} [loop] - True if the music should loop
|
|
3209
3210
|
* @return {AudioBufferSourceNode} - The audio source node
|
|
3210
3211
|
*/
|
|
3211
|
-
playMusic(volume, loop
|
|
3212
|
+
playMusic(volume, loop=false)
|
|
3212
3213
|
{ return super.play(undefined, volume, 1, 1, loop); }
|
|
3213
3214
|
}
|
|
3214
3215
|
|
|
3215
3216
|
/** Play an mp3, ogg, or wav audio from a local file or url
|
|
3216
|
-
* @param {String}
|
|
3217
|
+
* @param {String} filename - Location of sound file to play
|
|
3217
3218
|
* @param {Number} [volume] - How much to scale volume by
|
|
3218
3219
|
* @param {Boolean} [loop] - True if the music should loop
|
|
3219
3220
|
* @return {HTMLAudioElement} - The audio element for this sound
|
|
3220
3221
|
* @memberof Audio */
|
|
3221
|
-
function playAudioFile(
|
|
3222
|
+
function playAudioFile(filename, volume=1, loop=false)
|
|
3222
3223
|
{
|
|
3223
3224
|
if (!soundEnable) return;
|
|
3224
3225
|
|
|
3225
|
-
const audio = new Audio(
|
|
3226
|
+
const audio = new Audio(filename);
|
|
3226
3227
|
audio.volume = soundVolume * volume;
|
|
3227
3228
|
audio.loop = loop;
|
|
3228
3229
|
audio.play();
|
|
@@ -3274,6 +3275,11 @@ function getNoteFrequency(semitoneOffset, rootFrequency=220)
|
|
|
3274
3275
|
* @memberof Audio */
|
|
3275
3276
|
let audioContext = new AudioContext;
|
|
3276
3277
|
|
|
3278
|
+
/** Keep track if audio was suspended when last sound was played
|
|
3279
|
+
* @type {Boolean}
|
|
3280
|
+
* @memberof Audio */
|
|
3281
|
+
let audioSuspended = false;
|
|
3282
|
+
|
|
3277
3283
|
/** Play cached audio samples with given settings
|
|
3278
3284
|
* @param {Array} sampleChannels - Array of arrays of samples to play (for stereo playback)
|
|
3279
3285
|
* @param {Number} [volume] - How much to scale volume by
|
|
@@ -3288,11 +3294,15 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=false, sample
|
|
|
3288
3294
|
if (!soundEnable) return;
|
|
3289
3295
|
|
|
3290
3296
|
// prevent sounds from building up if they can't be played
|
|
3291
|
-
|
|
3297
|
+
const audioWasSuspended = audioSuspended;
|
|
3298
|
+
if (audioSuspended = audioContext.state != 'running')
|
|
3292
3299
|
{
|
|
3293
3300
|
// fix stalled audio
|
|
3294
3301
|
audioContext.resume();
|
|
3295
|
-
|
|
3302
|
+
|
|
3303
|
+
// prevent suspended sounds from building up
|
|
3304
|
+
if (audioWasSuspended)
|
|
3305
|
+
return;
|
|
3296
3306
|
}
|
|
3297
3307
|
|
|
3298
3308
|
// create buffer and source
|
|
@@ -3560,7 +3570,7 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
|
3560
3570
|
/**
|
|
3561
3571
|
* LittleJS Tile Layer System
|
|
3562
3572
|
* - Caches arrays of tiles to off screen canvas for fast rendering
|
|
3563
|
-
* -
|
|
3573
|
+
* - Unlimited numbers of layers, allocates canvases as needed
|
|
3564
3574
|
* - Interfaces with EngineObject for collision
|
|
3565
3575
|
* - Collision layer is separate from visible layers
|
|
3566
3576
|
* - It is recommended to have a visible layer that matches the collision
|
|
@@ -3612,7 +3622,7 @@ function getTileCollisionData(pos)
|
|
|
3612
3622
|
|
|
3613
3623
|
/** Check if collision with another object should occur
|
|
3614
3624
|
* @param {Vector2} pos
|
|
3615
|
-
* @param {Vector2} [size=(
|
|
3625
|
+
* @param {Vector2} [size=(0,0)]
|
|
3616
3626
|
* @param {EngineObject} [object]
|
|
3617
3627
|
* @return {Boolean}
|
|
3618
3628
|
* @memberof TileCollision */
|
|
@@ -4129,16 +4139,17 @@ class ParticleEmitter extends EngineObject
|
|
|
4129
4139
|
|
|
4130
4140
|
// build particle
|
|
4131
4141
|
const particle = new Particle(pos, this.tileInfo, angle, colorStart, colorEnd, particleTime, sizeStart, sizeEnd, this.fadeRate, this.additive, this.trailScale, this.localSpace && this, this.particleDestroyCallback);
|
|
4132
|
-
particle.velocity
|
|
4133
|
-
particle.
|
|
4134
|
-
particle.
|
|
4135
|
-
particle.
|
|
4136
|
-
particle.
|
|
4137
|
-
particle.
|
|
4138
|
-
particle.
|
|
4139
|
-
particle.
|
|
4140
|
-
particle.
|
|
4141
|
-
particle.
|
|
4142
|
+
particle.velocity = vec2().setAngle(velocityAngle, speed);
|
|
4143
|
+
particle.angleVelocity = angleSpeed;
|
|
4144
|
+
particle.fadeRate = this.fadeRate;
|
|
4145
|
+
particle.damping = this.damping;
|
|
4146
|
+
particle.angleDamping = this.angleDamping;
|
|
4147
|
+
particle.elasticity = this.elasticity;
|
|
4148
|
+
particle.friction = this.friction;
|
|
4149
|
+
particle.gravityScale = this.gravityScale;
|
|
4150
|
+
particle.collideTiles = this.collideTiles;
|
|
4151
|
+
particle.renderOrder = this.renderOrder;
|
|
4152
|
+
particle.mirror = !!randInt(2);
|
|
4142
4153
|
|
|
4143
4154
|
// call particle create callaback
|
|
4144
4155
|
this.particleCreateCallback && this.particleCreateCallback(particle);
|
|
@@ -4529,7 +4540,7 @@ class Newgrounds
|
|
|
4529
4540
|
}
|
|
4530
4541
|
|
|
4531
4542
|
// build the input object
|
|
4532
|
-
const input =
|
|
4543
|
+
const input =
|
|
4533
4544
|
{
|
|
4534
4545
|
'app_id': this.app_id,
|
|
4535
4546
|
'session_id': this.session_id,
|
|
@@ -4744,8 +4755,6 @@ function glCreateTexture(image)
|
|
|
4744
4755
|
const filter = canvasPixelated ? gl_NEAREST : gl_LINEAR;
|
|
4745
4756
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, filter);
|
|
4746
4757
|
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, filter);
|
|
4747
|
-
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_S, gl_CLAMP_TO_EDGE);
|
|
4748
|
-
glContext.texParameteri(gl_TEXTURE_2D, gl_TEXTURE_WRAP_T, gl_CLAMP_TO_EDGE);
|
|
4749
4758
|
|
|
4750
4759
|
return texture;
|
|
4751
4760
|
}
|
|
@@ -4823,7 +4832,7 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba, rgbaAdd
|
|
|
4823
4832
|
///////////////////////////////////////////////////////////////////////////////
|
|
4824
4833
|
// post processing - can be enabled to pass other canvases through a final shader
|
|
4825
4834
|
|
|
4826
|
-
let glPostShader,
|
|
4835
|
+
let glPostShader, glPostTexture, glPostIncludeOverlay;
|
|
4827
4836
|
|
|
4828
4837
|
/** Set up a post processing shader
|
|
4829
4838
|
* @param {String} shaderCode
|
|
@@ -4859,7 +4868,6 @@ function glInitPostProcess(shaderCode, includeOverlay=false)
|
|
|
4859
4868
|
);
|
|
4860
4869
|
|
|
4861
4870
|
// create buffer and texture
|
|
4862
|
-
glPostArrayBuffer = glContext.createBuffer();
|
|
4863
4871
|
glPostTexture = glCreateTexture(undefined);
|
|
4864
4872
|
glPostIncludeOverlay = includeOverlay;
|
|
4865
4873
|
|
|
@@ -4931,10 +4939,7 @@ gl_NEAREST = 9728,
|
|
|
4931
4939
|
gl_LINEAR = 9729,
|
|
4932
4940
|
gl_TEXTURE_MAG_FILTER = 10240,
|
|
4933
4941
|
gl_TEXTURE_MIN_FILTER = 10241,
|
|
4934
|
-
gl_TEXTURE_WRAP_S = 10242,
|
|
4935
|
-
gl_TEXTURE_WRAP_T = 10243,
|
|
4936
4942
|
gl_COLOR_BUFFER_BIT = 16384,
|
|
4937
|
-
gl_CLAMP_TO_EDGE = 33071,
|
|
4938
4943
|
gl_TEXTURE0 = 33984,
|
|
4939
4944
|
gl_ARRAY_BUFFER = 34962,
|
|
4940
4945
|
gl_STATIC_DRAW = 35044,
|
|
@@ -4951,7 +4956,7 @@ gl_MAX_INSTANCES = 1e4,
|
|
|
4951
4956
|
gl_INSTANCE_BYTE_STRIDE = gl_INDICIES_PER_INSTANCE * 4, // 11 * 4
|
|
4952
4957
|
gl_INSTANCE_BUFFER_SIZE = gl_MAX_INSTANCES * gl_INSTANCE_BYTE_STRIDE;
|
|
4953
4958
|
/**
|
|
4954
|
-
* LittleJS - The Tiny JavaScript Game Engine
|
|
4959
|
+
* LittleJS - The Tiny Fast JavaScript Game Engine
|
|
4955
4960
|
* MIT License - Copyright 2021 Frank Force
|
|
4956
4961
|
*
|
|
4957
4962
|
* Engine Features
|
|
@@ -4982,9 +4987,9 @@ const engineName = 'LittleJS';
|
|
|
4982
4987
|
* @type {String}
|
|
4983
4988
|
* @default
|
|
4984
4989
|
* @memberof Engine */
|
|
4985
|
-
const engineVersion = '1.9.
|
|
4990
|
+
const engineVersion = '1.9.3';
|
|
4986
4991
|
|
|
4987
|
-
/** Frames per second to update
|
|
4992
|
+
/** Frames per second to update
|
|
4988
4993
|
* @type {Number}
|
|
4989
4994
|
* @default
|
|
4990
4995
|
* @memberof Engine */
|
|
@@ -5001,7 +5006,7 @@ const timeDelta = 1/frameRate;
|
|
|
5001
5006
|
* @memberof Engine */
|
|
5002
5007
|
let engineObjects = [];
|
|
5003
5008
|
|
|
5004
|
-
/** Array
|
|
5009
|
+
/** Array with only objects set to collide with other objects this frame (for optimization)
|
|
5005
5010
|
* @type {Array}
|
|
5006
5011
|
* @memberof Engine */
|
|
5007
5012
|
let engineObjectsCollide = [];
|
|
@@ -5011,7 +5016,7 @@ let engineObjectsCollide = [];
|
|
|
5011
5016
|
* @memberof Engine */
|
|
5012
5017
|
let frame = 0;
|
|
5013
5018
|
|
|
5014
|
-
/** Current engine time since start in seconds
|
|
5019
|
+
/** Current engine time since start in seconds
|
|
5015
5020
|
* @type {Number}
|
|
5016
5021
|
* @memberof Engine */
|
|
5017
5022
|
let time = 0;
|
|
@@ -5037,12 +5042,12 @@ let frameTimeLastMS = 0, frameTimeBufferMS = 0, averageFPS = 0;
|
|
|
5037
5042
|
|
|
5038
5043
|
///////////////////////////////////////////////////////////////////////////////
|
|
5039
5044
|
|
|
5040
|
-
/**
|
|
5041
|
-
* @param {Function} gameInit
|
|
5042
|
-
* @param {Function} gameUpdate
|
|
5043
|
-
* @param {Function} gameUpdatePost
|
|
5044
|
-
* @param {Function} gameRender
|
|
5045
|
-
* @param {Function} gameRenderPost
|
|
5045
|
+
/** Startup LittleJS engine with your callback functions
|
|
5046
|
+
* @param {Function} gameInit - Called once after the engine starts up, setup the game
|
|
5047
|
+
* @param {Function} gameUpdate - Called every frame at 60 frames per second, handle input and update the game state
|
|
5048
|
+
* @param {Function} gameUpdatePost - Called after physics and objects are updated, setup camera and prepare for render
|
|
5049
|
+
* @param {Function} gameRender - Called before objects are rendered, draw any background effects that appear behind objects
|
|
5050
|
+
* @param {Function} gameRenderPost - Called after objects are rendered, draw effects or hud that appear above all objects
|
|
5046
5051
|
* @param {Array} [imageSources=['tiles.png']] - Image to load
|
|
5047
5052
|
* @memberof Engine */
|
|
5048
5053
|
function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=['tiles.png'])
|
|
@@ -5065,32 +5070,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
5065
5070
|
frameTimeBufferMS += paused ? 0 : frameTimeDeltaMS;
|
|
5066
5071
|
if (!debugSpeedUp)
|
|
5067
5072
|
frameTimeBufferMS = min(frameTimeBufferMS, 50); // clamp incase of slow framerate
|
|
5068
|
-
|
|
5069
|
-
if (canvasFixedSize.x)
|
|
5070
|
-
{
|
|
5071
|
-
// clear canvas and set fixed size
|
|
5072
|
-
mainCanvas.width = canvasFixedSize.x;
|
|
5073
|
-
mainCanvas.height = canvasFixedSize.y;
|
|
5074
|
-
|
|
5075
|
-
// fit to window by adding space on top or bottom if necessary
|
|
5076
|
-
const aspect = innerWidth / innerHeight;
|
|
5077
|
-
const fixedAspect = mainCanvas.width / mainCanvas.height;
|
|
5078
|
-
(glCanvas||mainCanvas).style.width = mainCanvas.style.width = overlayCanvas.style.width = aspect < fixedAspect ? '100%' : '';
|
|
5079
|
-
(glCanvas||mainCanvas).style.height = mainCanvas.style.height = overlayCanvas.style.height = aspect < fixedAspect ? '' : '100%';
|
|
5080
|
-
}
|
|
5081
|
-
else
|
|
5082
|
-
{
|
|
5083
|
-
// clear canvas and set size to same as window
|
|
5084
|
-
mainCanvas.width = min(innerWidth, canvasMaxSize.x);
|
|
5085
|
-
mainCanvas.height = min(innerHeight, canvasMaxSize.y);
|
|
5086
|
-
}
|
|
5087
|
-
|
|
5088
|
-
// clear overlay canvas and set size
|
|
5089
|
-
overlayCanvas.width = mainCanvas.width;
|
|
5090
|
-
overlayCanvas.height = mainCanvas.height;
|
|
5091
|
-
|
|
5092
|
-
// save canvas size
|
|
5093
|
-
mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
|
|
5073
|
+
updateCanvas();
|
|
5094
5074
|
|
|
5095
5075
|
if (paused)
|
|
5096
5076
|
{
|
|
@@ -5164,6 +5144,35 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
5164
5144
|
requestAnimationFrame(engineUpdate);
|
|
5165
5145
|
}
|
|
5166
5146
|
|
|
5147
|
+
function updateCanvas()
|
|
5148
|
+
{
|
|
5149
|
+
if (canvasFixedSize.x)
|
|
5150
|
+
{
|
|
5151
|
+
// clear canvas and set fixed size
|
|
5152
|
+
mainCanvas.width = canvasFixedSize.x;
|
|
5153
|
+
mainCanvas.height = canvasFixedSize.y;
|
|
5154
|
+
|
|
5155
|
+
// fit to window by adding space on top or bottom if necessary
|
|
5156
|
+
const aspect = innerWidth / innerHeight;
|
|
5157
|
+
const fixedAspect = mainCanvas.width / mainCanvas.height;
|
|
5158
|
+
(glCanvas||mainCanvas).style.width = mainCanvas.style.width = overlayCanvas.style.width = aspect < fixedAspect ? '100%' : '';
|
|
5159
|
+
(glCanvas||mainCanvas).style.height = mainCanvas.style.height = overlayCanvas.style.height = aspect < fixedAspect ? '' : '100%';
|
|
5160
|
+
}
|
|
5161
|
+
else
|
|
5162
|
+
{
|
|
5163
|
+
// clear canvas and set size to same as window
|
|
5164
|
+
mainCanvas.width = min(innerWidth, canvasMaxSize.x);
|
|
5165
|
+
mainCanvas.height = min(innerHeight, canvasMaxSize.y);
|
|
5166
|
+
}
|
|
5167
|
+
|
|
5168
|
+
// clear overlay canvas and set size
|
|
5169
|
+
overlayCanvas.width = mainCanvas.width;
|
|
5170
|
+
overlayCanvas.height = mainCanvas.height;
|
|
5171
|
+
|
|
5172
|
+
// save canvas size
|
|
5173
|
+
mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
|
|
5174
|
+
}
|
|
5175
|
+
|
|
5167
5176
|
// setup html
|
|
5168
5177
|
const styleBody =
|
|
5169
5178
|
'margin:0;overflow:hidden;' + // fill the window
|
|
@@ -5188,6 +5197,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
5188
5197
|
const styleCanvas = 'position:absolute;' + // position
|
|
5189
5198
|
'top:50%;left:50%;transform:translate(-50%,-50%)'; // center
|
|
5190
5199
|
(glCanvas||mainCanvas).style.cssText = mainCanvas.style.cssText = overlayCanvas.style.cssText = styleCanvas;
|
|
5200
|
+
updateCanvas();
|
|
5191
5201
|
|
|
5192
5202
|
// create promises for loading images
|
|
5193
5203
|
const promises = imageSources.map((src, textureIndex)=>
|
|
@@ -5384,9 +5394,9 @@ function drawEngineSplashScreen(t)
|
|
|
5384
5394
|
|
|
5385
5395
|
// big stack
|
|
5386
5396
|
rect(50,20,10,-10,color(0,1));
|
|
5387
|
-
rect(50,20,6,-10,color(0,2));
|
|
5388
|
-
rect(50,20,3,-10,color(0,3));
|
|
5389
|
-
rect(50,
|
|
5397
|
+
rect(50,20,6.5,-10,color(0,2));
|
|
5398
|
+
rect(50,20,3.5,-10,color(0,3));
|
|
5399
|
+
rect(50,20,10,-10);
|
|
5390
5400
|
circle(55,2,11.4,.5,PI-.5,color(3,3));
|
|
5391
5401
|
circle(55,2,11.4,.5,PI/2,color(3,2),1);
|
|
5392
5402
|
circle(55,2,11.4,.5,PI-.5);
|
|
@@ -5405,7 +5415,7 @@ function drawEngineSplashScreen(t)
|
|
|
5405
5415
|
|
|
5406
5416
|
// engine outline
|
|
5407
5417
|
circle(36,30,10,PI/2,PI*3/2);
|
|
5408
|
-
circle(
|
|
5418
|
+
circle(48,30,10,PI/2,PI*3/2);
|
|
5409
5419
|
circle(60,30,10);
|
|
5410
5420
|
line(36,20,60,20);
|
|
5411
5421
|
|