littlejsengine 1.14.10 → 1.14.16
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/littlejs.d.ts +264 -120
- package/dist/littlejs.esm.js +603 -288
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +600 -287
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +521 -232
- package/examples/box2d/gameObjects.js +2 -2
- package/examples/breakout/gameObjects.js +2 -2
- package/examples/breakoutTutorial/README.md +32 -32
- package/examples/breakoutTutorial/game.js +1 -1
- package/examples/electron/game.js +3 -3
- package/examples/electron/index.html +2 -2
- package/examples/electron/package.json +1 -8
- package/examples/index.html +59 -51
- package/examples/module/game.js +3 -3
- package/examples/platformer/gameCharacter.js +6 -2
- package/examples/platformer/gameEffects.js +4 -4
- package/examples/platformer/gameLevel.js +1 -1
- package/examples/platformer/gameObjects.js +11 -9
- package/examples/puzzle/game.js +1 -1
- package/examples/shorts/animation.js +1 -1
- package/examples/shorts/base.html +1 -1
- package/examples/shorts/blending.js +8 -14
- package/examples/shorts/box2d.js +7 -3
- package/examples/shorts/box2dCar.js +2 -1
- package/examples/shorts/empty.js +30 -0
- package/examples/shorts/helloWorld.js +1 -1
- package/examples/shorts/hillGlideGame.js +10 -4
- package/examples/shorts/landerGame.js +30 -3
- package/examples/shorts/medals.js +4 -4
- package/examples/shorts/music.js +29 -55
- package/examples/shorts/musicPlayer.js +134 -0
- package/examples/shorts/nineSlice.js +34 -15
- package/examples/shorts/parallax.js +4 -3
- package/examples/shorts/particles.js +16 -16
- package/examples/shorts/piano.js +15 -21
- package/examples/shorts/pongGame.js +6 -4
- package/examples/shorts/raycasting.js +13 -5
- package/examples/shorts/sequencer.js +122 -0
- package/examples/shorts/shapes.js +7 -4
- package/examples/shorts/slidingPuzzle.js +16 -6
- package/examples/shorts/sound.js +18 -9
- package/examples/shorts/spaceGame.js +12 -8
- package/examples/shorts/spriteAtlas.js +7 -7
- package/examples/shorts/starfield.js +1 -1
- package/examples/shorts/systemFont.js +2 -2
- package/examples/shorts/texture.js +2 -2
- package/examples/shorts/tileLayer.js +10 -10
- package/examples/shorts/tiltedView.js +14 -3
- package/examples/shorts/timers.js +10 -0
- package/examples/shorts/topDown.js +4 -1
- package/examples/shorts/uiSystem.js +8 -5
- package/examples/starter/game.js +3 -3
- package/examples/starter/index.html +2 -2
- package/examples/typescript/game.js +3 -3
- package/examples/typescript/game.ts +3 -3
- package/examples/uiSystem/game.js +6 -6
- package/package.json +4 -2
- package/plugins/box2d.js +18 -3
- package/plugins/newgrounds.js +11 -9
- package/plugins/postProcess.js +5 -2
- package/plugins/uiSystem.js +120 -34
- package/plugins/zzfxm.js +5 -1
- package/reference.md +1 -3
- package/src/engine.js +52 -21
- package/src/engineAudio.js +31 -14
- package/src/engineDebug.js +80 -55
- package/src/engineDraw.js +60 -31
- package/src/engineExport.js +3 -1
- package/src/engineMedals.js +10 -2
- package/src/engineObject.js +14 -10
- package/src/engineParticles.js +59 -46
- package/src/engineRelease.js +1 -0
- package/src/engineSettings.js +7 -7
- package/src/engineTileLayer.js +49 -18
- package/src/engineUtilities.js +79 -34
|
@@ -471,7 +471,7 @@ export function explosion(pos, radius=3, strength=300)
|
|
|
471
471
|
// smoke
|
|
472
472
|
new LJS.ParticleEmitter(
|
|
473
473
|
pos, 0, // pos, angle
|
|
474
|
-
radius/2, .2, 50*radius, 3.14,// emitSize, emitTime,
|
|
474
|
+
radius/2, .2, 50*radius, 3.14,// emitSize, emitTime, rate, cone
|
|
475
475
|
Game.spriteAtlas.dot, // tileInfo
|
|
476
476
|
hsl(0,0,0), hsl(0,0,0), // colorStartA, colorStartB
|
|
477
477
|
hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
|
|
@@ -483,7 +483,7 @@ export function explosion(pos, radius=3, strength=300)
|
|
|
483
483
|
// fire
|
|
484
484
|
new LJS.ParticleEmitter(
|
|
485
485
|
pos, 0, // pos, angle
|
|
486
|
-
radius, .1, 100*radius, 3.14, // emitSize, emitTime,
|
|
486
|
+
radius, .1, 100*radius, 3.14, // emitSize, emitTime, rate, cone
|
|
487
487
|
Game.spriteAtlas.dot, // tileInfo
|
|
488
488
|
hsl(0,1,.5), hsl(.15,1,.5), // colorStartA, colorStartB
|
|
489
489
|
hsl(0,1,.5,0), hsl(.1, 1,.5,0), // colorEndA, colorEndB
|
|
@@ -74,7 +74,7 @@ export class Brick extends PhysicsObject
|
|
|
74
74
|
const color2 = color1.lerp(hsl(), .5);
|
|
75
75
|
new LJS.ParticleEmitter(
|
|
76
76
|
this.pos, 0, // pos, angle
|
|
77
|
-
this.size, .1, 200, 3.14, // emitSize, emitTime,
|
|
77
|
+
this.size, .1, 200, 3.14, // emitSize, emitTime, rate, cone
|
|
78
78
|
tile(0, 16), // tileIndex, tileSize
|
|
79
79
|
color1, color2, // colorStartA, colorStartB
|
|
80
80
|
color1.scale(1,0), color2.scale(1,0), // colorEndA, colorEndB
|
|
@@ -110,7 +110,7 @@ export class Ball extends PhysicsObject
|
|
|
110
110
|
const color = hsl(0,0,.2);
|
|
111
111
|
this.trailEffect = new LJS.ParticleEmitter(
|
|
112
112
|
this.pos, 0, // pos, angle
|
|
113
|
-
this.size, 0, 80, 3.14, // emitSize, emitTime,
|
|
113
|
+
this.size, 0, 80, 3.14, // emitSize, emitTime, rate, cone
|
|
114
114
|
tile(0, 16), // tileIndex, tileSize
|
|
115
115
|
color, color, // colorStartA, colorStartB
|
|
116
116
|
color.scale(0), color.scale(0), // colorEndA, colorEndB
|
|
@@ -33,11 +33,11 @@ That will make a square of 20×20 engine objects, we can adjust it as we go. It
|
|
|
33
33
|
|
|
34
34
|

|
|
35
35
|
|
|
36
|
-
It is completely off center and may not look like much yet, but it
|
|
36
|
+
It is completely off center and may not look like much yet, but it's a start!
|
|
37
37
|
|
|
38
38
|
## Improve the Bricks
|
|
39
39
|
|
|
40
|
-
Let
|
|
40
|
+
Let's make the bricks more rectangular by passing vec2(2,1) to the size parameter of Engine Object. We will need to adjust the loop to add 2 for each x iteration. Also we can use a Vector2 to describe the size of the level.
|
|
41
41
|
|
|
42
42
|
```javascript
|
|
43
43
|
// create bricks
|
|
@@ -52,7 +52,7 @@ for (let y=0; y<=levelSize.y; y+=1)
|
|
|
52
52
|
|
|
53
53
|
## Move the Camera
|
|
54
54
|
|
|
55
|
-
Let
|
|
55
|
+
Let's move the camera to the center of our level by setting the cameraPos variable to half the level size.
|
|
56
56
|
You can also change the camera zoom by using camaraScale which controls the number of pixels for each world space unit.
|
|
57
57
|
For this example the camera will just remain stationary, but in other types of games it is very useful!
|
|
58
58
|
|
|
@@ -60,7 +60,7 @@ For this example the camera will just remain stationary, but in other types of g
|
|
|
60
60
|
LJS.setCameraPos(levelSize.scale(.5)); // center camera in level
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
We
|
|
63
|
+
We'll also start with a blank slate by commenting out the default “Hello World!” text in gameRenderPost.
|
|
64
64
|
|
|
65
65
|
```javascript
|
|
66
66
|
// LJS.drawTextScreen('Hello World!', LJS.mainCanvasSize.scale(.5), 80);
|
|
@@ -68,11 +68,11 @@ We’ll also start with a blank slate by commenting out the default “Hello Wor
|
|
|
68
68
|
|
|
69
69
|

|
|
70
70
|
|
|
71
|
-
It
|
|
71
|
+
It is getting closer! The camera is now centered and blocks are rectangular.
|
|
72
72
|
|
|
73
73
|
## Modify the Level Size
|
|
74
74
|
|
|
75
|
-
For this example we will use a fixed size canvas. This will let the drawing canvas always be the same resolution, even if the window size changes. Black space is added on the sides to compensate. It
|
|
75
|
+
For this example we will use a fixed size canvas. This will let the drawing canvas always be the same resolution, even if the window size changes. Black space is added on the sides to compensate. It is a great option for any game that uses a single screen like this.
|
|
76
76
|
|
|
77
77
|
To enable it we will set canvasFixedSize in gameInit to use 720p resolution.
|
|
78
78
|
|
|
@@ -80,7 +80,7 @@ To enable it we will set canvasFixedSize in gameInit to use 720p resolution.
|
|
|
80
80
|
LJS.setCanvasFixedSize(vec2(1280, 720)); // use a 720p fixed size canvas
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
Before we tweak the level size, let
|
|
83
|
+
Before we tweak the level size, let's add this bit of code to gameRender to show the size of the level. This will cause some rects to be drawn each frame before the engine objects. To create color objects we pass in RGB values between 0 and 1.
|
|
84
84
|
|
|
85
85
|
```javascript
|
|
86
86
|
LJS.drawRect(LJS.cameraPos, vec2(100), rgb(.5,.5,.5)); // draw background
|
|
@@ -112,7 +112,7 @@ Now that looks almost like a breakout game!
|
|
|
112
112
|
|
|
113
113
|
## Create the Player Paddle
|
|
114
114
|
|
|
115
|
-
For the player
|
|
115
|
+
For the player's paddle, let's create a new class of object that extends the built in EngineObject. This will allow us to control movement with the mouse. In this Paddle class we will just add some new code to the update function which is automatically called each frame by the engine.
|
|
116
116
|
|
|
117
117
|
```javascript
|
|
118
118
|
class Paddle extends LJS.EngineObject
|
|
@@ -132,7 +132,7 @@ new Paddle; // create player's paddle
|
|
|
132
132
|
|
|
133
133
|
There is now a square paddle that moves along the bottom of the screen.
|
|
134
134
|
|
|
135
|
-
Let
|
|
135
|
+
Let's make the paddle wider and move it up a smidge by adding a constructor to the Paddle class.
|
|
136
136
|
|
|
137
137
|
```javascript
|
|
138
138
|
constructor()
|
|
@@ -153,7 +153,7 @@ this.pos.x = LJS.clamp(this.pos.x, this.size.x/2, levelSize.x - this.size.x/2);
|
|
|
153
153
|
```
|
|
154
154
|
|
|
155
155
|
## Create the Ball
|
|
156
|
-
The final missing piece is of course that ball that moves around and bounces off of stuff. We will leverage the built in physics solver to handle all the ball
|
|
156
|
+
The final missing piece is of course that ball that moves around and bounces off of stuff. We will leverage the built in physics solver to handle all the ball's physics and collision math.
|
|
157
157
|
|
|
158
158
|
We can create a Ball class the same way we created the paddle. In this case we will also apply some velocity to ball so it starts moving right away.
|
|
159
159
|
|
|
@@ -169,7 +169,7 @@ class Ball extends LJS.EngineObject
|
|
|
169
169
|
}
|
|
170
170
|
```
|
|
171
171
|
|
|
172
|
-
Then we just need to create the ball in gameInit, passing in the camera position for
|
|
172
|
+
Then we just need to create the ball in gameInit, passing in the camera position for its location.
|
|
173
173
|
|
|
174
174
|
```javascript
|
|
175
175
|
{
|
|
@@ -186,13 +186,13 @@ You may have noticed that the ball goes right through the paddle and bricks. To
|
|
|
186
186
|
this.setCollision(); // make object collide
|
|
187
187
|
```
|
|
188
188
|
|
|
189
|
-
Now the ball collides but unfortunately also pushes the paddle away, not quite what we want. To prevent the paddle from being moved by physics we will make it use static physics by setting
|
|
189
|
+
Now the ball collides but unfortunately also pushes the paddle away, not quite what we want. To prevent the paddle from being moved by physics we will make it use static physics by setting its mass to 0 in the paddle constructor.
|
|
190
190
|
|
|
191
191
|
```javascript
|
|
192
192
|
this.mass = 0; // make object have static physics
|
|
193
193
|
```
|
|
194
194
|
|
|
195
|
-
Getting closer, the paddle is not pushed away but the ball doesn
|
|
195
|
+
Getting closer, the paddle is not pushed away but the ball doesn't bounce either. To make it bounce, we need to set the ball's restitution which controls how much it will bounce.
|
|
196
196
|
|
|
197
197
|
```javascript
|
|
198
198
|
this.restitution = 1; // make object bounce
|
|
@@ -202,7 +202,7 @@ this.restitution = 1; // make object bounce
|
|
|
202
202
|
|
|
203
203
|
It works! The ball now bounces off the paddle, still not the walls or blocks yet though.
|
|
204
204
|
|
|
205
|
-
Before we continue, let
|
|
205
|
+
Before we continue, let's make the ball a bit smaller by changing the super call in its constructor.
|
|
206
206
|
|
|
207
207
|
```javascript
|
|
208
208
|
super(pos, vec2(.5)); // set object position and size
|
|
@@ -210,7 +210,7 @@ super(pos, vec2(.5)); // set object position and size
|
|
|
210
210
|
|
|
211
211
|
## Make the Ball Bounce Off Walls
|
|
212
212
|
|
|
213
|
-
Next, let
|
|
213
|
+
Next, let's make the ball bounce when it hits the top or sides of the screen. To do this, we will make a Wall object class that works similar to the paddle but without an update function.
|
|
214
214
|
|
|
215
215
|
```javascript
|
|
216
216
|
class Wall extends LJS.EngineObject
|
|
@@ -275,11 +275,11 @@ if (!ball || ball.pos.y < -1)
|
|
|
275
275
|
}
|
|
276
276
|
```
|
|
277
277
|
|
|
278
|
-
Don
|
|
278
|
+
Don't forget to destroy the old ball before creating the new one! Though it doesn't really matter for this simple example, it would cause the old balls to continue existing while being updated and rendered. That could really slow things in bigger games with thousands of objects.
|
|
279
279
|
|
|
280
280
|
## Break the Bricks
|
|
281
281
|
|
|
282
|
-
Still, the ball doesn
|
|
282
|
+
Still, the ball doesn't collide with the bricks much less breaks them and it wouldn't be breakout without that. So we need to make the brick collide with the ball, just like the walls, so let's start with Brick class that is the same as Wall.
|
|
283
283
|
|
|
284
284
|
```javascript
|
|
285
285
|
class Brick extends LJS.EngineObject
|
|
@@ -300,7 +300,7 @@ And we will just change the for loop in gameInit to use the Brick class.
|
|
|
300
300
|
const brick = new Brick(vec2(x,y), vec2(2,1)); // create a brick
|
|
301
301
|
```
|
|
302
302
|
|
|
303
|
-
Now the ball will bounce off the bricks, but we want it to break the bricks. To do this we can override the brick
|
|
303
|
+
Now the ball will bounce off the bricks, but we want it to break the bricks. To do this we can override the brick's collideWithObject function which is called by the engine when the ball hits it. Instead of the default collide behavior, we just destroy the brick.
|
|
304
304
|
|
|
305
305
|
```javascript
|
|
306
306
|
collideWithObject(o)
|
|
@@ -319,7 +319,7 @@ return true; // allow object to collide
|
|
|
319
319
|
|
|
320
320
|
Success, we have breakout! All the core components are here though there are a few more changes we can make that will greatly increase the playability.
|
|
321
321
|
|
|
322
|
-
## Track the Player
|
|
322
|
+
## Track the Player's Score
|
|
323
323
|
|
|
324
324
|
We can easily add a score tracker to the game by making a global score variable called score.
|
|
325
325
|
|
|
@@ -343,7 +343,7 @@ LJS.drawTextScreen('Score ' + score, vec2(LJS.mainCanvasSize.x/2, 70), 50); // s
|
|
|
343
343
|
|
|
344
344
|
## Add Sound Effects
|
|
345
345
|
|
|
346
|
-
So far the game is completely silent. Let
|
|
346
|
+
So far the game is completely silent. Let's add sounds using ZzFX. This is a tiny sound effect generator that works in conjunction with LittleJS and can be used on its own too.
|
|
347
347
|
|
|
348
348
|
We will start with the ball bounce sound. [You can use the official ZzFX sound designer to create your own sound.](https://killedbyapixel.github.io/ZzFX/) I recommend using the Blip preset for this one.
|
|
349
349
|
|
|
@@ -364,7 +364,7 @@ collideWithObject(o)
|
|
|
364
364
|
return true; // allow object to collide
|
|
365
365
|
}
|
|
366
366
|
```
|
|
367
|
-
Let
|
|
367
|
+
Let's also make a brick break sound. You can use the ZzFX sound designer again to create your own sound, for this one try the Hit preset.
|
|
368
368
|
|
|
369
369
|
Create a global object for this sound the same way we did for the bounce sound. You can replace it with your own generated sound or use mine.
|
|
370
370
|
|
|
@@ -372,17 +372,17 @@ Create a global object for this sound the same way we did for the bounce sound.
|
|
|
372
372
|
const sound_break = new LJS.Sound([,,90,,.01,.03,4,,,,,,,9,50,.2,,.2,.01], 0);
|
|
373
373
|
```
|
|
374
374
|
|
|
375
|
-
Then in the Brick
|
|
375
|
+
Then in the Brick's collideWithObject function just add some code to play that sound.
|
|
376
376
|
|
|
377
377
|
```javascript
|
|
378
378
|
sound_break.play(); // play brick break sound
|
|
379
379
|
```
|
|
380
380
|
|
|
381
|
-
Now you should hear sound as the ball bounces around and breaks bricks! Of course it
|
|
381
|
+
Now you should hear sound as the ball bounces around and breaks bricks! Of course it is easy to swap out these sounds with other ones, feel free to experiment.
|
|
382
382
|
|
|
383
383
|
## Add Click To Start Interaction
|
|
384
384
|
|
|
385
|
-
Let
|
|
385
|
+
Let's improve the gameplay by letting the player click to start, instead of creating the ball right away. This will also ensure that the player has clicked which is requirement for audio to play in most browsers.
|
|
386
386
|
|
|
387
387
|
We can also add a special sound that plays on startup. Try making an interesting start from the ZzFX sound designer, maybe using the Powerup preset.
|
|
388
388
|
|
|
@@ -408,9 +408,9 @@ if (!ball && LJS.mouseWasPressed(0)) // if there is no ball and left mouse is pr
|
|
|
408
408
|
|
|
409
409
|
## Add Particle Effects
|
|
410
410
|
|
|
411
|
-
Let
|
|
411
|
+
Let's add some effects when the bricks break. You can use the LittleJS particle system designer to create an explosion effect.
|
|
412
412
|
|
|
413
|
-
This will be a one shot type of effect, not a continuous emitter so change emitTime to something small like .1 for this example. Now before you play with it too much, let
|
|
413
|
+
This will be a one shot type of effect, not a continuous emitter so change emitTime to something small like .1 for this example. Now before you play with it too much, let's test it by pasting in the code it generated into the Brick's collideWithObject function.
|
|
414
414
|
|
|
415
415
|
Make sure you replace the first parameter, vec2(), with this.pos so the effect appears wherever the brick is, otherwise it will spawn at the world origin.
|
|
416
416
|
|
|
@@ -419,14 +419,14 @@ Make sure you replace the first parameter, vec2(), with this.pos so the effect a
|
|
|
419
419
|
new LJS.ParticleEmitter(this.pos, 0, 0, 0.1, 100, 3.14, 0, rgb(1, 1, 1, 1), rgb(1, 1, 1, 1), rgb(1, 1, 1, 0), rgb(1, 1, 1, 0), 0.5, 0.1, 1, 0.1, 0.05, 1, 1, 0, 3.14, 0.1, 0.2, 0, 0, 1);
|
|
420
420
|
```
|
|
421
421
|
|
|
422
|
-
Now you should see this simple particle effect play wherever a brick breaks. You can continue tweaking the parameters to make your own effect or use the one I made which also uses this.color to change the particle
|
|
422
|
+
Now you should see this simple particle effect play wherever a brick breaks. You can continue tweaking the parameters to make your own effect or use the one I made which also uses this.color to change the particle's color so it matches the brick.
|
|
423
423
|
|
|
424
424
|
```javascript
|
|
425
425
|
// create explosion effect
|
|
426
426
|
const color = this.color;
|
|
427
427
|
new LJS.ParticleEmitter(
|
|
428
428
|
this.pos, 0, // pos, angle
|
|
429
|
-
this.size, .1, 200, 3.14,// emitSize, emitTime,
|
|
429
|
+
this.size, .1, 200, 3.14,// emitSize, emitTime, rate, cone
|
|
430
430
|
undefined, // tileInfo
|
|
431
431
|
color, color, // colorStartA, colorStartB
|
|
432
432
|
color.scale(1,0), color.scale(1,0), // colorEndA, colorEndB
|
|
@@ -440,7 +440,7 @@ new LJS.ParticleEmitter(
|
|
|
440
440
|
|
|
441
441
|
## Improve the Gameplay
|
|
442
442
|
|
|
443
|
-
Last but certainly not least, let
|
|
443
|
+
Last but certainly not least, let's make a few small improvements to the gameplay. It would help to give the player some more control of where the ball goes when it hits the paddle. We can do this by adding some code to the ball's collideWithObject function.
|
|
444
444
|
|
|
445
445
|
This code will use the rotate function to modify the bounce angle based on the distance from the center of the paddle.
|
|
446
446
|
|
|
@@ -484,7 +484,7 @@ And assign that paddle object when it is created in gameInit.
|
|
|
484
484
|
paddle = new Paddle; // create player's paddle
|
|
485
485
|
```
|
|
486
486
|
|
|
487
|
-
While we are working in the ball
|
|
487
|
+
While we are working in the ball's collideWithObject function, let's also make it speed up a little bit each time it bounces.
|
|
488
488
|
|
|
489
489
|
```javascript
|
|
490
490
|
// speed up the ball
|
|
@@ -494,13 +494,13 @@ this.velocity = this.velocity.normalize(speed);
|
|
|
494
494
|
|
|
495
495
|
## Improve the Sound
|
|
496
496
|
|
|
497
|
-
|
|
497
|
+
Let's make the sound a bit more interesting by using positional audio. This lets the volume and panning be adjusted based on the sound's on screen location. To enable this, just pass a position to the sound's play function.
|
|
498
498
|
|
|
499
499
|
```javascript
|
|
500
500
|
sound_break.play(this.pos); // play brick break sound
|
|
501
501
|
```
|
|
502
502
|
|
|
503
|
-
For the ball bounce sound, let
|
|
503
|
+
For the ball bounce sound, let's also tweak the pitch by how fast the ball is moving. For the sound play function, the second parameter takes a scalar for volume and the third parameter takes a scalar for pitch.
|
|
504
504
|
|
|
505
505
|
```javascript
|
|
506
506
|
sound_bounce.play(this.pos, 1, speed); // play bounce sound with pitch scaled by speed
|
|
@@ -117,7 +117,7 @@ class Brick extends LJS.EngineObject
|
|
|
117
117
|
const color = this.color;
|
|
118
118
|
new LJS.ParticleEmitter(
|
|
119
119
|
this.pos, 0, // pos, angle
|
|
120
|
-
this.size, .1, 200, 3.14,// emitSize, emitTime,
|
|
120
|
+
this.size, .1, 200, 3.14,// emitSize, emitTime, rate, cone
|
|
121
121
|
undefined, // tileInfo
|
|
122
122
|
color, color, // colorStartA, colorStartB
|
|
123
123
|
color.scale(1,0), color.scale(1,0), // colorEndA, colorEndB
|
|
@@ -65,7 +65,7 @@ function gameInit()
|
|
|
65
65
|
// create particle emitter
|
|
66
66
|
particleEmitter = new ParticleEmitter(
|
|
67
67
|
vec2(16,9), 0, // emitPos, emitAngle
|
|
68
|
-
0, 0, 500, PI, // emitSize, emitTime,
|
|
68
|
+
0, 0, 500, PI, // emitSize, emitTime, rate, cone
|
|
69
69
|
tile(0, 16), // tileIndex, tileSize
|
|
70
70
|
hsl(1,1,1), hsl(0,0,0), // colorStartA, colorStartB
|
|
71
71
|
hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
|
|
@@ -74,7 +74,7 @@ function gameInit()
|
|
|
74
74
|
.05, .5, true, true // fadeRate, randomness, collide, additive
|
|
75
75
|
);
|
|
76
76
|
particleEmitter.restitution = .3; // bounce when it collides
|
|
77
|
-
particleEmitter.trailScale = 2; // stretch
|
|
77
|
+
particleEmitter.trailScale = 2; // stretch as it moves
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -86,7 +86,7 @@ function gameUpdate()
|
|
|
86
86
|
sound_click.play(mousePos);
|
|
87
87
|
|
|
88
88
|
// change particle color and set to fade out
|
|
89
|
-
particleEmitter.colorStartA =
|
|
89
|
+
particleEmitter.colorStartA = randColor();
|
|
90
90
|
particleEmitter.colorStartB = randColor();
|
|
91
91
|
particleEmitter.colorEndA = particleEmitter.colorStartA.scale(1,0);
|
|
92
92
|
particleEmitter.colorEndB = particleEmitter.colorStartB.scale(1,0);
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../dist/littlejs.js?
|
|
10
|
+
<script src=../../dist/littlejs.js?11416></script>
|
|
11
11
|
|
|
12
12
|
<!-- Add your game scripts here -->
|
|
13
|
-
<script src=game.js?
|
|
13
|
+
<script src=game.js?11416></script>
|
package/examples/index.html
CHANGED
|
@@ -53,7 +53,7 @@ Theme:
|
|
|
53
53
|
|
|
54
54
|
class ExampleInfo
|
|
55
55
|
{
|
|
56
|
-
constructor(name, filename, description='', largeExample=false)
|
|
56
|
+
constructor(name, filename, description='', largeExample=false, tags='')
|
|
57
57
|
{
|
|
58
58
|
if (filename && !largeExample)
|
|
59
59
|
filename = 'shorts/' + filename;
|
|
@@ -61,62 +61,69 @@ class ExampleInfo
|
|
|
61
61
|
this.filename = filename;
|
|
62
62
|
this.description = description;
|
|
63
63
|
this.largeExample = largeExample;
|
|
64
|
+
this.tags = tags;
|
|
64
65
|
this.isHeading = !filename;
|
|
65
66
|
this.text = this.name;
|
|
66
67
|
if (this.description)
|
|
67
68
|
this.text += ' - ' + this.description;
|
|
69
|
+
this.selectText = this.text;
|
|
70
|
+
if (this.tags)
|
|
71
|
+
this.selectText += ' (' + this.tags + ')';
|
|
68
72
|
}
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
const exampleList =
|
|
72
76
|
[
|
|
73
77
|
new ExampleInfo('--- SHORT EXAMPLES ---'),
|
|
74
|
-
new ExampleInfo('Hello World', 'helloWorld.js', '
|
|
75
|
-
new ExampleInfo('
|
|
76
|
-
new ExampleInfo('
|
|
77
|
-
new ExampleInfo('
|
|
78
|
-
new ExampleInfo('
|
|
79
|
-
new ExampleInfo('
|
|
80
|
-
new ExampleInfo('
|
|
81
|
-
new ExampleInfo('
|
|
82
|
-
new ExampleInfo('
|
|
83
|
-
new ExampleInfo('
|
|
84
|
-
new ExampleInfo('
|
|
85
|
-
new ExampleInfo('
|
|
86
|
-
new ExampleInfo('
|
|
87
|
-
new ExampleInfo('
|
|
88
|
-
new ExampleInfo('
|
|
89
|
-
new ExampleInfo('
|
|
90
|
-
new ExampleInfo('
|
|
91
|
-
new ExampleInfo('
|
|
92
|
-
new ExampleInfo('Clock', 'clock.js', 'Animated analog clock'),
|
|
78
|
+
new ExampleInfo('Hello World', 'helloWorld.js', 'Simple starter example', false, 'beginner, gradient, text, tiles'),
|
|
79
|
+
new ExampleInfo('Empty', 'empty.js', 'Empty example template', false, 'beginner, text'),
|
|
80
|
+
new ExampleInfo('Texture', 'texture.js', 'Texture display and manipulation', false, 'sprites, loading, tiles'),
|
|
81
|
+
new ExampleInfo('Animation', 'animation.js', 'Sprite animation system', false, 'frames, loop, tiles, sprites'),
|
|
82
|
+
new ExampleInfo('Shapes', 'shapes.js', 'Draw geometric shapes and primitives', false, 'circle, ellipses, rectangles, polygon, lines'),
|
|
83
|
+
new ExampleInfo('Colors', 'colors.js', 'Color manipulation and HSL', false, 'hue, saturation, blending, rectangles'),
|
|
84
|
+
new ExampleInfo('Starfield', 'starfield.js', 'Animated parallax starfield', false, 'space, movement, depth, rectangles'),
|
|
85
|
+
new ExampleInfo('Sprite Atlas', 'spriteAtlas.js', 'Sprite atlas and tile rendering', false, 'sheet, frames, tiles'),
|
|
86
|
+
new ExampleInfo('Blending', 'blending.js', 'Additive blending and transparency', false, 'alpha, color, tiles, smooth'),
|
|
87
|
+
new ExampleInfo('Tile Layer', 'tileLayer.js', 'Tile layer rendering system', false, 'level, map, grid, particles'),
|
|
88
|
+
new ExampleInfo('Particles', 'particles.js', 'Particle system', false, 'effects, emitter, physics, fire, smoke'),
|
|
89
|
+
new ExampleInfo('Timers', 'timers.js', 'Timer objects and UI', false, 'delay, interval, slider'),
|
|
90
|
+
new ExampleInfo('Sound Effects', 'sound.js', 'ZzFX sound effect generator', false, 'audio, volume, ui'),
|
|
91
|
+
new ExampleInfo('Music', 'music.js', 'Basic music load, play, pause, and stop', false, 'music, sound, audio, streaming, volume, ui'),
|
|
92
|
+
new ExampleInfo('Font Image', 'systemFont.js', 'Bitmap font system with built-in system font', false, 'text, characters'),
|
|
93
|
+
new ExampleInfo('Parallax', 'parallax.js', 'Parallax scrolling mountains', false, 'generative, canvas, background'),
|
|
94
|
+
new ExampleInfo('Maze Generator', 'maze.js', 'Procedural maze generation', false, 'generative, level, tiles, map, grid'),
|
|
95
|
+
new ExampleInfo('Medals', 'medals.js', 'Achievement system', false, 'unlock, progress, newgrounds'),
|
|
96
|
+
new ExampleInfo('Clock', 'clock.js', 'Animated analog clock', false, 'time, rotation, lines, rectangles'),
|
|
97
|
+
new ExampleInfo('Piano', 'piano.js', 'Interactive piano keyboard', false, 'music, sound, audio, notes, ui, instrument'),
|
|
98
|
+
new ExampleInfo('Step Sequencer', 'sequencer.js', 'Simple music loop creation tool', false, 'music, sound, audio, notes, ui, instrument'),
|
|
99
|
+
new ExampleInfo('Music Player', 'musicPlayer.js', 'Advanced music player with audio seeking and drag and drop', false, 'music, sound, audio, streaming, volume, ui'),
|
|
93
100
|
new ExampleInfo('--- MINI GAMES ---'),
|
|
94
|
-
new ExampleInfo('Pong Game', 'pongGame.js', 'Classic paddle ball bouncing'),
|
|
95
|
-
new ExampleInfo('Platformer Game', 'platformer.js', 'Jump and run side view'),
|
|
96
|
-
new ExampleInfo('Top Down Game', 'topDown.js', 'Top-down style camera'),
|
|
97
|
-
new ExampleInfo('Tilted View Game', 'tiltedView.js', 'Pseudo-3D oblique view'),
|
|
98
|
-
new ExampleInfo('Flappy Game', 'flappyGame.js', 'Flappy bird style game'),
|
|
99
|
-
new ExampleInfo('Lander Game', 'landerGame.js', 'Lunar lander style game'),
|
|
100
|
-
new ExampleInfo('Hill Glide Game', 'hillGlideGame.js', 'Tiny wings style sliding game'),
|
|
101
|
-
new ExampleInfo('Sliding Puzzle', 'slidingPuzzle.js', '15 tile sliding puzzle'),
|
|
102
|
-
new ExampleInfo('Space Game', 'spaceGame.js', 'Spaceship shooter with parallax'),
|
|
103
|
-
new ExampleInfo('Raycasting 3D Game', 'raycasting.js', '
|
|
101
|
+
new ExampleInfo('Pong Game', 'pongGame.js', 'Classic paddle ball bouncing', false, 'objects, collision'),
|
|
102
|
+
new ExampleInfo('Platformer Game', 'platformer.js', 'Jump and run side view', false, 'objects, gravity, level, tiles, camera'),
|
|
103
|
+
new ExampleInfo('Top Down Game', 'topDown.js', 'Top-down style camera', false, 'objects, movement, exploration'),
|
|
104
|
+
new ExampleInfo('Tilted View Game', 'tiltedView.js', 'Pseudo-3D oblique view', false, 'isometric, depth'),
|
|
105
|
+
new ExampleInfo('Flappy Game', 'flappyGame.js', 'Flappy bird style game', false, 'objects, obstacles'),
|
|
106
|
+
new ExampleInfo('Lander Game', 'landerGame.js', 'Lunar lander style game', false, 'objects, physics'),
|
|
107
|
+
new ExampleInfo('Hill Glide Game', 'hillGlideGame.js', 'Tiny wings style sliding game', false, 'objects, physics, speed'),
|
|
108
|
+
new ExampleInfo('Sliding Puzzle', 'slidingPuzzle.js', '15 tile sliding puzzle', false, 'objects, numbers, ui'),
|
|
109
|
+
new ExampleInfo('Space Game', 'spaceGame.js', 'Spaceship shooter with parallax', false, 'objects, weapons, stars, camera, rotation'),
|
|
110
|
+
new ExampleInfo('Raycasting 3D Game', 'raycasting.js', 'Pseudo 3D raycasting demo', false, '3D, maze, camera'),
|
|
104
111
|
new ExampleInfo('--- PLUGINS ---'),
|
|
105
|
-
new ExampleInfo('Box2d Demo', 'box2d.js', 'Box2D physics plugin'),
|
|
106
|
-
new ExampleInfo('Box2d Car', 'box2dCar.js', 'Drivable car with Box2D physics'),
|
|
107
|
-
new ExampleInfo('Post Processing', 'postProcess.js', 'Shader effects and filters'),
|
|
108
|
-
new ExampleInfo('UI System Plugin', 'uiSystem.js', 'Buttons, sliders, and checkboxes'),
|
|
109
|
-
new ExampleInfo('Nine Slice', 'nineSlice.js', 'Scalable UI panels'),
|
|
112
|
+
new ExampleInfo('Box2d Demo', 'box2d.js', 'Box2D physics plugin', false, 'objects, mouse'),
|
|
113
|
+
new ExampleInfo('Box2d Car', 'box2dCar.js', 'Drivable car with Box2D physics', false, 'objects, vehicle, suspension, wheels'),
|
|
114
|
+
new ExampleInfo('Post Processing', 'postProcess.js', 'Shader effects and filters', false, 'webgl, visual, effect'),
|
|
115
|
+
new ExampleInfo('UI System Plugin', 'uiSystem.js', 'Buttons, sliders, and checkboxes', false, 'objects, widgets, interactive'),
|
|
116
|
+
new ExampleInfo('Nine Slice', 'nineSlice.js', 'Scalable UI panels', false, 'three slice, stretch, corners, text, tiles'),
|
|
110
117
|
new ExampleInfo('--- FULL EXAMPLES ---'),
|
|
111
|
-
new ExampleInfo('Starter', 'starter', 'Clean project template', true),
|
|
112
|
-
new ExampleInfo('Breakout Tutorial', 'breakoutTutorial', 'Step-by-step breakout tutorial', true),
|
|
113
|
-
new ExampleInfo('Breakout Game', 'breakout', 'Complete breakout game', true),
|
|
114
|
-
new ExampleInfo('Platforming Game', 'platformer', '
|
|
115
|
-
new ExampleInfo('Puzzle Game', 'puzzle', 'Match
|
|
116
|
-
new ExampleInfo('Stress Test', 'stress', 'Performance and music test', true),
|
|
117
|
-
new ExampleInfo('Box2D Plugin', 'box2d', 'Full Box2D physics demo', true),
|
|
118
|
-
new ExampleInfo('HTML Menus', 'htmlMenu', 'HTML UI integration', true),
|
|
119
|
-
new ExampleInfo('UI System Plugin', 'uiSystem', 'Complete UI system demo', true),
|
|
118
|
+
new ExampleInfo('Starter', 'starter', 'Clean project template', true, 'base, empty, particles'),
|
|
119
|
+
new ExampleInfo('Breakout Tutorial', 'breakoutTutorial', 'Step-by-step breakout game tutorial', true, 'objects, physics, score'),
|
|
120
|
+
new ExampleInfo('Breakout Game', 'breakout', 'Complete breakout game', true, 'objects, physics, score'),
|
|
121
|
+
new ExampleInfo('Platforming Game', 'platformer', 'Platformer with level loading', true, 'jump, world, tiles, pixel art, sprites'),
|
|
122
|
+
new ExampleInfo('Puzzle Game', 'puzzle', 'Match 3 style puzzle game', true, 'match, swap, sprites'),
|
|
123
|
+
new ExampleInfo('Stress Test', 'stress', 'Performance and music test', true, 'optimization, tiles, sprites'),
|
|
124
|
+
new ExampleInfo('Box2D Plugin', 'box2d', 'Full Box2D physics demo', true, 'objects, bodies, joints'),
|
|
125
|
+
new ExampleInfo('HTML Menus', 'htmlMenu', 'HTML UI integration', true, 'web, browser, overlay, button, slider, textbox'),
|
|
126
|
+
new ExampleInfo('UI System Plugin', 'uiSystem', 'Complete UI system demo', true, 'menu, overlay, button, slider, checkbox'),
|
|
120
127
|
];
|
|
121
128
|
|
|
122
129
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -229,7 +236,7 @@ function setExample()
|
|
|
229
236
|
exampleInfo.innerText = example.text;
|
|
230
237
|
const filename = 'examples/' + example.filename;
|
|
231
238
|
exampleLink.href = 'https://github.com/KilledByAPixel/LittleJS/tree/main/' + filename;
|
|
232
|
-
exampleLink.innerText = 'View
|
|
239
|
+
exampleLink.innerText = 'View on GitHub: ' + example.filename;
|
|
233
240
|
|
|
234
241
|
// update URL parameter
|
|
235
242
|
const url = new URL(window.location);
|
|
@@ -313,9 +320,10 @@ function filterExamples(reset=0)
|
|
|
313
320
|
if (!example.filename)
|
|
314
321
|
continue;
|
|
315
322
|
|
|
316
|
-
// Check if search term matches name or
|
|
323
|
+
// Check if search term matches name, description, or tags
|
|
317
324
|
if (example.name.toLowerCase().includes(searchTerm) ||
|
|
318
|
-
example.description.toLowerCase().includes(searchTerm)
|
|
325
|
+
example.description.toLowerCase().includes(searchTerm) ||
|
|
326
|
+
example.tags.toLowerCase().includes(searchTerm))
|
|
319
327
|
matchingIndices.push(i);
|
|
320
328
|
}
|
|
321
329
|
|
|
@@ -345,7 +353,7 @@ function filterExamples(reset=0)
|
|
|
345
353
|
else if (matchingIndices.includes(i))
|
|
346
354
|
{
|
|
347
355
|
// add matching example
|
|
348
|
-
const o = new Option(example.
|
|
356
|
+
const o = new Option(example.selectText);
|
|
349
357
|
o.originalIndex = i;
|
|
350
358
|
selectExample.add(o);
|
|
351
359
|
}
|
|
@@ -517,13 +525,13 @@ function setCode(code, filename)
|
|
|
517
525
|
iframeContent.engineInit(iframeContent.gameInit, iframeContent.gameUpdate, iframeContent.gameUpdatePost, iframeContent.gameRender, iframeContent.gameRenderPost, ['tiles.png?'+Date.now()])
|
|
518
526
|
.catch(error =>
|
|
519
527
|
{
|
|
520
|
-
const errorLine = getErrorLine(error.stack);
|
|
528
|
+
const errorLine = error ? getErrorLine(error.stack) : -1;
|
|
521
529
|
if (errorLine >= 0)
|
|
522
530
|
setErrorLine(errorLine);
|
|
523
531
|
let message = error;
|
|
524
|
-
if (error.message)
|
|
532
|
+
if (error && error.message)
|
|
525
533
|
message = error.message;
|
|
526
|
-
if (error.stack)
|
|
534
|
+
if (error && error.stack)
|
|
527
535
|
message += '\n' + error.stack;
|
|
528
536
|
setErrorMessage(message);
|
|
529
537
|
throw error;
|
package/examples/module/game.js
CHANGED
|
@@ -69,7 +69,7 @@ function gameInit()
|
|
|
69
69
|
// create particle emitter
|
|
70
70
|
particleEmitter = new LJS.ParticleEmitter(
|
|
71
71
|
vec2(16,9), 0, // emitPos, emitAngle
|
|
72
|
-
1, 0, 500, Math.PI, // emitSize, emitTime,
|
|
72
|
+
1, 0, 500, Math.PI, // emitSize, emitTime, rate, cone
|
|
73
73
|
tile(0, 16), // tileIndex, tileSize
|
|
74
74
|
hsl(1,1,1), hsl(0,0,0), // colorStartA, colorStartB
|
|
75
75
|
hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
|
|
@@ -78,7 +78,7 @@ function gameInit()
|
|
|
78
78
|
.05, .5, true, true // fadeRate, randomness, collide, additive
|
|
79
79
|
);
|
|
80
80
|
particleEmitter.restitution = .3; // bounce when it collides
|
|
81
|
-
particleEmitter.trailScale = 2; // stretch
|
|
81
|
+
particleEmitter.trailScale = 2; // stretch as it moves
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -90,7 +90,7 @@ function gameUpdate()
|
|
|
90
90
|
sound_click.play(LJS.mousePos);
|
|
91
91
|
|
|
92
92
|
// change particle color and set to fade out
|
|
93
|
-
particleEmitter.colorStartA =
|
|
93
|
+
particleEmitter.colorStartA = LJS.randColor();
|
|
94
94
|
particleEmitter.colorStartB = LJS.randColor();
|
|
95
95
|
particleEmitter.colorEndA = particleEmitter.colorStartA.scale(1,0);
|
|
96
96
|
particleEmitter.colorEndB = particleEmitter.colorStartB.scale(1,0);
|
|
@@ -22,10 +22,9 @@ const {vec2, hsl, Timer} = LJS;
|
|
|
22
22
|
export class Character extends GameObjects.GameObject
|
|
23
23
|
{
|
|
24
24
|
constructor(pos)
|
|
25
|
-
{
|
|
25
|
+
{
|
|
26
26
|
super(pos, vec2(.6,.95));
|
|
27
27
|
|
|
28
|
-
this.weapon = new GameObjects.Weapon(pos, this);
|
|
29
28
|
this.lastPos = pos;
|
|
30
29
|
this.groundTimer = new Timer;
|
|
31
30
|
this.jumpTimer = new Timer;
|
|
@@ -41,6 +40,11 @@ export class Character extends GameObjects.GameObject
|
|
|
41
40
|
this.health = 1;
|
|
42
41
|
this.climbingLadder = false;
|
|
43
42
|
this.setCollision(true,false);
|
|
43
|
+
|
|
44
|
+
// attach weapon
|
|
45
|
+
this.weapon = new GameObjects.Weapon(pos);
|
|
46
|
+
this.weapon.renderOrder = this.renderOrder + 1;
|
|
47
|
+
this.addChild(this.weapon, vec2(this.size.x,0));
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
update()
|
|
@@ -48,13 +48,13 @@ export function makeDebris(pos, color = hsl(), amount = 50, size=.2, restitution
|
|
|
48
48
|
{
|
|
49
49
|
const color2 = color.lerp(hsl(), .5);
|
|
50
50
|
const emitter = new LJS.ParticleEmitter(
|
|
51
|
-
pos, 0, 1, .1, amount/.1, 3.14, // pos, angle,
|
|
51
|
+
pos, 0, 1, .1, amount/.1, 3.14, // pos, angle, size, time, rate, cone
|
|
52
52
|
0, // tileInfo
|
|
53
53
|
color, color2, // colorStartA, colorStartB
|
|
54
54
|
color, color2, // colorEndA, colorEndB
|
|
55
55
|
3, size,size, .1, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
|
|
56
56
|
1, .95, .4, 3.14, 0, // damp, angleDamp, gravity, particleCone, fade
|
|
57
|
-
.5, 1 // randomness, collide
|
|
57
|
+
.5, 1 // randomness, collide
|
|
58
58
|
);
|
|
59
59
|
emitter.restitution = restitution;
|
|
60
60
|
emitter.particleDestroyCallback = persistentParticleDestroyCallback;
|
|
@@ -109,7 +109,7 @@ export function explosion(pos, radius=3)
|
|
|
109
109
|
// smoke
|
|
110
110
|
new LJS.ParticleEmitter(
|
|
111
111
|
pos, 0, // pos, angle
|
|
112
|
-
radius/2, .2, 50*radius, 3.14,// emitSize, emitTime,
|
|
112
|
+
radius/2, .2, 50*radius, 3.14,// emitSize, emitTime, rate, cone
|
|
113
113
|
0, // tileInfo
|
|
114
114
|
hsl(0,0,0), hsl(0,0,0), // colorStartA, colorStartB
|
|
115
115
|
hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
|
|
@@ -121,7 +121,7 @@ export function explosion(pos, radius=3)
|
|
|
121
121
|
// fire
|
|
122
122
|
new LJS.ParticleEmitter(
|
|
123
123
|
pos, 0, // pos, angle
|
|
124
|
-
radius/2, .1, 100*radius, 3.14, // emitSize, emitTime,
|
|
124
|
+
radius/2, .1, 100*radius, 3.14, // emitSize, emitTime, rate, cone
|
|
125
125
|
0, // tileInfo
|
|
126
126
|
rgb(1,.5,.1), rgb(1,.1,.1), // colorStartA, colorStartB
|
|
127
127
|
rgb(1,.5,.1,0), rgb(1,.1,.1,0), // colorEndA, colorEndB
|