littlejsengine 1.12.4 → 1.12.6
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/dist/box2d.wasm.js +630 -0
- package/dist/box2d.wasm.wasm +0 -0
- package/dist/littlejs.d.ts +52 -44
- package/dist/littlejs.esm.js +100 -97
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +98 -96
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +98 -96
- package/examples/box2d/game.js +36 -41
- package/examples/box2d/gameObjects.js +38 -35
- package/examples/box2d/index.html +1 -1
- package/examples/box2d/scenes.js +17 -13
- package/examples/box2d/tiles.png +0 -0
- package/examples/index.html +22 -14
- package/examples/platformer/game.js +6 -15
- package/examples/shorts/base.html +1 -0
- package/examples/shorts/box2d.js +46 -0
- package/examples/shorts/box2dCar.js +49 -0
- package/examples/shorts/postProcess.js +45 -0
- package/examples/shorts/tiles.png +0 -0
- package/examples/shorts/uiSystem.js +39 -0
- package/examples/starter/game.js +2 -0
- package/examples/uiSystem/game.js +1 -1
- package/package.json +1 -1
- package/plugins/box2d.js +23 -29
- package/plugins/pluginExport.js +1 -1
- package/plugins/uiSystem.js +9 -3
- package/src/engine.js +10 -11
- package/src/engineAudio.js +24 -15
- package/src/engineBuild.js +12 -2
- package/src/engineExport.js +1 -0
- package/src/engineInput.js +3 -3
- package/src/engineUtilities.js +16 -0
- package/src/engineWebGL.js +13 -1
package/dist/littlejs.release.js
CHANGED
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
* - Debug functionality is disabled to reduce size and increase performance
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
12
|
let showWatermark = 0;
|
|
15
13
|
let debugKey = '';
|
|
16
14
|
const debug = 0;
|
|
@@ -53,8 +51,6 @@ function debugVideoCaptureUpdate(){}
|
|
|
53
51
|
* @namespace Utilities
|
|
54
52
|
*/
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
58
54
|
/** A shortcut to get Math.PI
|
|
59
55
|
* @type {number}
|
|
60
56
|
* @default Math.PI
|
|
@@ -234,6 +230,16 @@ function wave(frequency=1, amplitude=1, t=time)
|
|
|
234
230
|
* @memberof Utilities */
|
|
235
231
|
function formatTime(t) { return (t/60|0) + ':' + (t%60<10?'0':'') + (t%60|0); }
|
|
236
232
|
|
|
233
|
+
/** Fetches a JSON file from a URL and returns the parsed JSON object. Must be used with await!
|
|
234
|
+
* @param {string} url - URL of JSON file
|
|
235
|
+
* @return {Promise<object>}
|
|
236
|
+
* @memberof Utilities */
|
|
237
|
+
async function fetchJSON(url)
|
|
238
|
+
{
|
|
239
|
+
const response = await fetch(url);
|
|
240
|
+
return response.json();
|
|
241
|
+
}
|
|
242
|
+
|
|
237
243
|
///////////////////////////////////////////////////////////////////////////////
|
|
238
244
|
|
|
239
245
|
/** Random global functions
|
|
@@ -329,6 +335,12 @@ class RandomGenerator
|
|
|
329
335
|
/** Randomly returns either -1 or 1 deterministically
|
|
330
336
|
* @return {number} */
|
|
331
337
|
sign() { return this.float() > .5 ? 1 : -1; }
|
|
338
|
+
|
|
339
|
+
/** Returns a seeded random value between the two values passed in with a random sign
|
|
340
|
+
* @param {number} [valueA]
|
|
341
|
+
* @param {number} [valueB]
|
|
342
|
+
* @return {number} */
|
|
343
|
+
floatSign(valueA=1, valueB=0) { return this.float(valueA, valueB) * this.sign(); }
|
|
332
344
|
}
|
|
333
345
|
|
|
334
346
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -969,8 +981,6 @@ class Timer
|
|
|
969
981
|
* @namespace Settings
|
|
970
982
|
*/
|
|
971
983
|
|
|
972
|
-
|
|
973
|
-
|
|
974
984
|
///////////////////////////////////////////////////////////////////////////////
|
|
975
985
|
// Camera settings
|
|
976
986
|
|
|
@@ -1455,8 +1465,6 @@ function setDebugKey(key) { debugKey = key; }
|
|
|
1455
1465
|
* LittleJS Object System
|
|
1456
1466
|
*/
|
|
1457
1467
|
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
1468
|
/**
|
|
1461
1469
|
* LittleJS Object Base Object Class
|
|
1462
1470
|
* - Top level object class used by the engine
|
|
@@ -1939,8 +1947,6 @@ class EngineObject
|
|
|
1939
1947
|
* @namespace Draw
|
|
1940
1948
|
*/
|
|
1941
1949
|
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
1950
|
/** The primary 2D canvas visible to the user
|
|
1945
1951
|
* @type {HTMLCanvasElement}
|
|
1946
1952
|
* @memberof Draw */
|
|
@@ -2562,8 +2568,6 @@ function setCursor(cursorStyle = 'auto')
|
|
|
2562
2568
|
* @namespace Input
|
|
2563
2569
|
*/
|
|
2564
2570
|
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
2571
|
/** Returns true if device key is down
|
|
2568
2572
|
* @param {string|number} key
|
|
2569
2573
|
* @param {number} [device]
|
|
@@ -2615,21 +2619,21 @@ function clearInput() { inputData = [[]]; touchGamepadButtons = []; }
|
|
|
2615
2619
|
* @param {number} button
|
|
2616
2620
|
* @return {boolean}
|
|
2617
2621
|
* @memberof Input */
|
|
2618
|
-
|
|
2622
|
+
function mouseIsDown(button) { return keyIsDown(button); }
|
|
2619
2623
|
|
|
2620
2624
|
/** Returns true if mouse button was pressed
|
|
2621
2625
|
* @function
|
|
2622
2626
|
* @param {number} button
|
|
2623
2627
|
* @return {boolean}
|
|
2624
2628
|
* @memberof Input */
|
|
2625
|
-
|
|
2629
|
+
function mouseWasPressed(button) { return keyWasPressed(button); }
|
|
2626
2630
|
|
|
2627
2631
|
/** Returns true if mouse button was released
|
|
2628
2632
|
* @function
|
|
2629
2633
|
* @param {number} button
|
|
2630
2634
|
* @return {boolean}
|
|
2631
2635
|
* @memberof Input */
|
|
2632
|
-
|
|
2636
|
+
function mouseWasReleased(button) { return keyWasReleased(button); }
|
|
2633
2637
|
|
|
2634
2638
|
/** Mouse pos in world space
|
|
2635
2639
|
* @type {Vector2}
|
|
@@ -3088,8 +3092,6 @@ function touchGamepadRender()
|
|
|
3088
3092
|
* @namespace Audio
|
|
3089
3093
|
*/
|
|
3090
3094
|
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
3095
|
/** Audio context used by the engine
|
|
3094
3096
|
* @type {AudioContext}
|
|
3095
3097
|
* @memberof Audio */
|
|
@@ -3126,17 +3128,17 @@ class Sound
|
|
|
3126
3128
|
{
|
|
3127
3129
|
/** Create a sound object and cache the zzfx samples for later use
|
|
3128
3130
|
* @param {Array} zzfxSound - Array of zzfx parameters, ex. [.5,.5]
|
|
3129
|
-
* @param {number} [range=soundDefaultRange] - World space max range of sound
|
|
3131
|
+
* @param {number} [range=soundDefaultRange] - World space max range of sound
|
|
3130
3132
|
* @param {number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
|
|
3131
3133
|
*/
|
|
3132
3134
|
constructor(zzfxSound, range=soundDefaultRange, taper=soundDefaultTaper)
|
|
3133
3135
|
{
|
|
3134
3136
|
if (!soundEnable || headlessMode) return;
|
|
3135
3137
|
|
|
3136
|
-
/** @property {number} - World space max range of sound
|
|
3138
|
+
/** @property {number} - World space max range of sound */
|
|
3137
3139
|
this.range = range;
|
|
3138
3140
|
|
|
3139
|
-
/** @property {number} - At what percentage of range should it start tapering
|
|
3141
|
+
/** @property {number} - At what percentage of range should it start tapering */
|
|
3140
3142
|
this.taper = taper;
|
|
3141
3143
|
|
|
3142
3144
|
/** @property {number} - How much to randomize frequency each time sound plays */
|
|
@@ -3252,8 +3254,8 @@ class SoundWave extends Sound
|
|
|
3252
3254
|
/** Create a sound object and cache the wave file for later use
|
|
3253
3255
|
* @param {string} filename - Filename of audio file to load
|
|
3254
3256
|
* @param {number} [randomness] - How much to randomize frequency each time sound plays
|
|
3255
|
-
* @param {number} [range=soundDefaultRange] - World space max range of sound
|
|
3256
|
-
* @param {number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
|
|
3257
|
+
* @param {number} [range=soundDefaultRange] - World space max range of sound
|
|
3258
|
+
* @param {number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering
|
|
3257
3259
|
* @param {Function} [onloadCallback] - callback function to call when sound is loaded
|
|
3258
3260
|
*/
|
|
3259
3261
|
constructor(filename, randomness=0, range, taper, onloadCallback)
|
|
@@ -3261,17 +3263,26 @@ class SoundWave extends Sound
|
|
|
3261
3263
|
super(undefined, range, taper);
|
|
3262
3264
|
if (!soundEnable || headlessMode) return;
|
|
3263
3265
|
|
|
3266
|
+
/** @property {Function} - callback function to call when sound is loaded */
|
|
3267
|
+
this.onloadCallback = onloadCallback;
|
|
3264
3268
|
this.randomness = randomness;
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3269
|
+
this.loadSound(filename);
|
|
3270
|
+
}
|
|
3271
|
+
|
|
3272
|
+
/** Loads a sound from a URL and decodes it into sample data. Must be used with await!
|
|
3273
|
+
* @param {string} filename
|
|
3274
|
+
* @return {Promise<void>} */
|
|
3275
|
+
async loadSound(filename)
|
|
3276
|
+
{
|
|
3277
|
+
const response = await fetch(filename);
|
|
3278
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
3279
|
+
const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
|
|
3280
|
+
this.sampleChannels = [];
|
|
3281
|
+
for (let i = audioBuffer.numberOfChannels; i--;)
|
|
3282
|
+
this.sampleChannels[i] = Array.from(audioBuffer.getChannelData(i));
|
|
3283
|
+
this.sampleRate = audioBuffer.sampleRate;
|
|
3284
|
+
if (this.onloadCallback)
|
|
3285
|
+
this.onloadCallback();
|
|
3275
3286
|
}
|
|
3276
3287
|
}
|
|
3277
3288
|
|
|
@@ -3551,8 +3562,6 @@ function zzfxG
|
|
|
3551
3562
|
* @namespace TileCollision
|
|
3552
3563
|
*/
|
|
3553
3564
|
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
3565
|
///////////////////////////////////////////////////////////////////////////////
|
|
3557
3566
|
// Tile Layer System
|
|
3558
3567
|
|
|
@@ -4016,8 +4025,6 @@ class TileCollisionLayer extends TileLayer
|
|
|
4016
4025
|
* LittleJS Particle System
|
|
4017
4026
|
*/
|
|
4018
4027
|
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
4028
|
/**
|
|
4022
4029
|
* Particle Emitter - Spawns particles with the given settings
|
|
4023
4030
|
* @extends EngineObject
|
|
@@ -4362,8 +4369,6 @@ class Particle extends EngineObject
|
|
|
4362
4369
|
* @namespace Medals
|
|
4363
4370
|
*/
|
|
4364
4371
|
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
4372
|
/** List of all medals
|
|
4368
4373
|
* @type {Object}
|
|
4369
4374
|
* @memberof Medals */
|
|
@@ -4551,8 +4556,6 @@ class Medal
|
|
|
4551
4556
|
* @namespace WebGL
|
|
4552
4557
|
*/
|
|
4553
4558
|
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
4559
|
/** The WebGL canvas which appears above the main canvas and below the overlay canvas
|
|
4557
4560
|
* @type {HTMLCanvasElement}
|
|
4558
4561
|
* @memberof WebGL */
|
|
@@ -4751,7 +4754,19 @@ function glCreateTexture(image)
|
|
|
4751
4754
|
const texture = glContext.createTexture();
|
|
4752
4755
|
glContext.bindTexture(glContext.TEXTURE_2D, texture);
|
|
4753
4756
|
if (image && image.width)
|
|
4757
|
+
{
|
|
4754
4758
|
glSetTextureData(texture, image);
|
|
4759
|
+
|
|
4760
|
+
const isPowerOfTwo = (value)=> !(value & (value - 1));
|
|
4761
|
+
if (!tilesPixelated && isPowerOfTwo(image.width) && isPowerOfTwo(image.height))
|
|
4762
|
+
{
|
|
4763
|
+
// use mipmap filtering
|
|
4764
|
+
glContext.generateMipmap(glContext.TEXTURE_2D);
|
|
4765
|
+
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MIN_FILTER, glContext.LINEAR_MIPMAP_LINEAR);
|
|
4766
|
+
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MAG_FILTER, glContext.LINEAR);
|
|
4767
|
+
return texture;
|
|
4768
|
+
}
|
|
4769
|
+
}
|
|
4755
4770
|
else
|
|
4756
4771
|
{
|
|
4757
4772
|
// create a white texture
|
|
@@ -4759,7 +4774,7 @@ function glCreateTexture(image)
|
|
|
4759
4774
|
glContext.texImage2D(glContext.TEXTURE_2D, 0, glContext.RGBA, 1, 1, 0, glContext.RGBA, glContext.UNSIGNED_BYTE, whitePixel);
|
|
4760
4775
|
}
|
|
4761
4776
|
|
|
4762
|
-
//
|
|
4777
|
+
// set texture filtering
|
|
4763
4778
|
const filter = tilesPixelated ? glContext.NEAREST : glContext.LINEAR;
|
|
4764
4779
|
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MIN_FILTER, filter);
|
|
4765
4780
|
glContext.texParameteri(glContext.TEXTURE_2D, glContext.TEXTURE_MAG_FILTER, filter);
|
|
@@ -4875,8 +4890,6 @@ function glDraw(x, y, sizeX, sizeY, angle, uv0X, uv0Y, uv1X, uv1Y, rgba=-1, rgba
|
|
|
4875
4890
|
* @namespace Engine
|
|
4876
4891
|
*/
|
|
4877
4892
|
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
4893
|
/** Name of engine
|
|
4881
4894
|
* @type {string}
|
|
4882
4895
|
* @default
|
|
@@ -4887,7 +4900,7 @@ const engineName = 'LittleJS';
|
|
|
4887
4900
|
* @type {string}
|
|
4888
4901
|
* @default
|
|
4889
4902
|
* @memberof Engine */
|
|
4890
|
-
const engineVersion = '1.12.
|
|
4903
|
+
const engineVersion = '1.12.6';
|
|
4891
4904
|
|
|
4892
4905
|
/** Frames per second to update
|
|
4893
4906
|
* @type {number}
|
|
@@ -4969,7 +4982,7 @@ function engineAddPlugin(updateFunction, renderFunction)
|
|
|
4969
4982
|
* @param {Array<string>} [imageSources=[]] - List of images to load
|
|
4970
4983
|
* @param {HTMLElement} [rootElement] - Root element to attach to, the document body by default
|
|
4971
4984
|
* @memberof Engine */
|
|
4972
|
-
function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
|
|
4985
|
+
async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
|
|
4973
4986
|
{
|
|
4974
4987
|
ASSERT(!mainContext, 'engine already initialized');
|
|
4975
4988
|
ASSERT(Array.isArray(imageSources), 'pass in images as array');
|
|
@@ -5126,16 +5139,14 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
5126
5139
|
mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
|
|
5127
5140
|
}
|
|
5128
5141
|
|
|
5129
|
-
|
|
5142
|
+
// wait for gameInit to load
|
|
5143
|
+
async function startEngine()
|
|
5130
5144
|
{
|
|
5131
|
-
|
|
5145
|
+
await gameInit();
|
|
5146
|
+
engineUpdate();
|
|
5132
5147
|
}
|
|
5133
|
-
|
|
5134
5148
|
if (headlessMode)
|
|
5135
|
-
|
|
5136
|
-
startEngine();
|
|
5137
|
-
return;
|
|
5138
|
-
}
|
|
5149
|
+
return startEngine();
|
|
5139
5150
|
|
|
5140
5151
|
// setup html
|
|
5141
5152
|
const styleRoot =
|
|
@@ -5211,8 +5222,9 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
5211
5222
|
}));
|
|
5212
5223
|
}
|
|
5213
5224
|
|
|
5214
|
-
//
|
|
5215
|
-
Promise.all(promises)
|
|
5225
|
+
// wait for all the promises to finish
|
|
5226
|
+
await Promise.all(promises);
|
|
5227
|
+
return startEngine();
|
|
5216
5228
|
}
|
|
5217
5229
|
|
|
5218
5230
|
/** Update each engine object, remove destroyed objects, and update time
|
|
@@ -5491,8 +5503,6 @@ function drawEngineSplashScreen(t)
|
|
|
5491
5503
|
* - Functions to unlock medals
|
|
5492
5504
|
*/
|
|
5493
5505
|
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
5506
|
/** Global Newgrounds object
|
|
5497
5507
|
* @type {NewgroundsPlugin}
|
|
5498
5508
|
* @memberof Medal */
|
|
@@ -5666,8 +5676,6 @@ class NewgroundsPlugin
|
|
|
5666
5676
|
* - can be enabled to pass other canvases through a final shader
|
|
5667
5677
|
*/
|
|
5668
5678
|
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
5679
|
///////////////////////////////////////////////////////////////////////////////
|
|
5672
5680
|
|
|
5673
5681
|
/** Global Post Process plugin object
|
|
@@ -5780,8 +5788,6 @@ class PostProcessPlugin
|
|
|
5780
5788
|
* LittleJS ZzFXM Plugin
|
|
5781
5789
|
*/
|
|
5782
5790
|
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
5791
|
/**
|
|
5786
5792
|
* Music Object - Stores a zzfx music track for later use
|
|
5787
5793
|
*
|
|
@@ -5950,8 +5956,6 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
|
|
|
5950
5956
|
* - Images
|
|
5951
5957
|
*/
|
|
5952
5958
|
|
|
5953
|
-
|
|
5954
|
-
|
|
5955
5959
|
///////////////////////////////////////////////////////////////////////////////
|
|
5956
5960
|
|
|
5957
5961
|
/** Global UI system plugin object
|
|
@@ -6119,6 +6123,8 @@ class UIObject
|
|
|
6119
6123
|
this.lineWidth = uiSystem.defaultLineWidth;
|
|
6120
6124
|
/** @property {string} */
|
|
6121
6125
|
this.font = uiSystem.defaultFont;
|
|
6126
|
+
/** @property {number} - override for text height */
|
|
6127
|
+
this.textHeight = undefined;
|
|
6122
6128
|
/** @property {boolean} */
|
|
6123
6129
|
this.visible = true;
|
|
6124
6130
|
/** @property {Array<UIObject>} */
|
|
@@ -6229,7 +6235,8 @@ class UIText extends UIObject
|
|
|
6229
6235
|
}
|
|
6230
6236
|
render()
|
|
6231
6237
|
{
|
|
6232
|
-
|
|
6238
|
+
const textSize = vec2(this.size.x, this.textHeight || this.size.y);
|
|
6239
|
+
uiSystem.drawText(this.text, this.pos, textSize, this.textColor, this.lineWidth, this.lineColor, this.align, this.font);
|
|
6233
6240
|
}
|
|
6234
6241
|
}
|
|
6235
6242
|
|
|
@@ -6292,7 +6299,9 @@ class UIButton extends UIObject
|
|
|
6292
6299
|
const lineColor = this.mouseIsHeld ? this.color : this.lineColor;
|
|
6293
6300
|
const color = this.mouseIsOver? this.hoverColor : this.color;
|
|
6294
6301
|
uiSystem.drawRect(this.pos, this.size, color, this.lineWidth, lineColor);
|
|
6295
|
-
|
|
6302
|
+
|
|
6303
|
+
const textScale = .8; // scale text to fit in button
|
|
6304
|
+
const textSize = vec2(this.size.x, this.textHeight || this.size.y*textScale);
|
|
6296
6305
|
uiSystem.drawText(this.text, this.pos, textSize,
|
|
6297
6306
|
this.textColor, 0, undefined, this.align, this.font);
|
|
6298
6307
|
}
|
|
@@ -6389,7 +6398,8 @@ class UIScrollbar extends UIObject
|
|
|
6389
6398
|
const barColor = this.mouseIsHeld ? this.color : this.handleColor;
|
|
6390
6399
|
uiSystem.drawRect(handlePos, handleSize, barColor, this.lineWidth, this.lineColor);
|
|
6391
6400
|
|
|
6392
|
-
const
|
|
6401
|
+
const textScale = .8; // scale text to fit in scrollbar
|
|
6402
|
+
const textSize = vec2(this.size.x, this.textHeight || this.size.y*textScale);
|
|
6393
6403
|
uiSystem.drawText(this.text, this.pos, textSize,
|
|
6394
6404
|
this.textColor, 0, undefined, this.align, this.font);
|
|
6395
6405
|
}
|
|
@@ -6398,31 +6408,33 @@ class UIScrollbar extends UIObject
|
|
|
6398
6408
|
/**
|
|
6399
6409
|
* LittleJS Box2D Physics Plugin
|
|
6400
6410
|
* - Box2dObject extends EngineObject with Box2D physics
|
|
6401
|
-
* - Call
|
|
6411
|
+
* - Call box2dInit() before engineInit() to enable
|
|
6402
6412
|
* - You will also need to include box2d.wasm.js
|
|
6403
|
-
* - Uses
|
|
6413
|
+
* - Uses a super fast web assembly port of Box2D
|
|
6404
6414
|
* - More info: https://github.com/kripken/box2d.js
|
|
6405
|
-
* - Fully wraps everything in Box2d
|
|
6406
6415
|
* - Functions to create polygon, circle, and edge shapes
|
|
6407
|
-
* - Raycasting and querying
|
|
6408
|
-
* - Joint creation
|
|
6409
6416
|
* - Contact begin and end callbacks
|
|
6417
|
+
* - Wraps b2Vec2 type to/from Vector2
|
|
6418
|
+
* - Raycasting and querying
|
|
6419
|
+
* - Every type of joint
|
|
6410
6420
|
* - Debug physics drawing
|
|
6421
|
+
* @namespace Box2D
|
|
6411
6422
|
*/
|
|
6412
6423
|
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
6424
|
/** Global Box2d Plugin object
|
|
6416
|
-
* @type {Box2dPlugin}
|
|
6425
|
+
* @type {Box2dPlugin}
|
|
6426
|
+
* @memberof Box2D */
|
|
6417
6427
|
let box2d;
|
|
6418
6428
|
|
|
6419
6429
|
/** Enable Box2D debug drawing
|
|
6420
6430
|
* @type {boolean}
|
|
6421
|
-
* @default
|
|
6431
|
+
* @default
|
|
6432
|
+
* @memberof Box2D */
|
|
6422
6433
|
let box2dDebug = false;
|
|
6423
6434
|
|
|
6424
6435
|
/** Enable Box2D debug drawing
|
|
6425
|
-
* @param {boolean} enable
|
|
6436
|
+
* @param {boolean} enable
|
|
6437
|
+
* @memberof Box2D */
|
|
6426
6438
|
function box2dSetDebug(enable) { box2dDebug = enable; }
|
|
6427
6439
|
|
|
6428
6440
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -6524,7 +6536,7 @@ class Box2dObject extends EngineObject
|
|
|
6524
6536
|
* @param {number} [friction]
|
|
6525
6537
|
* @param {number} [restitution]
|
|
6526
6538
|
* @param {boolean} [isSensor] */
|
|
6527
|
-
addShape(shape, density=1, friction
|
|
6539
|
+
addShape(shape, density=1, friction=1, restitution=0, isSensor=false)
|
|
6528
6540
|
{
|
|
6529
6541
|
const fd = new box2d.instance.b2FixtureDef();
|
|
6530
6542
|
fd.set_shape(shape);
|
|
@@ -8163,28 +8175,18 @@ class Box2dPlugin
|
|
|
8163
8175
|
}
|
|
8164
8176
|
|
|
8165
8177
|
///////////////////////////////////////////////////////////////////////////////
|
|
8166
|
-
/** Box2d Init -
|
|
8167
|
-
* @
|
|
8168
|
-
* @
|
|
8169
|
-
|
|
8170
|
-
* @param {Function} gameRender - Called before objects are rendered, for drawing the background
|
|
8171
|
-
* @param {Function} gameRenderPost - Called after objects are rendered, useful for drawing UI
|
|
8172
|
-
* @param {Array<string>} [imageSources=[]] - List of images to load
|
|
8173
|
-
* @param {HTMLElement} [rootElement] - Root element to attach to, the document body by default */
|
|
8174
|
-
function box2dEngineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources, rootElement)
|
|
8178
|
+
/** Box2d Init - Call with await before starting LittleJS to init box2d
|
|
8179
|
+
* @return {Promise<Box2dPlugin>}
|
|
8180
|
+
* @memberof Box2D */
|
|
8181
|
+
async function box2dInit()
|
|
8175
8182
|
{
|
|
8176
|
-
|
|
8177
|
-
|
|
8178
|
-
|
|
8179
|
-
|
|
8180
|
-
|
|
8181
|
-
|
|
8182
|
-
// start littlejs
|
|
8183
|
-
engineAddPlugin(box2dUpdate, box2dRender);
|
|
8184
|
-
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources, rootElement);
|
|
8185
|
-
});
|
|
8183
|
+
// load box2d
|
|
8184
|
+
new Box2dPlugin(await Box2D());
|
|
8185
|
+
setupDebugDraw();
|
|
8186
|
+
engineAddPlugin(box2dUpdate, box2dRender);
|
|
8187
|
+
return box2d;
|
|
8186
8188
|
|
|
8187
|
-
//
|
|
8189
|
+
// add the box2d plugin to the engine
|
|
8188
8190
|
function box2dUpdate()
|
|
8189
8191
|
{
|
|
8190
8192
|
if (!paused)
|
package/examples/box2d/game.js
CHANGED
|
@@ -17,24 +17,21 @@ import * as GameObjects from './gameObjects.js';
|
|
|
17
17
|
import * as Scenes from './scenes.js';
|
|
18
18
|
const {vec2, hsl} = LJS;
|
|
19
19
|
|
|
20
|
+
// use HD textures
|
|
21
|
+
LJS.setCanvasPixelated(false);
|
|
22
|
+
LJS.setTilesPixelated(false);
|
|
23
|
+
|
|
20
24
|
///////////////////////////////////////////////////////////////////////////////
|
|
21
25
|
// game variables
|
|
22
26
|
|
|
23
|
-
//LJS.box2dSetDebug(true); // enable box2d debug draw
|
|
24
|
-
|
|
25
27
|
const maxScenes = 11;
|
|
26
|
-
|
|
27
|
-
export let spriteAtlas, groundObject,
|
|
28
|
+
const startScene = 0;
|
|
29
|
+
export let spriteAtlas, groundObject, mouseJoint, repeatSpawnTimer = new LJS.Timer;
|
|
28
30
|
const sound_click = new LJS.Sound([.2,.1,,,,.01,,,,,,,,,,,,,,,-500]);
|
|
29
31
|
|
|
30
|
-
export function setSceneName(name) { sceneName = name; }
|
|
31
|
-
export function setCarObject(carObject) { car = carObject; }
|
|
32
|
-
|
|
33
32
|
///////////////////////////////////////////////////////////////////////////////
|
|
34
|
-
function setScene(
|
|
33
|
+
function setScene(scene)
|
|
35
34
|
{
|
|
36
|
-
scene = _scene;
|
|
37
|
-
|
|
38
35
|
// setup
|
|
39
36
|
LJS.setCameraPos(vec2(20,10));
|
|
40
37
|
LJS.setGravity(vec2(0,-20));
|
|
@@ -42,7 +39,6 @@ function setScene(_scene)
|
|
|
42
39
|
// destroy old scene
|
|
43
40
|
LJS.engineObjectsDestroy();
|
|
44
41
|
mouseJoint = 0;
|
|
45
|
-
car = 0;
|
|
46
42
|
|
|
47
43
|
// create walls
|
|
48
44
|
groundObject = GameObjects.spawnBox(vec2(0,-4), vec2(1e3,8), hsl(0,0,.2), LJS.box2d.bodyTypeStatic);
|
|
@@ -55,10 +51,14 @@ function setScene(_scene)
|
|
|
55
51
|
}
|
|
56
52
|
|
|
57
53
|
///////////////////////////////////////////////////////////////////////////////
|
|
58
|
-
function gameInit()
|
|
54
|
+
async function gameInit()
|
|
59
55
|
{
|
|
56
|
+
// start up LittleJS Box2D plugin
|
|
57
|
+
await LJS.box2dInit();
|
|
58
|
+
//LJS.box2dSetDebug(true); // enable box2d debug draw
|
|
59
|
+
|
|
60
60
|
// create a table of all sprites
|
|
61
|
-
const gameTile = (i)=> LJS.tile(i,
|
|
61
|
+
const gameTile = (i)=> LJS.tile(i, 496, 0, 8);
|
|
62
62
|
spriteAtlas =
|
|
63
63
|
{
|
|
64
64
|
circle: gameTile(0),
|
|
@@ -70,7 +70,7 @@ function gameInit()
|
|
|
70
70
|
squareOutline2: gameTile(6),
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
-
setScene(
|
|
73
|
+
setScene(startScene);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -80,7 +80,19 @@ function gameUpdate()
|
|
|
80
80
|
LJS.setCameraScale(LJS.mainCanvasSize.y * 48 / 1080);
|
|
81
81
|
|
|
82
82
|
// mouse controls
|
|
83
|
-
if (
|
|
83
|
+
if (mouseJoint)
|
|
84
|
+
{
|
|
85
|
+
// update mouse joint
|
|
86
|
+
mouseJoint.setTarget(LJS.mousePos);
|
|
87
|
+
if (LJS.mouseWasReleased(0))
|
|
88
|
+
{
|
|
89
|
+
// release object
|
|
90
|
+
sound_click.play(LJS.mousePos, 1, .5);
|
|
91
|
+
mouseJoint.destroy();
|
|
92
|
+
mouseJoint = 0;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else if (LJS.mouseWasPressed(0))
|
|
84
96
|
{
|
|
85
97
|
// grab object
|
|
86
98
|
sound_click.play(LJS.mousePos);
|
|
@@ -88,16 +100,8 @@ function gameUpdate()
|
|
|
88
100
|
if (object)
|
|
89
101
|
mouseJoint = new LJS.Box2dTargetJoint(object, groundObject, LJS.mousePos);
|
|
90
102
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// release object
|
|
94
|
-
sound_click.play(LJS.mousePos, 1, .5);
|
|
95
|
-
if (mouseJoint)
|
|
96
|
-
{
|
|
97
|
-
mouseJoint.destroy();
|
|
98
|
-
mouseJoint = 0;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
103
|
+
|
|
104
|
+
// controls
|
|
101
105
|
if (LJS.mouseIsDown(1) || LJS.mouseIsDown('KeyZ'))
|
|
102
106
|
{
|
|
103
107
|
const isSet = repeatSpawnTimer.isSet();
|
|
@@ -112,23 +116,14 @@ function gameUpdate()
|
|
|
112
116
|
repeatSpawnTimer.unset();
|
|
113
117
|
if (LJS.mouseWasPressed(2) || LJS.keyWasPressed('KeyX'))
|
|
114
118
|
GameObjects.explosion(LJS.mousePos);
|
|
115
|
-
if (mouseJoint)
|
|
116
|
-
mouseJoint.setTarget(LJS.mousePos);
|
|
117
119
|
|
|
118
120
|
if (LJS.keyWasPressed('KeyR'))
|
|
119
121
|
setScene(scene); // reset scene
|
|
120
122
|
if (LJS.keyWasPressed('ArrowUp') || LJS.keyWasPressed('ArrowDown'))
|
|
121
123
|
{
|
|
122
124
|
// change scene
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
setScene(scene);
|
|
126
|
-
}
|
|
127
|
-
if (car)
|
|
128
|
-
{
|
|
129
|
-
// update car controls
|
|
130
|
-
const input = LJS.keyDirection();
|
|
131
|
-
car.applyMotorInput(-input.x);
|
|
125
|
+
const upPressed = LJS.keyWasPressed('ArrowUp');
|
|
126
|
+
setScene(LJS.mod(Scenes.scene + (upPressed?1:-1), maxScenes));
|
|
132
127
|
}
|
|
133
128
|
}
|
|
134
129
|
|
|
@@ -144,7 +139,7 @@ function gameRender()
|
|
|
144
139
|
// draw a grey square in the background without using webgl
|
|
145
140
|
LJS.drawRect(vec2(20,8), vec2(100), hsl(0,0,.8), 0, 0);
|
|
146
141
|
|
|
147
|
-
if (scene == 5)
|
|
142
|
+
if (Scenes.scene == 5)
|
|
148
143
|
{
|
|
149
144
|
// raycast test
|
|
150
145
|
const count = 100;
|
|
@@ -174,15 +169,15 @@ function gameRenderPost()
|
|
|
174
169
|
// draw to overlay canvas for hud rendering
|
|
175
170
|
const pos = vec2(LJS.mainCanvasSize.x/2, 50);
|
|
176
171
|
drawText('LittleJS Box2D Demo', 80, 80);
|
|
177
|
-
drawText(sceneName, 60, 100);
|
|
178
|
-
if (scene == 0)
|
|
172
|
+
drawText(Scenes.sceneName, 60, 100);
|
|
173
|
+
if (Scenes.scene == 0)
|
|
179
174
|
{
|
|
180
175
|
drawText('Mouse Left = Grab');
|
|
181
176
|
drawText('Mouse Middle or Z = Spawn');
|
|
182
177
|
drawText('Mouse Right or X = Explode');
|
|
183
178
|
drawText('Arrows Up/Down = Change Scene');
|
|
184
179
|
}
|
|
185
|
-
if (scene == 3)
|
|
180
|
+
if (Scenes.scene == 3)
|
|
186
181
|
{
|
|
187
182
|
drawText('Right = Accelerate');
|
|
188
183
|
drawText('Left = Reverse');
|
|
@@ -195,4 +190,4 @@ function gameRenderPost()
|
|
|
195
190
|
///////////////////////////////////////////////////////////////////////////////
|
|
196
191
|
// Startup LittleJS Engine with Box2D
|
|
197
192
|
|
|
198
|
-
LJS.
|
|
193
|
+
LJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
|