littlejsengine 1.11.13 → 1.12.4

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 (79) hide show
  1. package/dist/littlejs.d.ts +1418 -109
  2. package/dist/littlejs.esm.js +3495 -581
  3. package/dist/littlejs.esm.min.js +1 -1
  4. package/dist/littlejs.js +3258 -399
  5. package/dist/littlejs.min.js +1 -1
  6. package/dist/littlejs.release.js +3147 -379
  7. package/examples/box2d/game.js +73 -45
  8. package/examples/box2d/gameObjects.js +96 -92
  9. package/examples/box2d/index.html +2 -7
  10. package/examples/box2d/scenes.js +82 -92
  11. package/examples/breakout/game.js +62 -30
  12. package/examples/breakout/gameObjects.js +45 -47
  13. package/examples/breakout/index.html +1 -5
  14. package/examples/breakoutTutorial/game.js +36 -29
  15. package/examples/breakoutTutorial/index.html +1 -3
  16. package/examples/empty/game.js +5 -2
  17. package/examples/empty/index.html +1 -3
  18. package/examples/htmlMenu/game.js +25 -19
  19. package/examples/htmlMenu/index.html +5 -7
  20. package/examples/index.html +2 -3
  21. package/examples/module/game.js +32 -34
  22. package/examples/module/index.html +1 -1
  23. package/examples/particles/index.html +27 -22
  24. package/examples/platformer/game.js +71 -48
  25. package/examples/platformer/gameCharacter.js +42 -34
  26. package/examples/platformer/gameEffects.js +82 -75
  27. package/examples/platformer/gameLevel.js +67 -38
  28. package/examples/platformer/{gameLevelData.js → gameLevelData.json} +1 -11
  29. package/examples/platformer/gameObjects.js +70 -64
  30. package/examples/platformer/gamePlayer.js +12 -7
  31. package/examples/platformer/index.html +1 -9
  32. package/examples/puzzle/game.js +58 -42
  33. package/examples/puzzle/index.html +1 -3
  34. package/examples/shorts/base.html +2 -2
  35. package/examples/shorts/particles.js +1 -1
  36. package/examples/shorts/platformer.js +1 -1
  37. package/examples/shorts/tileLayer.js +5 -6
  38. package/examples/shorts/tiles.png +0 -0
  39. package/examples/starter/build.js +4 -4
  40. package/examples/starter/game.js +9 -12
  41. package/examples/starter/index.html +13 -13
  42. package/examples/stress/index.html +44 -43
  43. package/examples/typescript/build.js +17 -18
  44. package/examples/typescript/game.js +32 -34
  45. package/examples/typescript/game.ts +32 -34
  46. package/examples/typescript/index.html +1 -1
  47. package/examples/uiSystem/game.js +33 -36
  48. package/examples/uiSystem/index.html +1 -5
  49. package/package.json +3 -3
  50. package/plugins/box2d.js +1556 -640
  51. package/plugins/{Box2D_v2.3.1_min.wasm.js → box2d.wasm.js} +1 -1
  52. package/plugins/newgrounds.js +7 -8
  53. package/plugins/pluginExport.js +50 -0
  54. package/plugins/postProcess.js +94 -93
  55. package/plugins/uiSystem.js +145 -161
  56. package/plugins/zzfxm.js +163 -0
  57. package/reference.md +29 -27
  58. package/src/engine.js +15 -20
  59. package/src/engineAudio.js +74 -204
  60. package/src/engineBuild.js +29 -4
  61. package/src/engineDebug.js +105 -9
  62. package/src/engineDraw.js +27 -14
  63. package/src/engineExport.js +12 -8
  64. package/src/engineInput.js +3 -1
  65. package/src/engineObject.js +18 -14
  66. package/src/engineParticles.js +6 -1
  67. package/src/engineRelease.js +6 -1
  68. package/src/engineSettings.js +8 -8
  69. package/src/engineTileLayer.js +179 -96
  70. package/src/engineUtilities.js +5 -11
  71. package/src/engineWebGL.js +19 -7
  72. package/examples/starter/build/index.html +0 -2
  73. package/examples/starter/build/index.js +0 -1
  74. package/examples/starter/build/tiles.png +0 -0
  75. package/examples/starter/game.zip +0 -0
  76. package/examples/typescript/build/dist/littlejs.esm.js +0 -4834
  77. package/examples/typescript/build/examples/typescript/build.js +0 -24
  78. package/examples/typescript/build/examples/typescript/game.js +0 -102
  79. /package/plugins/{Box2D_v2.3.1_min.wasm.wasm → box2d.wasm.wasm} +0 -0
