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.
@@ -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
- const mouseIsDown = keyIsDown;
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
- const mouseWasPressed = keyWasPressed;
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
- const mouseWasReleased = keyWasReleased;
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, will not play if camera is farther away
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, will not play if camera is farther away */
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 off */
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, will not play if camera is farther away
3256
- * @param {number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering off
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
- fetch(filename)
3266
- .then(response => response.arrayBuffer())
3267
- .then(arrayBuffer => audioContext.decodeAudioData(arrayBuffer))
3268
- .then(audioBuffer =>
3269
- {
3270
- this.sampleChannels = [];
3271
- for (let i = audioBuffer.numberOfChannels; i--;)
3272
- this.sampleChannels[i] = Array.from(audioBuffer.getChannelData(i));
3273
- this.sampleRate = audioBuffer.sampleRate;
3274
- }).then(() => onloadCallback && onloadCallback(this));
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
- // use point filtering for pixelated rendering
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.4';
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
- function startEngine()
5142
+ // wait for gameInit to load
5143
+ async function startEngine()
5130
5144
  {
5131
- new Promise((resolve) => resolve(gameInit())).then(engineUpdate);
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
- // load all of the images
5215
- Promise.all(promises).then(startEngine);
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
- uiSystem.drawText(this.text, this.pos, this.size, this.textColor, this.lineWidth, this.lineColor, this.align, this.font);
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
- const textSize = vec2(this.size.x, this.size.y*.8);
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 textSize = vec2(this.size.x, this.size.y*.8);
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 box2dEngineInit() to start instead of normal engineInit()
6411
+ * - Call box2dInit() before engineInit() to enable
6402
6412
  * - You will also need to include box2d.wasm.js
6403
- * - Uses box2d.js super fast web assembly port of Box2D
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=.2, restitution=0, isSensor=false)
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 - Startup LittleJS engine with your callback functions
8167
- * @param {Function|function():Promise} gameInit - Called once after the engine starts up
8168
- * @param {Function} gameUpdate - Called every frame before objects are updated
8169
- * @param {Function} gameUpdatePost - Called after physics and objects are updated, even when paused
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
- Box2D().then(box2dInstance=>
8177
- {
8178
- // create box2d object
8179
- new Box2dPlugin(box2dInstance);
8180
- setupDebugDraw();
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
- // hook up box2d plugin to update and render
8189
+ // add the box2d plugin to the engine
8188
8190
  function box2dUpdate()
8189
8191
  {
8190
8192
  if (!paused)
@@ -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
- export let scene = 0, sceneName;
27
- export let spriteAtlas, groundObject, car, mouseJoint, repeatSpawnTimer = new LJS.Timer;
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(_scene)
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, 16, 0, 1);
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(scene);
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 (LJS.mouseWasPressed(0))
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
- if (LJS.mouseWasReleased(0))
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
- scene += LJS.keyWasPressed('ArrowUp') ? 1 : -1;
124
- scene = LJS.mod(scene, maxScenes);
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.box2dEngineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
193
+ LJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);