littlejsengine 1.6.6 → 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.
Files changed (59) hide show
  1. package/README.md +76 -53
  2. package/build/littlejs.d.ts +154 -136
  3. package/build/littlejs.esm.js +461 -305
  4. package/build/littlejs.esm.min.js +1 -1
  5. package/build/littlejs.js +452 -291
  6. package/build/littlejs.min.js +1 -1
  7. package/build/littlejs.release.js +2317 -2168
  8. package/examples/breakout/game.js +5 -1
  9. package/examples/breakout/index.html +5 -5
  10. package/examples/breakoutTutorial/README.md +6 -6
  11. package/examples/breakoutTutorial/game.js +3 -0
  12. package/examples/breakoutTutorial/index.html +3 -3
  13. package/examples/electron/build.js +105 -0
  14. package/examples/electron/game.js +4 -2
  15. package/examples/electron/index.html +13 -2
  16. package/examples/electron/package.json +5 -3
  17. package/examples/empty/game.js +3 -1
  18. package/examples/empty/index.html +1 -1
  19. package/examples/js13k/build.bat +2 -0
  20. package/examples/js13k/build.js +110 -0
  21. package/examples/js13k/game.js +109 -0
  22. package/examples/js13k/index.html +18 -0
  23. package/examples/js13k/tiles.png +0 -0
  24. package/examples/module/game.js +9 -3
  25. package/examples/module/index.html +2 -2
  26. package/examples/particles/index.html +7 -13
  27. package/examples/platformer/game.js +5 -2
  28. package/examples/platformer/gameEffects.js +12 -12
  29. package/examples/platformer/gamePlayer.js +2 -2
  30. package/examples/platformer/index.html +8 -8
  31. package/examples/puzzle/game.js +5 -3
  32. package/examples/puzzle/index.html +4 -4
  33. package/examples/starter/build.bat +2 -78
  34. package/examples/starter/build.js +109 -0
  35. package/examples/starter/game.js +4 -1
  36. package/examples/starter/index.html +15 -18
  37. package/examples/stress/index.html +5 -7
  38. package/examples/typescript/build.bat +2 -14
  39. package/examples/typescript/build.js +31 -0
  40. package/examples/typescript/game.js +94 -89
  41. package/examples/typescript/game.ts +9 -3
  42. package/examples/typescript/index.html +2 -2
  43. package/package.json +2 -2
  44. package/src/engine.js +3 -3
  45. package/src/engineAudio.js +44 -16
  46. package/src/engineBuild.bat +2 -132
  47. package/src/engineBuild.js +156 -0
  48. package/src/engineDebug.js +25 -15
  49. package/src/engineDraw.js +62 -53
  50. package/src/engineExport.js +7 -12
  51. package/src/engineInput.js +27 -35
  52. package/src/engineObject.js +15 -13
  53. package/src/engineParticles.js +6 -6
  54. package/src/engineRelease.js +1 -3
  55. package/src/engineSettings.js +1 -0
  56. package/src/engineTileLayer.js +31 -18
  57. package/src/engineUtilities.js +161 -93
  58. package/src/engineWebGL.js +63 -27
  59. package/examples/electron/build.bat +0 -52
@@ -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;
@@ -78,7 +78,6 @@ function explosion(pos, radius=3)
78
78
  }
79
79
 
80
80
  // kill/push objects