@@ -8,25 +8,59 @@
8
8
 
9
9
  'use strict';
10
10
 
11
- // show the LittleJS splash screen
12
- setShowSplashScreen(true);
13
-
14
- let spriteAtlas, score, deaths;
11
+ // import LittleJS module
12
+ import * as LJS from '../../dist/littlejs.esm.js';
13
+ import * as GameObjects from './gameObjects.js';
14
+ import * as GameEffects from './gameEffects.js';
15
+ import * as GamePlayer from './gamePlayer.js';
16
+ import * as GameLevel from './gameLevel.js';
17
+ const {vec2} = LJS;
15
18
 
16
19
  // enable touch gamepad on touch devices
17
- touchGamepadEnable = true;
20
+ LJS.setTouchGamepadEnable(true);
21
+
22
+ // globals
23
+ export let spriteAtlas, player, score, deaths, gameLevelData;
24
+ export function addToScore(delta=1) { score += delta; }
25
+ export function addToDeaths() { ++deaths; }
26
+
27
+ ///////////////////////////////////////////////////////////////////////////////
28
+ function loadLevel()
29
+ {
30
+ // setup level
31
+ GameLevel.buildLevel();
32
+
33
+ // spawn player
34
+ player = new GamePlayer.Player(GameLevel.playerStartPos);
35
+ LJS.setCameraPos(GameLevel.getCameraTarget());
36
+
37
+ // init game
38
+ score = deaths = 0;
39
+ }
18
40
 
19
41
  ///////////////////////////////////////////////////////////////////////////////
20
- function gameInit()
42
+ async function gameInit()
21
43
  {
44
+ try
45
+ {
46
+ // load level data from external JSON file
47
+ const response = await fetch('gameLevelData.json');
48
+ gameLevelData = await response.json();
49
+ console.log('Level data loaded successfully');
50
+ }
51
+ catch (error)
52
+ {
53
+ console.error('Failed to load level data!');
54
+ }
55
+
22
56
  // engine settings
23
- gravity = -.01;
24
- objectDefaultDamping = .99;
25
- objectDefaultAngleDamping = .99;
26
- cameraScale = 4*16;
57
+ LJS.setGravity(vec2(0,-.01));
58
+ LJS.setObjectDefaultDamping(.99);
59
+ LJS.setObjectDefaultAngleDamping(.99);
60
+ LJS.setCameraScale(4*16);
27
61
 
28
62
  // create a table of all sprites
29
- const gameTile = (i, size=16)=> tile(i, size, 0, 1);
63
+ const gameTile = (i, size=16)=> LJS.tile(i, size, 0, 1);
30
64
  spriteAtlas =
31
65
  {
32
66
  // large tiles
@@ -41,11 +75,7 @@ function gameInit()
41
75
  grenade: gameTile(vec2(1,2),8),
42
76
  };
43
77
 
44
- // setup level
45
- buildLevel();
46
-
47
- // init game
48
- score = deaths = 0;
78
+ loadLevel();
49
79
  }
50
80
 
51
81
  ///////////////////////////////////////////////////////////////////////////////
@@ -54,48 +84,40 @@ function gameUpdate()
54
84
  // respawn player
55
85
  if (player.deadTimer > 1)
56
86
  {
57
- player = new Player(playerStartPos);
87
+ player = new GamePlayer.Player(GameLevel.playerStartPos);
58
88
  player.velocity = vec2(0,.1);
59
- sound_jump.play();
89
+ GameEffects.sound_jump.play();
60
90
  }
