littlejsengine 1.6.92 → 1.7.1

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.
@@ -6,6 +6,6 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.js?1691></script>
10
- <script src=gameObjects.js?1691></script>
11
- <script src=game.js?1691></script>
9
+ <script src=../../build/littlejs.js?1701></script>
10
+ <script src=gameObjects.js?1701></script>
11
+ <script src=game.js?1701></script>
@@ -6,5 +6,5 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.js?1691></script>
10
- <script src=game.js?1691></script>
9
+ <script src=../../build/littlejs.js?1701></script>
10
+ <script src=game.js?1701></script>
@@ -7,7 +7,7 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- LittleJS Engine -->
10
- <script src=../../build/littlejs.js?1691></script>
10
+ <script src=../../build/littlejs.js?1701></script>
11
11
 
12
12
  <!-- Add your game scripts here -->
13
- <script src=game.js?1691></script>
13
+ <script src=game.js?1701></script>
@@ -1,18 +1,18 @@
1
1
  <head><title>LittleJS JS13K Project</title></head>
2
2
 
3
3
  <!-- LittleJS Engine -->
4
- <script src=../../src/engineDebug.js?1691></script>
5
- <script src=../../src/engineUtilities.js?1691></script>
6
- <script src=../../src/engineSettings.js?1691></script>
7
- <script src=../../src/engineObject.js?1691></script>
8
- <script src=../../src/engineDraw.js?1691></script>
9
- <script src=../../src/engineInput.js?1691></script>
10
- <script src=../../src/engineAudio.js?1691></script>
11
- <script src=../../src/engineTileLayer.js?1691></script>
12
- <script src=../../src/engineParticles.js?1691></script>
13
- <script src=../../src/engineMedals.js?1691></script>
14
- <script src=../../src/engineWebGL.js?1691></script>
15
- <script src=../../src/engine.js?1691></script>
4
+ <script src=../../src/engineDebug.js?1701></script>
5
+ <script src=../../src/engineUtilities.js?1701></script>
6
+ <script src=../../src/engineSettings.js?1701></script>
7
+ <script src=../../src/engineObject.js?1701></script>
8
+ <script src=../../src/engineDraw.js?1701></script>
9
+ <script src=../../src/engineInput.js?1701></script>
10
+ <script src=../../src/engineAudio.js?1701></script>
11
+ <script src=../../src/engineTileLayer.js?1701></script>
12
+ <script src=../../src/engineParticles.js?1701></script>
13
+ <script src=../../src/engineMedals.js?1701></script>
14
+ <script src=../../src/engineWebGL.js?1701></script>
15
+ <script src=../../src/engine.js?1701></script>
16
16
 
17
17
  <!-- Add your game scripts here -->
18
- <script src=game.js?1691></script>
18
+ <script src=game.js?1701></script>
@@ -7,4 +7,4 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- Add your game scripts here -->
10
- <script src=game.js?1691 type=module></script>
10
+ <script src=game.js?1701 type=module></script>
@@ -10,7 +10,7 @@ button { margin:1px; }
10
10
  </style>
11
11
  </head><body>
12
12
 
13
- <script src=../../build/littlejs.js?1691></script>
13
+ <script src=../../build/littlejs.js?1701></script>
14
14
  <script>
15
15
 
16
16
  'use strict';
@@ -69,7 +69,7 @@ function explosion(pos, radius=3)
69
69
  }
70
70
 
71
71
  // cleanup neighbors
72
- const cleanupRadius = radius + 1;
72
+ const cleanupRadius = radius + 2;
73
73
  for (let x = -cleanupRadius; x < cleanupRadius; ++x)
