littlejsengine 1.13.4 → 1.14.2
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/README.md +2 -1
- package/copyToGithub.bat +28 -0
- package/dist/littlejs.d.ts +346 -240
- package/dist/littlejs.esm.js +1370 -723
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +1350 -709
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +1333 -692
- package/examples/box2d/game.js +1 -1
- package/examples/box2d/gameObjects.js +1 -1
- package/examples/breakout/game.js +30 -25
- package/examples/electron/index.html +2 -2
- package/examples/index.html +207 -96
- package/examples/platformer/gameEffects.js +19 -18
- package/examples/platformer/gameLevel.js +6 -1
- package/examples/shorts/base.html +1 -1
- package/examples/shorts/flappyGame.js +2 -1
- package/examples/shorts/helloWorld.js +1 -1
- package/examples/shorts/music.js +106 -0
- package/examples/shorts/parallax.js +71 -0
- package/examples/shorts/piano.js +7 -8
- package/examples/shorts/postProcess.js +25 -8
- package/examples/shorts/shapes.js +1 -9
- package/examples/shorts/song.mp3 +0 -0
- package/examples/shorts/uiSystem.js +15 -8
- package/examples/starter/index.html +2 -2
- package/examples/stress/index.html +8 -3
- package/examples/style.css +14 -4
- package/examples/uiSystem/game.js +11 -11
- package/package.json +1 -1
- package/plugins/box2d.js +10 -8
- package/plugins/drawUtilities.js +5 -5
- package/plugins/newgrounds.js +6 -6
- package/plugins/pluginExport.js +1 -1
- package/plugins/uiSystem.js +103 -79
- package/plugins/zzfxm.js +10 -10
- package/reference.md +90 -54
- package/src/engine.js +22 -22
- package/src/engineAudio.js +284 -109
- package/src/engineBuild.js +9 -9
- package/src/engineDebug.js +26 -26
- package/src/engineDraw.js +148 -97
- package/src/engineExport.js +22 -16
- package/src/engineInput.js +57 -67
- package/src/engineMedals.js +25 -25
- package/src/engineObject.js +25 -22
- package/src/engineParticles.js +59 -59
- package/src/engineRelease.js +1 -1
- package/src/engineSettings.js +20 -13
- package/src/engineTileLayer.js +34 -34
- package/src/engineUtilities.js +62 -55
- package/src/engineWebGL.js +447 -65
- /package/examples/shorts/{playSound.js → sound.js} +0 -0
|
@@ -82,7 +82,7 @@ export function explosion(pos, radius=3)
|
|
|
82
82
|
GameLevel.decorateTile(pos.add(vec2(x,y)).floor());
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
// update
|
|
85
|
+
// update WebGL texture
|
|
86
86
|
GameLevel.updateWebGL(GameLevel.foregroundTileLayer);
|
|
87
87
|
|
|
88
88
|
// kill/push objects
|
|
@@ -153,7 +153,7 @@ export function destroyTile(pos, makeSound = 1, cleanup = 1)
|
|
|
153
153
|
layer.setData(pos, new LJS.TileLayerData, true);
|
|
154
154
|
layer.setCollisionData(pos, GameLevel.tileType_empty);
|
|
155
155
|
|
|
156
|
-
// cleanup neighbors and rebuild
|
|
156
|
+
// cleanup neighbors and rebuild WebGL
|
|
157
157
|
if (cleanup)
|
|
158
158
|
{
|
|
159
159
|
for (let i=-1;i<=1;++i)
|
|
@@ -216,21 +216,20 @@ export class Sky extends LJS.EngineObject
|
|
|
216
216
|
|
|
217
217
|
export class ParallaxLayer extends LJS.CanvasLayer
|
|
218
218
|
{
|
|
219
|
-
constructor(depth)
|
|
219
|
+
constructor(pos, topColor, bottomColor, depth)
|
|
220
220
|
{
|
|
221
221
|
const renderOrder = depth - 3e3;
|
|
222
222
|
const canvasSize = vec2(512, 256);
|
|
223
|
-
super(
|
|
224
|
-
this.
|
|
223
|
+
super(pos, vec2(), 0, renderOrder, canvasSize);
|
|
224
|
+
this.centerPos = pos;
|
|
225
225
|
this.depth = depth;
|
|
226
226
|
|
|
227
227
|
// create a gradient for the mountains
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
for (let i = canvasSize.y; i--;)
|
|
228
|
+
const w = canvasSize.x, h = canvasSize.y;
|
|
229
|
+
for (let i = h; i--;)
|
|
231
230
|
{
|
|
232
231
|
// draw a 1 pixel gradient line on the left side of the canvas
|
|
233
|
-
const p = i/
|
|
232
|
+
const p = i/h;
|
|
234
233
|
this.context.fillStyle = topColor.lerp(bottomColor, p);
|
|
235
234
|
this.context.fillRect(0, i, 1, 1);
|
|
236
235
|
}
|
|
@@ -239,40 +238,42 @@ export class ParallaxLayer extends LJS.CanvasLayer
|
|
|
239
238
|
const pointiness = .2; // how pointy the mountains are
|
|
240
239
|
const levelness = .005; // how much the mountains level out
|
|
241
240
|
const slopeRange = 1; // max slope of the mountains
|
|
242
|
-
const startGroundLevel =
|
|
241
|
+
const startGroundLevel = h/2;
|
|
243
242
|
let y = startGroundLevel, groundSlope = LJS.rand(-slopeRange, slopeRange);
|
|
244
|
-
for (let x=
|
|
243
|
+
for (let x=w; x--;)
|
|
245
244
|
{
|
|
246
245
|
// pull slope towards start ground level
|
|
247
246
|
y += groundSlope -= (y-startGroundLevel)*levelness;
|
|
248
247
|
|
|
249
|
-
//
|
|
248
|
+
// randomly change slope
|
|
250
249
|
if (LJS.rand() < pointiness)
|
|
251
250
|
groundSlope = LJS.rand(-slopeRange, slopeRange);
|
|
252
251
|
|
|
253
252
|
// draw 1 pixel wide vertical slice of mountain
|
|
254
|
-
this.context.drawImage(this.canvas, 0, 0, 1,
|
|
253
|
+
this.context.drawImage(this.canvas, 0, 0, 1, h, x, y, 1, h - y);
|
|
255
254
|
}
|
|
256
255
|
|
|
257
256
|
// remove gradient sliver from left side
|
|
258
|
-
this.context.clearRect(0,0,1,
|
|
257
|
+
this.context.clearRect(0,0,1,h);
|
|
259
258
|
|
|
260
|
-
// make
|
|
259
|
+
// make WebGL texture
|
|
261
260
|
this.useWebGL(LJS.glEnable);
|
|
262
261
|
}
|
|
263
262
|
|
|
264
263
|
render()
|
|
265
264
|
{
|
|
265
|
+
const canvasSize = vec2(this.canvas.width, this.canvas.height);
|
|
266
266
|
const depth = this.depth
|
|
267
267
|
const distance = 4 + depth;
|
|
268
268
|
const parallax = vec2(150, 30).scale(depth**2+1);
|
|
269
|
-
const levelCenter =
|
|
270
|
-
const cameraDeltaFromCenter = LJS.cameraPos.subtract(levelCenter)
|
|
269
|
+
const levelCenter = this.centerPos;
|
|
270
|
+
const cameraDeltaFromCenter = LJS.cameraPos.subtract(levelCenter)
|
|
271
|
+
.divide(levelCenter.scale(-1).divide(parallax));
|
|
271
272
|
const scale = distance/LJS.cameraScale;
|
|
272
273
|
const positonOffset = vec2(0, 2-depth);
|
|
273
274
|
const cameraOffset = cameraDeltaFromCenter.scale(1/LJS.cameraScale);
|
|
274
275
|
this.pos = LJS.cameraPos.add(positonOffset).add(cameraOffset);
|
|
275
|
-
this.size =
|
|
276
|
+
this.size = canvasSize.scale(scale);
|
|
276
277
|
super.render();
|
|
277
278
|
}
|
|
278
279
|
}
|
|
@@ -39,7 +39,12 @@ export function buildLevel()
|
|
|
39
39
|
|
|
40
40
|
// create parallax layers
|
|
41
41
|
for (let i=3; i--;)
|
|
42
|
-
|
|
42
|
+
{
|
|
43
|
+
const pos = levelSize.scale(.5);
|
|
44
|
+
const topColor = levelColor.mutate(.2).lerp(sky.skyColor, .8 - i*.15);
|
|
45
|
+
const bottomColor = levelColor.subtract(LJS.CLEAR_WHITE).mutate(.2);
|
|
46
|
+
new GameEffects.ParallaxLayer(pos, topColor, bottomColor, i );
|
|
47
|
+
}
|
|
43
48
|
}
|
|
44
49
|
|
|
45
50
|
function loadLevelData()
|
|
@@ -28,6 +28,7 @@ class Player extends EngineObject
|
|
|
28
28
|
if (mouseWasPressed(0) || keyWasPressed('Space'))
|
|
29
29
|
this.velocity = vec2(0,.2);
|
|
30
30
|
this.angle = -this.velocity.y*2;
|
|
31
|
+
this.pos.y = max(-50, this.pos.y);
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
collideWithObject(object)
|
|
@@ -44,7 +45,7 @@ function gameInit()
|
|
|
44
45
|
gravity.y = -.01;
|
|
45
46
|
for (let i=100; i--;)
|
|
46
47
|
{
|
|
47
|
-
const h=
|
|
48
|
+
const h=100, y=-h/2-6+rand(9), spacing=15, gap=5;
|
|
48
49
|
new Wall(vec2(14 + i*spacing,y+h + gap), vec2(3,h));
|
|
49
50
|
new Wall(vec2(14 + i*spacing,y), vec2(3,h));
|
|
50
51
|
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// Music player variables
|
|
2
|
+
let musicSound = new SoundWave('song.mp3');
|
|
3
|
+
let musicVolume = .8;
|
|
4
|
+
let musicInstance;
|
|
5
|
+
|
|
6
|
+
// UI elements
|
|
7
|
+
let playButton, stopButton, progressBar;
|
|
8
|
+
|
|
9
|
+
function gameInit()
|
|
10
|
+
{
|
|
11
|
+
// load ui system plugin
|
|
12
|
+
new UISystemPlugin;
|
|
13
|
+
uiSystem.defaultSoundPress = new Sound([.3,0,220]);
|
|
14
|
+
uiSystem.defaultSoundClick = new Sound([.3,0,440]);
|
|
15
|
+
uiSystem.defaultCornerRadius = 20;
|
|
16
|
+
|
|
17
|
+
// setup music player UI
|
|
18
|
+
const musicPlayer = new UIObject(mainCanvasSize.scale(.5), vec2(500, 300));
|
|
19
|
+
|
|
20
|
+
// title
|
|
21
|
+
const title = new UIText(vec2(0, -100), vec2(500, 40), 'LittleJS Music Player');
|
|
22
|
+
musicPlayer.addChild(title);
|
|
23
|
+
|
|
24
|
+
// volume slider
|
|
25
|
+
const volumeSlider = new UIScrollbar(vec2(0, -40), vec2(400, 30), musicVolume, 'Music Volume');
|
|
26
|
+
musicPlayer.addChild(volumeSlider);
|
|
27
|
+
volumeSlider.onChange = () =>
|
|
28
|
+
{
|
|
29
|
+
musicVolume = volumeSlider.value;
|
|
30
|
+
if (musicInstance)
|
|
31
|
+
musicInstance.setVolume(musicVolume);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// play button
|
|
35
|
+
playButton = new UIButton(vec2(-90, 30), vec2(140, 50), 'Play');
|
|
36
|
+
musicPlayer.addChild(playButton);
|
|
37
|
+
playButton.onClick = ()=>
|
|
38
|
+
{
|
|
39
|
+
if (!musicSound.isLoaded())
|
|
40
|
+
return;
|
|
41
|
+
|
|
42
|
+
// handle play/pause toggle
|
|
43
|
+
if (!musicInstance)
|
|
44
|
+
musicInstance = musicSound.playMusic(musicVolume);
|
|
45
|
+
else if (musicInstance.isPaused())
|
|
46
|
+
musicInstance.resume();
|
|
47
|
+
else
|
|
48
|
+
musicInstance.pause();
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// stop button
|
|
52
|
+
stopButton = new UIButton(vec2(90, 30), vec2(140, 50), 'Stop');
|
|
53
|
+
musicPlayer.addChild(stopButton);
|
|
54
|
+
stopButton.onClick = ()=>
|
|
55
|
+
{
|
|
56
|
+
if (!musicInstance)
|
|
57
|
+
return;
|
|
58
|
+
|
|
59
|
+
// stop sound
|
|
60
|
+
musicInstance.stop();
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// progress bar and scrollbar for seeking
|
|
64
|
+
progressBar = new UIScrollbar(vec2(0, 100), vec2(400, 30), 0, 'Progress');
|
|
65
|
+
musicPlayer.addChild(progressBar);
|
|
66
|
+
progressBar.onChange = ()=>
|
|
67
|
+
{
|
|
68
|
+
// control music seek position
|
|
69
|
+
const wasPlaying = musicInstance && musicInstance.isPlaying();
|
|
70
|
+
if (!musicInstance)
|
|
71
|
+
musicInstance = musicSound.playMusic(musicVolume, true, true);
|
|
72
|
+
progressBar.value = min(progressBar.value, .999); // prevent looping around
|
|
73
|
+
const seekTime = progressBar.value * musicSound.getDuration();
|
|
74
|
+
musicInstance.start(seekTime);
|
|
75
|
+
if (!wasPlaying)
|
|
76
|
+
musicInstance.pause();
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function gameUpdate()
|
|
81
|
+
{
|
|
82
|
+
// disable buttons while loading or waiting for interaction
|
|
83
|
+
const isDisabled = !musicSound.isLoaded() || !audioIsRunning();
|
|
84
|
+
playButton.disabled = isDisabled
|
|
85
|
+
stopButton.disabled = isDisabled
|
|
86
|
+
progressBar.disabled = isDisabled
|
|
87
|
+
|
|
88
|
+
// update ui
|
|
89
|
+
if (!musicSound.isLoaded())
|
|
90
|
+
{
|
|
91
|
+
// update loading progress
|
|
92
|
+
const loadingPercent = musicSound.loadedPercent * 100;
|
|
93
|
+
progressBar.text = `Loading: ${(loadingPercent).toFixed(2)}%`;
|
|
94
|
+
}
|
|
95
|
+
else
|
|
96
|
+
{
|
|
97
|
+
// update ui text
|
|
98
|
+
playButton.text = !musicInstance || !musicInstance.isPlaying() ? 'Play' : 'Pause';
|
|
99
|
+
const currentTime = musicInstance ? musicInstance.getCurrentTime() : 0;
|
|
100
|
+
const duration = musicSound.getDuration();
|
|
101
|
+
if (!progressBar.mouseIsHeld)
|
|
102
|
+
progressBar.value = currentTime / duration;
|
|
103
|
+
const timeText = `${formatTime(currentTime)} / ${formatTime(duration)}`;
|
|
104
|
+
progressBar.text = audioIsRunning() ? timeText : 'Click to Enable Audio';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
function gameInit()
|
|
2
|
+
{
|
|
3
|
+
// create parallax layers
|
|
4
|
+
const levelColor = hsl(rand(), .5, .5);
|
|
5
|
+
for (let i=3; i--;)
|
|
6
|
+
{
|
|
7
|
+
const topColor = levelColor.mutate(.3);
|
|
8
|
+
const bottomColor = levelColor.subtract(CLEAR_WHITE).mutate(.3);
|
|
9
|
+
new ParallaxLayer(topColor, bottomColor, i);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class ParallaxLayer extends CanvasLayer
|
|
14
|
+
{
|
|
15
|
+
constructor(topColor, bottomColor, depth)
|
|
16
|
+
{
|
|
17
|
+
const renderOrder = depth;
|
|
18
|
+
const canvasSize = vec2(512, 256);
|
|
19
|
+
super(vec2(), vec2(), 0, renderOrder, canvasSize);
|
|
20
|
+
this.depth = depth;
|
|
21
|
+
|
|
22
|
+
// create a gradient for the mountains
|
|
23
|
+
const w = canvasSize.x, h = canvasSize.y;
|
|
24
|
+
for (let i = h; i--;)
|
|
25
|
+
{
|
|
26
|
+
// draw a 1 pixel gradient line on the left side of the canvas
|
|
27
|
+
const p = i/h;
|
|
28
|
+
this.context.fillStyle = topColor.lerp(bottomColor, p);
|
|
29
|
+
this.context.fillRect(0, i, 1, 1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// draw random mountains
|
|
33
|
+
const pointiness = .2; // how pointy the mountains are
|
|
34
|
+
const levelness = .005; // how much the mountains level out
|
|
35
|
+
const slopeRange = 1; // max slope of the mountains
|
|
36
|
+
const startGroundLevel = h/2;
|
|
37
|
+
let y = startGroundLevel, groundSlope = rand(-slopeRange, slopeRange);
|
|
38
|
+
for (let x=w; x--;)
|
|
39
|
+
{
|
|
40
|
+
// pull slope towards start ground level
|
|
41
|
+
y += groundSlope -= (y-startGroundLevel)*levelness;
|
|
42
|
+
|
|
43
|
+
// randomly change slope
|
|
44
|
+
if (rand() < pointiness)
|
|
45
|
+
groundSlope = rand(-slopeRange, slopeRange);
|
|
46
|
+
|
|
47
|
+
// draw 1 pixel wide vertical slice of mountain
|
|
48
|
+
this.context.drawImage(this.canvas, 0, 0, 1, h, x, y, 1, h - y);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// remove gradient sliver from left side
|
|
52
|
+
this.context.clearRect(0,0,1,h);
|
|
53
|
+
|
|
54
|
+
// make WebGL texture
|
|
55
|
+
this.useWebGL(glEnable);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
render()
|
|
59
|
+
{
|
|
60
|
+
const canvasSize = vec2(this.canvas.width, this.canvas.height);
|
|
61
|
+
const viewerPos = mousePos;
|
|
62
|
+
const depth = this.depth
|
|
63
|
+
const distance = 3 + depth;
|
|
64
|
+
const parallax = vec2(.2, .05).scale(depth**2+1);
|
|
65
|
+
const cameraDeltaFromCenter = viewerPos.multiply(parallax);
|
|
66
|
+
const positonOffset = vec2(0, 4-depth*3);
|
|
67
|
+
this.pos = cameraDeltaFromCenter.add(positonOffset)
|
|
68
|
+
this.size = canvasSize.scale(distance/cameraScale);
|
|
69
|
+
super.render();
|
|
70
|
+
}
|
|
71
|
+
}
|
package/examples/shorts/piano.js
CHANGED
|
@@ -13,19 +13,18 @@ class PianoKey extends EngineObject
|
|
|
13
13
|
}
|
|
14
14
|
press()
|
|
15
15
|
{
|
|
16
|
-
if (!this.
|
|
17
|
-
pianoSound.playNote(this.semitone);
|
|
18
|
-
this.isDown = true;
|
|
16
|
+
if (!this.soundInstance)
|
|
17
|
+
this.soundInstance = pianoSound.playNote(this.semitone);
|
|
19
18
|
}
|
|
20
19
|
release()
|
|
21
20
|
{
|
|
22
|
-
if (this.
|
|
23
|
-
|
|
24
|
-
this.
|
|
21
|
+
if (this.soundInstance)
|
|
22
|
+
this.soundInstance.stop(.2);
|
|
23
|
+
this.soundInstance = 0;
|
|
25
24
|
}
|
|
26
25
|
render()
|
|
27
26
|
{
|
|
28
|
-
const color = this.
|
|
27
|
+
const color = this.soundInstance ? RED : this.color;
|
|
29
28
|
drawRect(this.pos, this.drawSize, color);
|
|
30
29
|
}
|
|
31
30
|
}
|
|
@@ -42,7 +41,7 @@ function gameInit()
|
|
|
42
41
|
function gameUpdate()
|
|
43
42
|
{
|
|
44
43
|
// update state of piano keys
|
|
45
|
-
const pressedKey = keys.find(k=>k.
|
|
44
|
+
const pressedKey = keys.find(k=>k.soundInstance);
|
|
46
45
|
const newPressedKey = mouseIsDown(0) && keys.find(k=>isOverlapping(k.pos, k.size, mousePos));
|
|
47
46
|
if (newPressedKey != pressedKey)
|
|
48
47
|
{
|
|
@@ -6,7 +6,7 @@ function gameInit()
|
|
|
6
6
|
function gameRender()
|
|
7
7
|
{
|
|
8
8
|
drawRect(vec2(), vec2(99), GRAY);
|
|
9
|
-
drawTile(vec2(), vec2(12), tile(3,128));
|
|
9
|
+
drawTile(vec2(Math.sin(time)*3, 0), vec2(12), tile(3,128));
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
const tvShader = `
|
|
@@ -16,27 +16,44 @@ float hash(vec2 p)
|
|
|
16
16
|
p=fract(p*.3197);
|
|
17
17
|
return fract(1.+sin(51.*p.x+73.*p.y)*13753.3);
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
vec2 i=floor(p),f=fract(p),u=f*f*(3.-2.*f);
|
|
22
|
-
return mix(mix(hash(i),hash(i+vec2(1,0)),u.x),mix(hash(i+vec2(0,1)),hash(i+1.),u.x),u.y);
|
|
23
|
-
}
|
|
19
|
+
|
|
24
20
|
void mainImage(out vec4 c, vec2 p)
|
|
25
21
|
{
|
|
26
22
|
// setup the shader
|
|
23
|
+
vec2 uv = p;
|
|
27
24
|
p /= iResolution.xy;
|
|
28
25
|
c = texture(iChannel0, p);
|
|
29
26
|
|
|
30
27
|
// static noise
|
|
31
28
|
const float staticAlpha = .1;
|
|
32
|
-
const float staticScale = .
|
|
29
|
+
const float staticScale = .002;
|
|
33
30
|
c += staticAlpha * hash(floor(p/staticScale) + mod(iTime*500., 1e3));
|
|
34
31
|
|
|
35
32
|
// scan lines
|
|
36
33
|
const float scanlineScale = 2.;
|
|
37
|
-
const float scanlineAlpha = .
|
|
34
|
+
const float scanlineAlpha = .5;
|
|
38
35
|
c *= 1. - scanlineAlpha*cos(p.y*2.*iResolution.y/scanlineScale);
|
|
39
36
|
|
|
37
|
+
{
|
|
38
|
+
// bloom effect
|
|
39
|
+
const float blurSize = .002;
|
|
40
|
+
const float bloomIntensity = .2;
|
|
41
|
+
|
|
42
|
+
// 5-tap Gaussian blur
|
|
43
|
+
vec4 bloom = vec4(0);
|
|
44
|
+
bloom += texture(iChannel0, p + vec2(-2.*blurSize, 0)) * .12;
|
|
45
|
+
bloom += texture(iChannel0, p + vec2( -blurSize, 0)) * .24;
|
|
46
|
+
bloom += texture(iChannel0, p) * .28;
|
|
47
|
+
bloom += texture(iChannel0, p + vec2( blurSize, 0)) * .24;
|
|
48
|
+
bloom += texture(iChannel0, p + vec2( 2.*blurSize, 0)) * .12;
|
|
49
|
+
bloom += texture(iChannel0, p + vec2(0, -2.*blurSize)) * .12;
|
|
50
|
+
bloom += texture(iChannel0, p + vec2(0, -blurSize)) * .24;
|
|
51
|
+
bloom += texture(iChannel0, p) * .28;
|
|
52
|
+
bloom += texture(iChannel0, p + vec2(0, blurSize)) * .24;
|
|
53
|
+
bloom += texture(iChannel0, p + vec2(0, 2.*blurSize)) * .12;
|
|
54
|
+
c += bloom * bloomIntensity;
|
|
55
|
+
}
|
|
56
|
+
|
|
40
57
|
// black vignette around edges
|
|
41
58
|
const float vignette = 2.;
|
|
42
59
|
const float vignettePow = 6.;
|
|
@@ -2,15 +2,7 @@ function gameRender()
|
|
|
2
2
|
{
|
|
3
3
|
// polygon shapes
|
|
4
4
|
for (let j=3; j<7; ++j)
|
|
5
|
-
|
|
6
|
-
let points = [];
|
|
7
|
-
for (let i=0; i<j; ++i)
|
|
8
|
-
{
|
|
9
|
-
let angle = i * Math.PI * 2 / j;
|
|
10
|
-
points.push(vec2(j*4-18,0).add(vec2(0,1).rotate(angle)));
|
|
11
|
-
}
|
|
12
|
-
drawPoly(points, hsl(j/4+time/9,1,.5)); // draw a regular polygon
|
|
13
|
-
}
|
|
5
|
+
drawRegularPoly(vec2(j*4-18,0), vec2(1), j, hsl(j/4+time/9,1,.5), .2, WHITE, time);
|
|
14
6
|
|
|
15
7
|
// circles and ellipses
|
|
16
8
|
drawCircle(vec2(0,5), 1+wave(.5), hsl(.15,1,.5));
|
|
Binary file
|
|
@@ -11,26 +11,33 @@ function gameInit()
|
|
|
11
11
|
uiSystem.defaultCornerRadius = 8;
|
|
12
12
|
|
|
13
13
|
// setup example menu
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
uiMenu
|
|
14
|
+
uiBackground = new UIObject(mainCanvasSize.scale(.5), vec2(1e5));
|
|
15
|
+
uiBackground.color = hsl(0,0,.8);
|
|
16
|
+
const uiMenu = new UIObject(vec2(), vec2(450));
|
|
17
|
+
uiBackground.addChild(uiMenu);
|
|
17
18
|
|
|
18
19
|
// example text
|
|
19
|
-
const textTitle = new UIText(vec2(0,-
|
|
20
|
+
const textTitle = new UIText(vec2(0,-120), vec2(400, 60), 'LittleJS UI\nSystem Demo');
|
|
20
21
|
uiMenu.addChild(textTitle);
|
|
21
22
|
|
|
22
23
|
// example button
|
|
23
|
-
const button1 = new UIButton(vec2(70,
|
|
24
|
-
button1.textHeight =
|
|
24
|
+
const button1 = new UIButton(vec2(70,0), vec2(140, 80), 'Test');
|
|
25
|
+
button1.textHeight = 60;
|
|
25
26
|
uiMenu.addChild(button1);
|
|
26
27
|
button1.onClick = ()=> uiBackground.color = randColor();
|
|
27
28
|
|
|
28
29
|
// example checkbox
|
|
29
|
-
const checkbox = new UICheckbox(vec2(-70,
|
|
30
|
+
const checkbox = new UICheckbox(vec2(-70,0), vec2(50));
|
|
31
|
+
checkbox.onChange = ()=> button1.disabled = checkbox.checked;
|
|
30
32
|
uiMenu.addChild(checkbox);
|
|
31
33
|
|
|
34
|
+
// example scrollbar
|
|
35
|
+
const scrollbar = new UIScrollbar(vec2(0,90), vec2(300, 50), soundVolume, 'Volume');
|
|
36
|
+
uiMenu.addChild(scrollbar);
|
|
37
|
+
scrollbar.onChange = ()=> setSoundVolume(scrollbar.value);
|
|
38
|
+
|
|
32
39
|
// exit button
|
|
33
|
-
const button2 = new UIButton(vec2(0,
|
|
40
|
+
const button2 = new UIButton(vec2(0,170), vec2(300, 50), 'Exit Menu');
|
|
34
41
|
button2.textHeight = 40;
|
|
35
42
|
uiMenu.addChild(button2);
|
|
36
43
|
button2.onClick = ()=> uiMenu.visible = false;
|
|
@@ -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?1136></script>
|
|
11
11
|
|
|
12
12
|
<!-- LittleJS Engine Source
|
|
13
13
|
<script src=../../src/engineDebug.js></script>
|
|
@@ -31,4 +31,4 @@
|
|
|
31
31
|
-->
|
|
32
32
|
|
|
33
33
|
<!-- Add your game scripts here -->
|
|
34
|
-
<script src=game.js?
|
|
34
|
+
<script src=game.js?1136></script>
|
|
@@ -21,7 +21,7 @@ import * as LJS from '../../dist/littlejs.esm.min.js';
|
|
|
21
21
|
const {vec2, rgb} = LJS;
|
|
22
22
|
|
|
23
23
|
// keep our own list of simple sprites and track fps
|
|
24
|
-
let sprites, tileLayer, timeMS, fpsDisplay, statsDisplay, spriteColor, spriteAdditiveColor;
|
|
24
|
+
let sprites, tileLayer, timeMS, fpsDisplay, statsDisplay, spriteColor, spriteAdditiveColor, musicInstance;
|
|
25
25
|
|
|
26
26
|
///////////////////////////////////////////////////////////////////////////////
|
|
27
27
|
|
|
@@ -59,8 +59,13 @@ function gameInit()
|
|
|
59
59
|
///////////////////////////////////////////////////////////////////////////////
|
|
60
60
|
function gameUpdate()
|
|
61
61
|
{
|
|
62
|
-
if (LJS.mouseWasPressed(0)
|
|
63
|
-
|
|
62
|
+
if (LJS.mouseWasPressed(0))
|
|
63
|
+
{
|
|
64
|
+
if (!musicInstance)
|
|
65
|
+
musicInstance = music.play();
|
|
66
|
+
else if (!musicInstance.isPlaying())
|
|
67
|
+
musicInstance.start();
|
|
68
|
+
}
|
|
64
69
|
|
|
65
70
|
// mouse click = change color
|
|
66
71
|
if (LJS.mouseWasPressed(0) || LJS.mouseIsDown(2))
|
package/examples/style.css
CHANGED
|
@@ -30,22 +30,27 @@ iframe
|
|
|
30
30
|
#selectExample
|
|
31
31
|
{
|
|
32
32
|
flex-grow: 1;
|
|
33
|
+
min-height: 100px;
|
|
34
|
+
}
|
|
35
|
+
#divTextareas
|
|
36
|
+
{
|
|
37
|
+
flex-grow: 1;
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
min-height: 300px;
|
|
33
41
|
}
|
|
34
42
|
.CodeMirror,
|
|
35
43
|
#textareaCode
|
|
36
44
|
{
|
|
37
45
|
flex-grow: 1;
|
|
38
|
-
padding: 5px;
|
|
39
46
|
resize: none;
|
|
40
47
|
color: #fff;
|
|
41
48
|
background: #000;
|
|
42
|
-
font-size: 20px;
|
|
43
49
|
}
|
|
44
50
|
#textareaConsole,
|
|
45
51
|
#textareaError
|
|
46
52
|
{
|
|
47
53
|
flex-grow: .3;
|
|
48
|
-
padding: 5px;
|
|
49
54
|
resize: none;
|
|
50
55
|
display: none;
|
|
51
56
|
color:#f22;
|
|
@@ -79,9 +84,10 @@ iframe
|
|
|
79
84
|
{
|
|
80
85
|
margin: 0px;
|
|
81
86
|
text-align: center;
|
|
82
|
-
font-size:
|
|
87
|
+
font-size: 15px;
|
|
83
88
|
display: inline-block;
|
|
84
89
|
align-self: center;
|
|
90
|
+
font-style: italic;
|
|
85
91
|
}
|
|
86
92
|
select
|
|
87
93
|
{
|
|
@@ -117,6 +123,10 @@ input[type='checkbox']:disabled
|
|
|
117
123
|
{
|
|
118
124
|
background-color: #f004 !important;
|
|
119
125
|
}
|
|
126
|
+
.nowrap
|
|
127
|
+
{
|
|
128
|
+
white-space:nowrap;
|
|
129
|
+
}
|
|
120
130
|
|
|
121
131
|
/* LittleJS CodeMirror Theme */
|
|
122
132
|
.cm-s-littlejs.CodeMirror { background: #080808; color: #aef; }
|
|
@@ -54,26 +54,26 @@ function createUI()
|
|
|
54
54
|
// example tile image
|
|
55
55
|
const tileTest = new LJS.UITile(vec2(150,-130), vec2(110), tile(3,128))
|
|
56
56
|
uiMenu.addChild(tileTest);
|
|
57
|
-
|
|
58
|
-
// example checkbox
|
|
59
|
-
const checkbox = new LJS.UICheckbox(vec2(-140,-20), vec2(40));
|
|
60
|
-
uiMenu.addChild(checkbox);
|
|
61
|
-
checkbox.onChange = ()=> console.log('Checkbox clicked');
|
|
62
|
-
|
|
63
|
-
// text attached to checkbox
|
|
64
|
-
const checkboxText = new LJS.UIText(vec2(170,0), vec2(300, 40), 'Test Checkbox');
|
|
65
|
-
checkbox.addChild(checkboxText);
|
|
66
|
-
|
|
67
57
|
// example scrollbar
|
|
68
58
|
const scrollbar = new LJS.UIScrollbar(vec2(0,60), vec2(350, 50));
|
|
69
59
|
uiMenu.addChild(scrollbar);
|
|
70
|
-
scrollbar.onChange
|
|
60
|
+
scrollbar.onChange = ()=> scrollbar.text = scrollbar.value.toFixed(2)
|
|
61
|
+
scrollbar.onChange();
|
|
71
62
|
|
|
72
63
|
// example button
|
|
73
64
|
const button1 = new LJS.UIButton(vec2(0,140), vec2(350, 50), 'Test Button');
|
|
74
65
|
uiMenu.addChild(button1);
|
|
75
66
|
button1.onClick = ()=> console.log('Button 1 clicked');
|
|
76
67
|
|
|
68
|
+
// example checkbox
|
|
69
|
+
const checkbox = new LJS.UICheckbox(vec2(-140,-20), vec2(40));
|
|
70
|
+
uiMenu.addChild(checkbox);
|
|
71
|
+
checkbox.onChange = ()=> button1.disabled = checkbox.checked;
|
|
72
|
+
|
|
73
|
+
// text attached to checkbox
|
|
74
|
+
const checkboxText = new LJS.UIText(vec2(170,0), vec2(300, 40), 'Test Checkbox');
|
|
75
|
+
checkbox.addChild(checkboxText);
|
|
76
|
+
|
|
77
77
|
// exit button
|
|
78
78
|
const button2 = new LJS.UIButton(vec2(0,220), vec2(350, 50), 'Exit Menu');
|
|
79
79
|
uiMenu.addChild(button2);
|