61
91
 
62
92
  // mouse wheel = zoom
63
- cameraScale = clamp(cameraScale*(1-mouseWheel/10), 1, 1e3);
93
+ LJS.setCameraScale(LJS.clamp(LJS.cameraScale*(1-LJS.mouseWheel/10), 1, 1e3));
64
94
 
65
95
  // T = drop test crate
66
- if (keyWasPressed('KeyT'))
67
- new Crate(mousePos);
96
+ if (LJS.keyWasPressed('KeyT'))
97
+ new GameObjects.Crate(LJS.mousePos);
68
98
 
69
99
  // E = drop enemy
70
- if (keyWasPressed('KeyE'))
71
- new Enemy(mousePos);
100
+ if (LJS.keyWasPressed('KeyE'))
101
+ new GameObjects.Enemy(LJS.mousePos);
72
102
 
73
103
  // X = make explosion
74
- if (keyWasPressed('KeyX'))
75
- explosion(mousePos);
104
+ if (LJS.keyWasPressed('KeyX'))
105
+ GameEffects.explosion(LJS.mousePos);
76
106
 
77
107
  // M = move player to mouse
78
- if (keyWasPressed('KeyM'))
79
- player.pos = mousePos;
108
+ if (LJS.keyWasPressed('KeyM'))
109
+ player.pos = LJS.mousePos;
80
110
 
81
111
  // R = restart level
82
- if (keyWasPressed('KeyR'))
83
- buildLevel();
84
- }
85
-
86
- ///////////////////////////////////////////////////////////////////////////////
87
- function getCameraTarget()
88
- {
89
- // camera is above player
90
- const offset = 200/cameraScale*percent(mainCanvasSize.y, 300, 600);
91
- return player.pos.add(vec2(0, offset));
112
+ if (LJS.keyWasPressed('KeyR'))
113
+ loadLevel();
92
114
  }
93
115
 
94
116
  ///////////////////////////////////////////////////////////////////////////////
95
117
  function gameUpdatePost()
96
118
  {
97
119
  // update camera
98
- cameraPos = cameraPos.lerp(getCameraTarget(), clamp(player.getAliveTime()/2));
120
+ LJS.setCameraPos(LJS.cameraPos.lerp(GameLevel.getCameraTarget(), LJS.clamp(player.getAliveTime()/2)));
99
121
  }
100
122
 
101
123
  ///////////////////////////////////////////////////////////////////////////////
@@ -109,18 +131,19 @@ function gameRenderPost()
109
131
  // draw to overlay canvas for hud rendering
110
132
  const drawText = (text, x, y, size=40) =>
111
133
  {
112
- overlayContext.textAlign = 'center';
113
- overlayContext.textBaseline = 'top';
114
- overlayContext.font = size + 'px arial';
115
- overlayContext.fillStyle = '#fff';
116
- overlayContext.lineWidth = 3;
117
- overlayContext.strokeText(text, x, y);
118
- overlayContext.fillText(text, x, y);
134
+ const context = LJS.overlayContext;
135
+ context.textAlign = 'center';
136
+ context.textBaseline = 'top';
137
+ context.font = size + 'px arial';
138
+ context.fillStyle = '#fff';
139
+ context.lineWidth = 3;
140
+ context.strokeText(text, x, y);
141
+ context.fillText(text, x, y);
119
142
  }
120
- drawText('Score: ' + score, overlayCanvas.width*1/4, 20);
121
- drawText('Deaths: ' + deaths, overlayCanvas.width*3/4, 20);
143
+ drawText('Score: ' + score, LJS.overlayCanvas.width*1/4, 20);
144
+ drawText('Deaths: ' + deaths, LJS.overlayCanvas.width*3/4, 20);
122
145
  }
123
146
 
124
147
  ///////////////////////////////////////////////////////////////////////////////
125
148
  // Startup LittleJS Engine
126
- engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png', 'tilesLevel.png']);
149
+ LJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png', 'tilesLevel.png']);
@@ -11,13 +11,21 @@
11
11
 