74
74
  {
75
75
  const h = (cleanupRadius**2 - x**2)**.5;
@@ -235,26 +235,27 @@ function drawSky()
235
235
  function drawStars()
236
236
  {
237
237
  // draw stars and planets
238
- randSeed = skySeed;
238
+ const random = new RandomGenerator;
239
+ random.seed = skySeed;
239
240
  const largeStarCount = 9;
240
241
  for (let i = 1e3; i--;)
241
242
  {
242
- let size = randSeeded(6, 1);
243
- let speed = randSeeded() < .9 ? randSeeded(5) : randSeeded(99,9);
244
- let color = (new Color).setHSLA(randSeeded(.2,-.3), randSeeded()**9, randSeeded(1,.5), randSeeded(.9,.3));
243
+ let size = random.float(6, 1);
244
+ let speed = random.float() < .9 ? random.float(5) : random.float(99,9);
245
+ let color = (new Color).setHSLA(random.float(.2,-.3), random.float()**9, random.float(1,.5), random.float(.9,.3));
245
246
  if (i < largeStarCount)
246
247
  {
247
248
  // large planets and suns
248
- size = randSeeded()**3*99 + 9;
249
- speed = randSeeded(5);
250
- color = (new Color).setHSLA(randSeeded(), randSeeded(), randSeeded(1,.5)).add(skyColor.scale(.5)).clamp();
249
+ size = random.float()**3*99 + 9;
250
+ speed = random.float(5);
251
+ color = (new Color).setHSLA(random.float(), random.float(), random.float(1,.5)).add(skyColor.scale(.5)).clamp();
251
252
  }
252
253
 
253
254
  const extraSpace = 200;
254
255
  const w = mainCanvas.width+2*extraSpace, h = mainCanvas.height+2*extraSpace;
255
256
  const screenPos = vec2(
256
- (randSeeded(w)+time*speed)%w-extraSpace,
257
- (randSeeded(h)+time*speed*randSeeded())%h-extraSpace);
257
+ (random.float(w)+time*speed)%w-extraSpace,
258
+ (random.float(h)+time*speed*random.float())%h-extraSpace);
258
259
 
259
260
  mainContext.fillStyle = color;
260
261
  if (size < 9)
@@ -6,9 +6,9 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.js?1691></script>
10
- <script src=gameObjects.js?1691></script>
11
- <script src=gamePlayer.js?1691></script>
12
- <script src=gameEffects.js?1691></script>
13
- <script src=gameLevel.js?1691></script>
14
- <script src=game.js?1691></script>
9
+ <script src=../../build/littlejs.js?1701></script>
10
+ <script src=gameObjects.js?1701></script>
11
+ <script src=gamePlayer.js?1701></script>
12
+ <script src=gameEffects.js?1701></script>
13
+ <script src=gameLevel.js?1701></script>
14
+ <script src=game.js?1701></script>
@@ -6,5 +6,5 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.js?1691></script>
10
- <script src=game.js?1691></script>
9
+ <script src=../../build/littlejs.js?1701></script>
10
+ <script src=game.js?1701></script>
@@ -7,18 +7,18 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- LittleJS Engine -->
10
- <script src=../../src/engineDebug.js?1691></script>
11
- <script src=../../src/engineUtilities.js?1691></script>
12
- <script src=../../src/engineSettings.js?1691></script>
13
- <script src=../../src/engineObject.js?1691></script>
14
- <script src=../../src/engineDraw.js?1691></script>
15
- <script src=../../src/engineInput.js?1691></script>
16
- <script src=../../src/engineAudio.js?1691></script>
17
- <script src=../../src/engineTileLayer.js?1691></script>
18
- <script src=../../src/engineParticles.js?1691></script>
19
- <script src=../../src/engineMedals.js?1691></script>
20
- <script src=../../src/engineWebGL.js?1691></script>
21
- <script src=../../src/engine.js?1691></script>
10
+ <script src=../../src/engineDebug.js?1701></script>
11
+ <script src=../../src/engineUtilities.js?1701></script>
12
+ <script src=../../src/engineSettings.js?1701></script>
13
+ <script src=../../src/engineObject.js?1701></script>
14
+ <script src=../../src/engineDraw.js?1701></script>
15
+ <script src=../../src/engineInput.js?1701></script>
16
+ <script src=../../src/engineAudio.js?1701></script>
17
+ <script src=../../src/engineTileLayer.js?1701></script>
18
+ <script src=../../src/engineParticles.js?1701></script>
19
+ <script src=../../src/engineMedals.js?1701></script>
20
+ <script src=../../src/engineWebGL.js?1701></script>
21
+ <script src=../../src/engine.js?1701></script>
22
22
 
23
23
  <!-- Add your game scripts here -->
24
- <script src=game.js?1691></script>
24
+ <script src=game.js?1701></script>
@@ -6,7 +6,7 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.min.js?1691></script>
9
+ <script src=../../build/littlejs.min.js?1701></script>
10
10
  <script>
11
11
 
12
12
  /*
@@ -19,7 +19,7 @@
19
19
  'use strict';
20
20
 
21
21
  // keep our own list of simple sprites and track fps
22
- let sprites, timeMS, showFPS, statsDisplay, spriteColor, spriteAdditiveColor;
22
+ let sprites, timeMS, fpsDisplay, statsDisplay, spriteColor, spriteAdditiveColor;
23
23
 
24
24
  ///////////////////////////////////////////////////////////////////////////////
25
25
 
@@ -95,7 +95,7 @@ function gameRender()
95
95
  {
96
96
  // track fps and update stats
97
97
  const frameTimeMS = Date.now();
98
- showFPS = lerp(.05, showFPS, 1e3/(frameTimeMS - timeMS||1));
98
+ fpsDisplay = lerp(.05, fpsDisplay||0, 1e3/(frameTimeMS - timeMS||1));
99
99
  timeMS = frameTimeMS;
100
100
 
101
101
  const spriteCount = sprites.length
@@ -104,7 +104,7 @@ function gameRender()
104
104
  spriteCount + objectCount ?
105
105
  spriteCount + ' Sprites\n'
106
106
  + objectCount + ' Objects\n'
107
- + showFPS.toFixed(1) + ' FPS'
107
+ + fpsDisplay.toFixed(1) + ' FPS'
108
108
  : 'LittleJS Stress Test\nLeft Click = Add Particles\nRight Click = Add Objects';
109
109
 
110
110
  const size = vec2(.5);
@@ -7,4 +7,4 @@
7
7
  </head><body>
8
8
 
9
9
  <!-- Add your game scripts here -->
10
- <script src=game.js?1691 type=module></script>
10
+ <script src=game.js?1701 type=module></script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlejsengine",
3
- "version": "1.6.92",
3
+ "version": "1.7.01",
4
4
  "description": "LittleJS - Tiny and Fast HTML5 Game Engine",
5
5
  "main": "build/littlejs.esm.js",
6
6
  "repository": {
package/src/engine.js CHANGED
@@ -30,7 +30,7 @@ const engineName = 'LittleJS';
30
30
  * @type {String}
31
31
  * @default
32
32
  * @memberof Engine */
33
- const engineVersion = '1.6.92';
33
+ const engineVersion = '1.7.01';
34
34
 
35
35
  /** Frames per second to update objects
36
36
  * @type {Number}
@@ -128,7 +128,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
128
128
  };
129
129
 
130
130
  // frame time tracking
131
- let frameTimeLastMS = 0, frameTimeBufferMS = 0, averageFPS;
131
+ let frameTimeLastMS = 0, frameTimeBufferMS = 0, averageFPS = 0;
132
132
 
133
133
  // main update loop
134
134
  function engineUpdate(frameTimeMS=0)
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * LittleJS Audio System
3
- * - <a href=https://killedbyapixel.github.io/ZzFX/>ZzFX Sound Effects</a> - Sound Effect Generator
4
- * - <a href=https://keithclark.github.io/ZzFXM/>ZzFXM Music</a> - Music System
3
+ * - <a href=https://killedbyapixel.github.io/ZzFX/>ZzFX Sound Effects</a> - ZzFX Sound Effect Generator
4
+ * - <a href=https://keithclark.github.io/ZzFXM/>ZzFXM Music</a> - ZzFXM Music System
5
5
  * - Caches sounds and music for fast playback
6
6
  * - Can attenuate and apply stereo panning to sounds
7
7
  * - Ability to play mp3, ogg, and wave files
8
- * - Speech synthesis wrapper functions
8
+ * - Speech synthesis functions
9
9
  * @namespace Audio
10
10
  */
11
11
 
@@ -39,12 +39,15 @@ class Sound
39
39
  /** @property {Number} - At what percentage of range should it start tapering off */
40
40
  this.taper = taper;
41
41
 
42
- // get randomness from sound parameters
43
- this.randomness = zzfxSound[1] || 0;
44
- zzfxSound[1] = 0;
42
+ /** @property {Number} - How much to randomize frequency each time sound plays */
43
+ this.randomness = 0;
45
44
 
46
- // generate sound now for fast playback
47
- this.cachedSamples = zzfxG(...zzfxSound);
45
+ if (zzfxSound)
46
+ {
47
+ // generate zzfx sound now for fast playback
48
+ this.randomness = zzfxSound[1] || (zzfxSound[1] = 0);
49
+ this.cachedSamples = zzfxSound && zzfxG(...zzfxSound);
50
+ }
48
51
  }
49
52
 
50
53
  /** Play the sound
@@ -56,7 +59,7 @@ class Sound
56
59
  */
57
60
  play(pos, volume=1, pitch=1, randomnessScale=1)
58
61
  {
59
- if (!soundEnable) return;
62
+ if (!soundEnable || !this.cachedSamples) return;
60
63
 
61
64
  let pan;
62
65
  if (pos)
@@ -89,12 +92,36 @@ class Sound
89
92
  * @return {AudioBufferSourceNode} - The audio, can be used to stop sound later
90
93
  */
91
94
  playNote(semitoneOffset, pos, volume)
95
+ { return this.play(pos, volume, 2**(semitoneOffset/12), 0); }
96
+ }
97
+
98
+ /**
99
+ * Sound Wave Object - Stores a wave sound for later use and can be played positionally
100
+ */
101
+ class SoundWave extends Sound
102
+ {
103
+ /** Create a sound object and cache the wave file for later use
104
+ * @param {String} waveFilename - Filename of wave file to load
105
+ * @param {Number} [randomness=.05] - How much to randomize frequency each time sound plays
106
+ * @param {Number} [range=soundDefaultRange] - World space max range of sound, will not play if camera is farther away
107
+ * @param {Number} [taper=soundDefaultTaper] - At what percentage of range should it start tapering off
108
+ */
109
+ constructor(waveFilename, randomness=.05, range, taper)
92
110
  {
111
+ super(0, range, taper);
112
+ this.randomness = randomness;
113
+
93
114
  if (!soundEnable) return;
115
+ if (!soundWaveDecoderContext)
116
+ soundDecoderContext = new AudioContext;
94
117
 
95
- return this.play(pos, volume, 2**(semitoneOffset/12), 0);
118
+ fetch(waveFilename)
119
+ .then(response => response.arrayBuffer())
120
+ .then(arrayBuffer => soundWaveDecoderContext.decodeAudioData(arrayBuffer))
121
+ .then(audioBuffer => this.cachedSamples = audioBuffer.getChannelData(0));
96
122
  }
97
123
  }
124
+ let soundDecoderContext; // audio context used only to decode audio files
98
125
 
99
126
  /**
100
127
  * Music Object - Stores a zzfx music track for later use
@@ -237,16 +264,17 @@ function playSamples(sampleChannels, volume=1, rate=1, pan=0, loop=0)
237
264
  {
238
265
  if (!soundEnable) return;
239
266
 
240
- // create audio context
267
+ // create audio context if needed
241
268
  if (!audioContext)
242
269
  audioContext = new AudioContext;
243
270
 
244
- // fix stalled audio
245
- audioContext.resume();
246
-
247
271
  // prevent sounds from building up if they can't be played
248
272
  if (audioContext.state != 'running')
273
+ {
274
+ // fix stalled audio
275
+ audioContext.resume();
249
276
  return;
277
+ }
250
278
 
251
279
  // create buffer and source
252
280
  const buffer = audioContext.createBuffer(sampleChannels.length, sampleChannels[0].length, zzfxR),
@@ -451,7 +479,7 @@ function zzfxM(instruments, patterns, sequence, BPM = 125)
451
479
 
452
480
  // stop if end, different instrument or new note
453
481
  stop = i == patternChannel.length + isSequenceEnd - 1 && isSequenceEnd ||
454
- instrument != (patternChannel[0] || 0) || note;
482
+ instrument != (patternChannel[0] || 0) || note | 0;
455
483
 
456
484
  // fill buffer with samples for previous beat, most cpu intensive part
457
485
  for (j = 0; j < beatLength && notFirstBeat;
@@ -26,8 +26,17 @@ const engineSourceFiles =
26
26
  `${SOURCE_FOLDER}/engineWebGL.js`,
27
27
  `${SOURCE_FOLDER}/engine.js`,
28
28
  ];
29
-
30
- console.log('Choo Choo... Building LittleJS Engine!');
29
+ const asciiArt =`
30
+ ~~~~°°°°ooo°oOo°ooOooOooOo.
31
+ __________ ________ ____ '°OoO.
32
+ |LittleJS| |Engine| |[]|_._._Y
33
+ .|________|_._|______|_._|__|_|_|_|}
34
+ OOO OOO OO OO OO=OO---oo\\
35
+ `;
36
+ const license = '// LittleJS - MIT License - Copyright 2021 Frank Force\n'
37
+
38
+ console.log(asciiArt);
39
+ console.log('Choo Choo... Building LittleJS Engine!\n');
31
40
  const startTime = Date.now();
32
41
  const fs = require('node:fs');
33
42
  const child_process = require('node:child_process');
@@ -44,14 +53,16 @@ Build
44
53
  (
45
54
  'Build Engine -- all',
46
55
  `${BUILD_FOLDER}/${ENGINE_NAME}.js`,
47
- [`${SOURCE_FOLDER}/engineDebug.js`].concat(engineSourceFiles)
56
+ [`${SOURCE_FOLDER}/engineDebug.js`, ...engineSourceFiles],
57
+ [], license
48
58
  );
49
59
 
50
60
  Build
51
61
  (
52
62
  'Build Engine -- release',
53
63
  `${BUILD_FOLDER}/${ENGINE_NAME}.release.js`,
54
- [`${SOURCE_FOLDER}/engineRelease.js`].concat(engineSourceFiles)
64
+ [`${SOURCE_FOLDER}/engineRelease.js`, ...engineSourceFiles],
65
+ [], license
55
66
  );
56
67
 
57
68
  Build
@@ -84,12 +95,14 @@ console.log(`Engine built in ${((Date.now() - startTime)/1e3).toFixed(2)} second
84
95
 
85
96
  // A single build with its own source files, build steps, and output file
86
97
  // - each build step is a callback that accepts a single filename
87
- function Build(message, outputFile, files=[], buildSteps=[])
98
+ function Build(message, outputFile, files=[], buildSteps=[], topOfFileText)
88
99
  {
89
100
  console.log(message);
90
101
 
91
102
  // copy files into a buffer
92
103
  let buffer = '';
104
+ if (topOfFileText)
105
+ buffer += topOfFileText + '\n';
93
106
  for (const file of files)
94
107
  buffer += fs.readFileSync(file) + '\n';
95
108
 
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * LittleJS Debug System
3
- * - Press ~ to show debug overlay with mouse pick
3
+ * - Press Esc to show debug overlay with mouse pick
4
4
  * - Number keys toggle debug functions
5
5
  * - +/- apply time scale
6
6
  * - Debug primitive rendering
7
- * - Save a 2d canvas as an image
7
+ * - Save a 2d canvas as a png image
8
8
  * @namespace Debug
9
9
  */
10
10
 
@@ -138,11 +138,27 @@ function debugClear() { debugPrimitives = []; }
138
138
  /** Save a canvas to disk
139
139
  * @param {HTMLCanvasElement} canvas
140
140
  * @param {String} [filename]
141
+ * @param {String} [type='image/png']
141
142
  * @memberof Debug */
142
- function debugSaveCanvas(canvas, filename = engineName + '.png')
143
+ function debugSaveCanvas(canvas, filename=engineName, type='image/png')
144
+ { debugSaveDataURL(canvas.toDataURL(type), filename); }
145
+
146
+ /** Save a text file to disk
147
+ * @param {String} text
148
+ * @param {String} [filename]
149
+ * @param {String} [type='text/plain']
150
+ * @memberof Debug */
151
+ function debugSaveText(text, filename=engineName, type='text/plain')
152
+ { debugSaveDataURL(URL.createObjectURL(new Blob([text], {'type':type})), filename); }
153
+
154
+ /** Save a data url to disk
155
+ * @param {String} dataURL
156
+ * @param {String} filename
157
+ * @memberof Debug */
158
+ function debugSaveDataURL(dataURL, filename)
143
159
  {
144
- downloadLink.download = 'screenshot.png';
145
- downloadLink.href = canvas.toDataURL('image/png').replace('image/png','image/octet-stream');
160
+ downloadLink.download = filename;
161
+ downloadLink.href = dataURL;
146
162
  downloadLink.click();
147
163
  }
148
164