81
- const maxRangeSquared = (radius*1.5)**2;
82
81
  engineObjectsCallback(pos, radius*3, (o)=>
83
82
  {
84
83
  const d = o.pos.distance(pos);
@@ -170,7 +169,7 @@ function decorateBackgroundTile(pos)
170
169
  // check corner neighbors
171
170
  const neighborTileDataA = getTileBackgroundData(pos.add(vec2().setAngle(i*PI/2)));
172
171
  const neighborTileDataB = getTileBackgroundData(pos.add(vec2().setAngle((i+1)%4*PI/2)));
173
- if (neighborTileDataA > 0 | neighborTileDataB > 0)
172
+ if (neighborTileDataA > 0 || neighborTileDataB > 0)
174
173
  continue;
175
174
 
176
175
  const directionVector = vec2().setAngle(i*PI/2+PI/4, 10).floor();
@@ -236,26 +235,27 @@ function drawSky()
236
235
  function drawStars()
237
236
  {
238
237
  // draw stars and planets
239
- randSeed = skySeed;
238
+ const random = new RandomGenerator;
239
+ random.seed = skySeed;
240
240
  const largeStarCount = 9;
241
241
  for (let i = 1e3; i--;)
242
242
  {
243
- let size = randSeeded(6, 1);
244
- let speed = randSeeded() < .9 ? randSeeded(5) : randSeeded(99,9);
245
- 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));
246
246
  if (i < largeStarCount)
247
247
  {
248
248
  // large planets and suns
249
- size = randSeeded()**3*99 + 9;
250
- speed = randSeeded(5);
251
- 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();
252
252
  }
253
253
 
254
254
  const extraSpace = 200;
255
255
  const w = mainCanvas.width+2*extraSpace, h = mainCanvas.height+2*extraSpace;
256
256
  const screenPos = vec2(
257
- (randSeeded(w)+time*speed)%w-extraSpace,
258
- (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);
259
259
 
260
260
  mainContext.fillStyle = color;
261
261
  if (size < 9)
@@ -97,7 +97,7 @@ class Character extends GameObject
97
97
  {
98
98
  const testPos = this.pos.add(vec2(0, y + .1*moveInput.y - this.size.y/2));
99
99
  const collisionData = getTileCollisionData(testPos);
100
- touchingLadder |= collisionData == tileType_ladder;
100
+ touchingLadder ||= collisionData == tileType_ladder;
101
101
  }
102
102
  if (!touchingLadder)
103
103
  this.climbingLadder = 0;
@@ -231,7 +231,7 @@ class Character extends GameObject
231
231
 
232
232
  damage(damage, damagingObject)
233
233
  {
234
- if (this.isDead() || this.getAliveTime() < 1 || this.dodgeTimer.active() || godMode)
234
+ if (this.isDead() || this.getAliveTime() < 1 || this.dodgeTimer.active())
235
235
  return;
236
236
 
237
237
  makeBlood(damagingObject ? damagingObject.pos : this.pos);
@@ -1,14 +1,14 @@
1
- <html><head>
2
- <title>Little JS Platforming Game Demo</title>
1
+ <!DOCTYPE html><head>
2
+ <title>Little JS Platforming Game</title>
3
3
  <meta name=viewport content=width=device-width,height=device-height,initial-scale=1,maximum-scale=1>
4
4
  <meta name=apple-mobile-web-app-capable content=yes>
5
5
  <meta name=mobile-web-app-capable content=yes>
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.js?166></script>
10
- <script src=gameObjects.js?166></script>
11
- <script src=gamePlayer.js?166></script>
12
- <script src=gameEffects.js?166></script>
13
- <script src=gameLevel.js?166></script>
14
- <script src=game.js?166></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>
@@ -1,7 +1,9 @@
1
1
  /*
2
- LittleJS Puzzle Example
3
- - A match 3 style puzzle game to get you started
4
- - Uses a higher resolution texture
2
+ Little Puzzle Game
3
+ - A simple match 3 style puzzle game
4
+ - Uses a high resolution texture
5
+ - Tracks high score in local storage
6
+ - Control with mouse or touch
5
7
  */
6
8
 
7
9
  'use strict';
@@ -1,10 +1,10 @@
1
- <html><head>
2
- <title>Little Puzzle Game Demo</title>
1
+ <!DOCTYPE html><head>
2
+ <title>Little Puzzle Game</title>
3
3
  <meta name=viewport content=width=device-width,height=device-height,initial-scale=1,maximum-scale=1>
4
4
  <meta name=apple-mobile-web-app-capable content=yes>
5
5
  <meta name=mobile-web-app-capable content=yes>
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.js?166></script>
10
- <script src=game.js?166></script>
9
+ <script src=../../build/littlejs.js?1701></script>
10
+ <script src=game.js?1701></script>
@@ -1,78 +1,2 @@
1
- rem Simple build script for LittleJS by Frank Force
2
- rem Minfies and combines index.html and index.js and zips the result
3
-
4
- set NAME=game
5
- set BUILD_FOLDER=build
6
- set BUILD_FILENAME=index.js
7
-
8
- rem install dev packages
9
- rem call npm install
10
-
11
- rem remove old files
12
- del %NAME%.zip
13
- rmdir /s /q %BUILD_FOLDER%
14
-
15
- rem copy engine release build
16
- mkdir %BUILD_FOLDER%
17
- pushd %BUILD_FOLDER%
18
-
19
- rem rebuild engine first
20
- pushd ..\..\..\src
21
- call engineBuild.bat
22
- if %ERRORLEVEL% NEQ 0 (
23
- pause
24
- exit /b %ERRORLEVEL%
25
- )
26
- popd
27
-
28
- type ..\..\..\build\littlejs.release.js >> %BUILD_FILENAME%
29
- echo. >> %BUILD_FILENAME%
30
-
31
- rem add your game's files to include here
32
- type ..\game.js >> %BUILD_FILENAME%
33
- echo. >> %BUILD_FILENAME%
34
-
35
- rem copy images to build folder
36
- copy ..\tiles.png tiles.png
37
-
38
- rem minify code with closure
39
- move %BUILD_FILENAME% temp_%BUILD_FILENAME%
40
- call npx google-closure-compiler --js=temp_%BUILD_FILENAME% --js_output_file=%BUILD_FILENAME% --compilation_level=ADVANCED --language_out=ECMASCRIPT_2021 --warning_level=VERBOSE --jscomp_off=* --assume_function_wrapper
41
- if %ERRORLEVEL% NEQ 0 (
42
- pause
43
- exit /b %ERRORLEVEL%
44
- )
45
- del temp_%BUILD_FILENAME%
46
-
47
- rem more minification with uglify
48
- call npx uglifyjs -o %BUILD_FILENAME% --compress --mangle -- %BUILD_FILENAME%
49
- if %ERRORLEVEL% NEQ 0 (
50
- pause
51
- exit /b %ERRORLEVEL%
52
- )
53
-
54
- rem roadroller compresses the code better then zip
55
- call npx roadroller %BUILD_FILENAME% -o %BUILD_FILENAME%
56
- if %ERRORLEVEL% NEQ 0 (
57
- pause
58
- exit /b %ERRORLEVEL%
59
- )
60
-
61
- rem build the html, you can add an html header and footer here
62
- rem type ..\header.html >> index.html
63
- echo ^<script^> >> index.html
64
- type %BUILD_FILENAME% >> index.html
65
- echo ^</script^> >> index.html
66
- rem type ..\footer.html >> index.html
67
-
68
- rem delete intermediate files
69
- del %BUILD_FILENAME%
70
-
71
- rem zip the result, ect is recommended
72
- call ..\..\..\node_modules\ect-bin\vendor\win32\ect.exe -9 -strip -zip ..\%NAME%.zip index.html tiles.png
73
- if %ERRORLEVEL% NEQ 0 (
74
- pause
75
- exit /b %ERRORLEVEL%
76
- )
77
-
78
- popd
1
+ rem LittleJS Build Script
2
+ call node build.js
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * LittleJS Build System
5
+ */
6
+
7
+ const PROGRAM_TITLE = 'Little JS Starter Project';
8
+ const PROGRAM_NAME = 'game';
9
+ const BUILD_FOLDER = 'build';
10
+ const sourceFiles =
11
+ [
12
+ '../../build/littlejs.release.js',
13
+ 'game.js',
14
+ // add your game's files here
15
+ ];
16
+ const dataFiles =
17
+ [
18
+ 'tiles.png',
19
+ // add your game's data files here
20
+ ];
21
+
22
+ console.log(`Building ${PROGRAM_NAME}...`);
23
+ const startTime = Date.now();
24
+ const fs = require('node:fs');
25
+ const child_process = require('node:child_process');
26
+
27
+ // rebuild engine
28
+ child_process.execSync(`npm run build`, { stdio: 'inherit' });
29
+
30
+ // remove old files and setup build folder
31
+ fs.rmSync(BUILD_FOLDER, { recursive: true, force: true });
32
+ fs.rmSync(`${PROGRAM_NAME}.zip`, { force: true });
33
+ fs.mkdirSync(BUILD_FOLDER);
34
+
35
+ // copy data files
36
+ for(const file of dataFiles)
37
+ fs.copyFileSync(file, `${BUILD_FOLDER}/${file}`);
38
+
39
+ Build
40
+ (
41
+ `${BUILD_FOLDER}/index.js`,
42
+ sourceFiles,
43
+ [closureCompilerStep, uglifyBuildStep, htmlBuildStep, zipBuildStep]
44
+ );
45
+
46
+ console.log('');
47
+ console.log(`Build Completed in ${((Date.now() - startTime)/1e3).toFixed(2)} seconds!`);
48
+ console.log(`Size of ${PROGRAM_NAME}.zip: ${fs.statSync(`${PROGRAM_NAME}.zip`).size} bytes`);
49
+
50
+ ///////////////////////////////////////////////////////////////////////////////
51
+
52
+ // A single build with its own source files, build steps, and output file
53
+ // - each build step is a callback that accepts a single filename
54
+ function Build(outputFile, files=[], buildSteps=[])
55
+ {
56
+ // copy files into a buffer
57
+ let buffer = '';
58
+ for (const file of files)
59
+ buffer += fs.readFileSync(file) + '\n';
60
+
61
+ // output file
62
+ fs.writeFileSync(outputFile, buffer, {flag: 'w+'});
63
+
64
+ // execute build steps in order
65
+ for (const buildStep of buildSteps)
66
+ buildStep(outputFile);
67
+ }
68
+
69
+ function closureCompilerStep(filename)
70
+ {
71
+ console.log(`Running closure compiler...`);
72
+
73
+ const filenameTemp = filename + '.tmp';
74
+ fs.copyFileSync(filename, filenameTemp);
75
+ child_process.execSync(`npx google-closure-compiler --js=${filenameTemp} --js_output_file=${filename} --compilation_level=ADVANCED --language_out=ECMASCRIPT_2021 --warning_level=VERBOSE --jscomp_off=* --assume_function_wrapper`, {stdio: 'inherit'});
76
+ fs.rmSync(filenameTemp);
77
+ };
78
+
79
+ function uglifyBuildStep(filename)
80
+ {
81
+ console.log(`Running uglify...`);
82
+ child_process.execSync(`npx uglifyjs ${filename} -c -m -o ${filename}`, {stdio: 'inherit'});
83
+ };
84
+
85
+ function htmlBuildStep(filename)
86
+ {
87
+ console.log(`Building html...`);
88
+
89
+ // create html file
90
+ let buffer = '<!DOCTYPE html>';
91
+ buffer += '<head>';
92
+ buffer += `<title>${PROGRAM_TITLE}</title>`;
93
+ buffer += '</head>';
94
+ buffer += '<script>';
95
+ buffer += fs.readFileSync(filename) + '\n';
96
+ buffer += '</script>';
97
+
98
+ // output html file
99
+ fs.writeFileSync(`${BUILD_FOLDER}/index.html`, buffer, {flag: 'w+'});
100
+ };
101
+
102
+ function zipBuildStep(filename)
103
+ {
104
+ console.log(`Zipping...`);
105
+
106
+ const ect = '../../../node_modules/ect-bin/vendor/win32/ect.exe';
107
+ const args = ['-9', '-strip', '-zip', `../${PROGRAM_NAME}.zip`, 'index.html', ...dataFiles];
108
+ child_process.spawnSync(ect, args, {stdio: 'inherit', cwd: BUILD_FOLDER});
109
+ };
@@ -1,5 +1,8 @@
1
1
  /*
2
- LittleJS Hello World Starter Game
2
+ Little JS Starter Project
3
+ - A simple starter project for LittleJS
4
+ - Demos all the main engine features
5
+ - Builds to a zip file
3
6
  */
4
7
 
5
8
  'use strict';
@@ -1,4 +1,4 @@
1
- <html><head>
1
+ <!DOCTYPE html><head>
2
2
  <title>Little JS Starter Project</title>
3
3
  <meta name=viewport content=width=device-width,height=device-height,initial-scale=1,maximum-scale=1>
4
4
  <meta name=apple-mobile-web-app-capable content=yes>
@@ -6,22 +6,19 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <!-- LittleJS engine scripts -->
10
- <script src=../../src/engineDebug.js?166></script>
11
- <script src=../../src/engineUtilities.js?166></script>
12
- <script src=../../src/engineSettings.js?166></script>
13
- <script src=../../src/engineObject.js?166></script>
14
- <script src=../../src/engineDraw.js?166></script>
15
- <script src=../../src/engineInput.js?166></script>
16
- <script src=../../src/engineAudio.js?166></script>
17
- <script src=../../src/engineTileLayer.js?166></script>
18
- <script src=../../src/engineParticles.js?166></script>
19
- <script src=../../src/engineMedals.js?166></script>
20
- <script src=../../src/engineWebGL.js?166></script>
21
- <script src=../../src/engine.js?166></script>
22
-
23
- <!-- You can also include all engine scripts like this... -->
24
- <!-- <script src=engine/engine.all.js></script> -->
9
+ <!-- LittleJS Engine -->
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>
25
22
 
26
23
  <!-- Add your game scripts here -->
27
- <script src=game.js?166></script>
24
+ <script src=game.js?1701></script>
@@ -1,4 +1,4 @@
1
- <html><head>
1
+ <!DOCTYPE html><head>
2
2
  <title>Little JS Stress Test</title>
3
3
  <meta name=viewport content=width=device-width,height=device-height,initial-scale=1,maximum-scale=1>
4
4
  <meta name=apple-mobile-web-app-capable content=yes>
@@ -6,22 +6,20 @@
6
6
  <link rel=icon type=image/png href=../favicon.png>
7
7
  </head><body>
8
8
 
9
- <script src=../../build/littlejs.min.js?166></script>
9
+ <script src=../../build/littlejs.min.js?1701></script>
10
10
  <script>
11
11
 
12
12
  /*
13
13
  LittleJS Stress Test
14
14
  - Render over 50,000 sprites at 60 fps in Chrome
15
- - Uses glOverlay mode in Firefox to improve performance
16
15
  - Also plays music in the background with zzfxm
17
16
  - All code and the image is contained in this html file
18
- - Text displayed using a div so it appears on top in glOverlay mode
19
17
  */
20
18
 
21
19
  'use strict';
22
20
 
23
21
  // keep our own list of simple sprites and track fps
24
- let sprites, timeMS, showFPS, statsDisplay, spriteColor, spriteAdditiveColor;
22
+ let sprites, timeMS, fpsDisplay, statsDisplay, spriteColor, spriteAdditiveColor;
25
23
 
26
24
  ///////////////////////////////////////////////////////////////////////////////
27
25
 
@@ -97,7 +95,7 @@ function gameRender()
97
95
  {
98
96
  // track fps and update stats
99
97
  const frameTimeMS = Date.now();
100
- showFPS = lerp(.05, showFPS, 1e3/(frameTimeMS - timeMS||1));
98
+ fpsDisplay = lerp(.05, fpsDisplay||0, 1e3/(frameTimeMS - timeMS||1));
101
99
  timeMS = frameTimeMS;
102
100
 
103
101
  const spriteCount = sprites.length
@@ -106,7 +104,7 @@ function gameRender()
106
104
  spriteCount + objectCount ?
107
105
  spriteCount + ' Sprites\n'
108
106
  + objectCount + ' Objects\n'
109
- + showFPS.toFixed(1) + ' FPS'
107
+ + fpsDisplay.toFixed(1) + ' FPS'
110
108
  : 'LittleJS Stress Test\nLeft Click = Add Particles\nRight Click = Add Objects';
111
109
 
112
110
  const size = vec2(.5);
@@ -1,14 +1,2 @@
1
- rem TypeScript build script for LittleJS by Frank Force
2
-
3
- set BUILD_FOLDER=build
4
-
5
- call npx tsc
6
- if %ERRORLEVEL% NEQ 0 (
7
- pause
8
- exit /b %ERRORLEVEL%
9
- )
10
-
11
- rem copy output js file and remove build folder
12
-
13
- copy %BUILD_FOLDER%\examples\typescript\game.js game.js
14
- rmdir /s /q %BUILD_FOLDER%
1
+ rem LittleJS Build Script
2
+ call node build.js
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * LittleJS Build System
5
+ */
6
+
7
+ const PROGRAM_NAME = 'game';
8
+ const BUILD_FOLDER = 'build';
9
+ const ROOT_FOLDER = 'examples/typescript';
10
+ const sourceFiles =
11
+ [
12
+ 'game.js',
13
+ // add your game's scripts here
14
+ ];
15
+
16
+ console.log(`Building TypeScript for ${PROGRAM_NAME}...`);
17
+ const startTime = Date.now();
18
+ const fs = require('node:fs');
19
+ const child_process = require('node:child_process');
20
+
21
+ console.log(`Removing old build filder...`);
22
+ fs.rmSync(BUILD_FOLDER, { recursive: true, force: true });
23
+
24
+ console.log(`Compiling TypeScript...`);
25
+ child_process.execSync(`npx tsc --outDir "./${BUILD_FOLDER}"`, {stdio: 'inherit'});
26
+
27
+ console.log(`Moving js files to root...`);
28
+ for(const file of sourceFiles)
29
+ fs.copyFileSync(`${BUILD_FOLDER}/${ROOT_FOLDER}/${file}`, `${file}`);
30
+
31
+ console.log(`TypeScript built in ${((Date.now() - startTime)/1e3).toFixed(2)} seconds!`);