12
12
  'use strict';
13
13
 
14
- class Character extends GameObject
14
+ // import LittleJS module
15
+ import * as LJS from '../../dist/littlejs.esm.js';
16
+ import * as GameObjects from './gameObjects.js';
17
+ import * as GameEffects from './gameEffects.js';
18
+ import * as GameLevel from './gameLevel.js';
19
+ import * as Game from './game.js';
20
+ const {vec2, hsl, Timer} = LJS;
21
+
22
+ export class Character extends GameObjects.GameObject
15
23
  {
16
24
  constructor(pos)
17
25
  {
18
26
  super(pos, vec2(.6,.95));
19
27
 
20
- this.weapon = new Weapon(pos, this);
28
+ this.weapon = new GameObjects.Weapon(pos, this);
21
29
  this.lastPos = pos;
22
30
  this.groundTimer = new Timer;
23
31
  this.jumpTimer = new Timer;
@@ -27,7 +35,7 @@ class Character extends GameObject
27
35
  this.deadTimer = new Timer;
28
36
  this.grenadeThrowTimer = new Timer;
29
37
  this.drawSize = vec2(1);
30
- this.color = hsl(rand(),1,.7);
38
+ this.color = hsl(LJS.rand(),1,.7);
31
39
  this.renderOrder = 10;
32
40
  this.walkCyclePercent = 0;
33
41
  this.health = 1;
@@ -63,7 +71,7 @@ class Character extends GameObject
63
71
  if (this.dodgeTimer.active())
64
72
  {
65
73
  // update roll
66
- this.angle = this.getMirrorSign()*2*PI*this.dodgeTimer.getPercent();
74
+ this.angle = this.getMirrorSign()*2*LJS.PI*this.dodgeTimer.getPercent();
67
75
  if (this.groundObject)
68
76
  this.velocity.x += this.getMirrorSign()*.1;
69
77
  }
@@ -77,7 +85,7 @@ class Character extends GameObject
77
85
  this.dodgeTimer.set(.4);
78
86
  this.dodgeRechargeTimer.set(2);
79
87
  this.jumpTimer.unset();
80
- sound_dodge.play(this.pos);
88
+ GameEffects.sound_dodge.play(this.pos);
81
89
 
82
90
  if (!this.groundObject && this.getAliveTime() > .2)
83
91
  this.velocity.y += .2;
@@ -85,10 +93,11 @@ class Character extends GameObject
85
93
  if (this.pressingThrow && !this.wasPressingThrow && !this.grenadeThrowTimer.active())
86
94
  {
87
95
  // throw grenade
88
- const grenade = new Grenade(this.pos);
89
- grenade.velocity = this.velocity.add(vec2(this.getMirrorSign(),rand(.8,.7)).normalize(.2+rand(.02)));
90
- grenade.angleVelocity = this.getMirrorSign() * rand(.8,.5);
91
- sound_jump.play(this.pos);
96
+ const grenade = new GameObjects.Grenade(this.pos);
97
+ const speed = vec2(this.getMirrorSign(),LJS.rand(.8,.7)).normalize(.2+LJS.rand(.02));
98
+ grenade.velocity = this.velocity.add(speed);
99
+ grenade.angleVelocity = this.getMirrorSign() * LJS.rand(.8,.5);
100
+ GameEffects.sound_jump.play(this.pos);
92
101
  this.grenadeThrowTimer.set(1);
93
102
  }
94
103
  this.wasPressingThrow = this.pressingThrow;
@@ -99,8 +108,8 @@ class Character extends GameObject
99
108
  for (let y=2;y--;)
100
109
  {
101
110
  const testPos = this.pos.add(vec2(0, y + .1*moveInput.y - this.size.y/2));
102
- const collisionData = getTileCollisionData(testPos);
103
- touchingLadder ||= collisionData == tileType_ladder;
111
+ const collisionData = LJS.getTileCollisionData(testPos);
112
+ touchingLadder ||= collisionData == GameLevel.tileType_ladder;
104
113
  }
105
114
  if (!touchingLadder)
106
115
  this.climbingLadder = false;
@@ -120,11 +129,11 @@ class Character extends GameObject
120
129
 
121
130
  // pull towards ladder
122
131
  const delta = (this.pos.x|0)+.5 - this.pos.x;
123
- this.velocity.x += .02*delta*abs(moveInput.x ? 0:moveInput.y);
132
+ this.velocity.x += .02*delta*LJS.abs(moveInput.x ? 0:moveInput.y);
124
133
  moveInput.x *= .2;
125
134
 
126
135
  // exit ladder if ground is below
127
- this.climbingLadder = moveInput.y >= 0 || getTileCollisionData(this.pos.subtract(vec2(0,1))) <= 0;
136
+ this.climbingLadder = moveInput.y >= 0 || LJS.getTileCollisionData(this.pos.subtract(vec2(0,1))) <= 0;
128
137
  }
129
138
  else
130
139
  {
@@ -132,8 +141,7 @@ class Character extends GameObject
132
141
  if (this.groundObject || this.climbingWall)
133
142
  {
134
143
  if (!this.groundTimer.isSet())
135
- sound_walk.play(this.pos); // land sound
136
-
144
+ GameEffects.sound_walk.play(this.pos); // land sound
137
145
  this.groundTimer.set(.1);
138
146
  }
139
147
 
@@ -150,7 +158,7 @@ class Character extends GameObject
150
158
  this.velocity.y = .15;
151
159
  this.jumpTimer.set(.2);
152
160
  }
153
- sound_jump.play(this.pos);
161
+ GameEffects.sound_jump.play(this.pos);
154
162
  }
155
163
  }
156
164
 
@@ -165,20 +173,20 @@ class Character extends GameObject
165
173
  if (!this.groundObject)
166
174
  {
167
175
  // air control
168
- if (sign(moveInput.x) == sign(this.velocity.x))
176
+ if (LJS.sign(moveInput.x) == LJS.sign(this.velocity.x))
169
177
  moveInput.x *= .1; // moving with velocity
170
178
  else
171
179
  moveInput.x *= .2; // moving against velocity (stopping)
172
180
 
173
181
  // slight extra gravity when moving down
174
182
  if (this.velocity.y < 0)
175
- this.velocity.y += gravity*.2;
183
+ this.velocity.y += LJS.gravity.y*.2;
176
184
  }
177
185
  }
178
186
 
179
187
  // apply movement acceleration and clamp
180
188
  const maxCharacterSpeed = .2;
181
- this.velocity.x = clamp(this.velocity.x + moveInput.x * .04, -maxCharacterSpeed, maxCharacterSpeed);
189
+ this.velocity.x = LJS.clamp(this.velocity.x + moveInput.x * .04, -maxCharacterSpeed, maxCharacterSpeed);
182
190
 
183
191
  // track last pos for ladder collision code
184
192
  this.lastPos = this.pos.copy();
@@ -191,7 +199,7 @@ class Character extends GameObject
191
199
  if (this.climbingLadder || this.groundTimer.active() && !this.dodgeTimer.active())
192
200
  {
193
201
  this.walkCyclePercent += speed * .5;
194
- this.walkCyclePercent = speed > .01 ? mod(this.walkCyclePercent) : 0;
202
+ this.walkCyclePercent = speed > .01 ? LJS.mod(this.walkCyclePercent) : 0;
195
203
  }
196
204
  else
197
205
  this.walkCyclePercent = 0;
@@ -203,7 +211,7 @@ class Character extends GameObject
203
211
  if (this.walkSoundTime > 1)
204
212
  {
205
213
  this.walkSoundTime = this.walkSoundTime%1;
206
- sound_walk.play(this.pos);
214
+ GameEffects.sound_walk.play(this.pos);
207
215
  }
208
216
  }
209
217
  else
@@ -220,18 +228,18 @@ class Character extends GameObject
220
228
  const animationFrame = this.isDead() ? 0 :
221
229
  this.climbingLadder || this.groundTimer.active() ?
222
230
  2*this.walkCyclePercent|0 : 1;
223
- this.tileInfo = spriteAtlas.player.frame(animationFrame);
231
+ this.tileInfo = Game.spriteAtlas.player.frame(animationFrame);
224
232
 
225
233
  let bodyPos = this.pos;
226
234
  if (!this.isDead())
227
235
  {
228
236
  // bounce pos with walk cycle
229
- bodyPos = bodyPos.add(vec2(0,.01+.05*Math.sin(this.walkCyclePercent*PI)));
237
+ bodyPos = bodyPos.add(vec2(0,.01+.05*Math.sin(this.walkCyclePercent*LJS.PI)));
230
238
 
231
239
  // make bottom flush
232
240
  bodyPos = bodyPos.add(vec2(0,(this.drawSize.y-this.size.y)/2));
233
241
  }
234
- drawTile(bodyPos, this.drawSize, this.tileInfo, this.color, this.angle, this.mirror);
242
+ LJS.drawTile(bodyPos, this.drawSize, this.tileInfo, this.color, this.angle, this.mirror);
235
243
  }
236
244
 
237
245
  damage(damage, damagingObject)
@@ -239,7 +247,7 @@ class Character extends GameObject
239
247
  if (this.isDead() || this.getAliveTime() < 1 || this.dodgeTimer.active())
240
248
  return 0;
241
249
 
242
- makeBlood(damagingObject ? damagingObject.pos : this.pos);
250
+ GameEffects.makeBlood(damagingObject ? damagingObject.pos : this.pos);
243
251
  return super.damage(damage, damagingObject);
244
252
  }
245
253
 
@@ -248,14 +256,14 @@ class Character extends GameObject
248
256
  if (this.isDead())
249
257
  return;
250
258
 
251
- makeBlood(this.pos, 100);
252
- sound_die.play(this.pos);
259
+ GameEffects.makeBlood(this.pos, 100);
260
+ GameEffects.sound_die.play(this.pos);
253
261
 
254
262
  this.health = 0;
255
263
  this.deadTimer.set();
256
264
  this.size = this.size.scale(.5);
257
- const fallDirection = damagingObject ? sign(damagingObject.velocity.x) : randSign();
258
- this.angleVelocity = fallDirection*rand(.22,.14);
265
+ const fallDirection = damagingObject ? LJS.sign(damagingObject.velocity.x) : LJS.randSign();
266
+ this.angleVelocity = fallDirection*LJS.rand(.22,.14);
259
267
  this.angleDamping = .9;
260
268
  this.renderOrder = -1; // move to back layer
261
269
  if (this.weapon)
@@ -267,15 +275,15 @@ class Character extends GameObject
267
275
  if (!data)
268
276
  return false;
269
277
 
270
- if (data == tileType_ladder)
278
+ if (data == GameLevel.tileType_ladder)
271
279
  {
272
280
  // handle ladder collisions
273
281
  if (pos.y + 1 > this.lastPos.y - this.size.y/2)
274
282
  return false;
275
283
 
276
- if (getTileCollisionData(pos.add(vec2(0,1))) // above
277
- && !getTileCollisionData(pos.add(vec2(1,0))) // left
278
- && !getTileCollisionData(pos.add(vec2(1,0)))) // right
284
+ if (LJS.getTileCollisionData(pos.add(vec2(0,1))) // above
285
+ && !LJS.getTileCollisionData(pos.add(vec2(1,0))) // left
286
+ && !LJS.getTileCollisionData(pos.add(vec2(1,0)))) // right
279
287
  return false; // don't collide if something above it and nothing to left or right
280
288
 
281
289
  // allow standing on top of ladders
@@ -284,7 +292,7 @@ class Character extends GameObject
284
292
 
285
293
  const d = pos.y - this.pos.y;
286
294
  if (!this.climbingLadder && this.velocity.y > .1 && d > 0 && d < this.size.y/2)
287
- if (destroyTile(pos))
295
+ if (GameEffects.destroyTile(pos))
288
296
  {
289
297
  // break blocks above
290
298
  this.velocity.y = 0;