littlejsengine 1.13.4 → 1.14.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.
- package/README.md +4 -3
- package/dist/littlejs.d.ts +395 -249
- package/dist/littlejs.esm.js +1550 -754
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +1528 -744
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +1504 -720
- package/examples/box2d/game.js +4 -4
- package/examples/box2d/gameObjects.js +1 -1
- package/examples/breakout/game.js +30 -25
- package/examples/breakoutTutorial/README.md +1 -1
- package/examples/breakoutTutorial/game.js +1 -1
- package/examples/electron/build.js +1 -1
- package/examples/electron/index.html +2 -2
- package/examples/empty/game.js +1 -1
- package/examples/htmlMenu/index.html +7 -7
- package/examples/index.html +208 -97
- package/examples/platformer/gameEffects.js +20 -25
- 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 +12 -18
- 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 +14 -7
- package/examples/style.css +14 -4
- package/examples/typescript/build.js +1 -1
- package/examples/uiSystem/game.js +11 -11
- package/package.json +1 -1
- package/plugins/box2d.js +12 -10
- 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 +94 -56
- package/src/engine.js +28 -24
- package/src/engineAudio.js +284 -109
- package/src/engineBuild.js +11 -11
- package/src/engineDebug.js +29 -29
- package/src/engineDraw.js +285 -112
- package/src/engineExport.js +28 -16
- package/src/engineInput.js +57 -67
- package/src/engineMedals.js +25 -25
- package/src/engineObject.js +28 -25
- package/src/engineParticles.js +59 -59
- package/src/engineRelease.js +1 -1
- package/src/engineSettings.js +20 -13
- package/src/engineTileLayer.js +34 -35
- package/src/engineUtilities.js +66 -59
- package/src/engineWebGL.js +466 -66
- /package/examples/shorts/{playSound.js → sound.js} +0 -0
|
@@ -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.;
|
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
function gameRender()
|
|
2
2
|
{
|
|
3
|
-
// polygon shapes
|
|
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
|
-
}
|
|
14
|
-
|
|
15
3
|
// circles and ellipses
|
|
16
|
-
drawCircle(vec2(0,5), 1+wave(.5),
|
|
17
|
-
drawEllipse(vec2(-
|
|
18
|
-
drawEllipse(vec2(
|
|
4
|
+
drawCircle(vec2(0,5), 1+wave(.5), RED);
|
|
5
|
+
drawEllipse(vec2(-6,5), vec2(1,1), YELLOW, .5);
|
|
6
|
+
drawEllipse(vec2(6,5), vec2(1,2), CLEAR_BLACK, .3, .5, CYAN)
|
|
7
|
+
|
|
8
|
+
// polygon shapes
|
|
9
|
+
drawRectGradient(vec2(-6,0), vec2(5,4), RED, BLUE)
|
|
10
|
+
drawRegularPoly(vec2(0,0), vec2(2), 3, PURPLE, .2, WHITE, time);
|
|
11
|
+
const starPath = [vec2(0,2), vec2(2,-2), vec2(-3,.5), vec2(3,.5), vec2(-2,-2), vec2(0,2)];
|
|
12
|
+
drawLineList(starPath, .2, MAGENTA, true, vec2(6, 0));
|
|
19
13
|
|
|
20
14
|
// rects and lines
|
|
21
|
-
drawRect(vec2(0,-5), vec2(4,3),
|
|
22
|
-
drawLine(vec2(-5,-7), vec2(5,-3), 1, hsl(0,0,1
|
|
23
|
-
|
|
15
|
+
drawRect(vec2(0,-5), vec2(4,3), ORANGE, time);
|
|
16
|
+
drawLine(vec2(-5,-7), vec2(5,-3), 1, hsl(0,0,1,.5));
|
|
17
|
+
drawLineList([vec2(5,-3), vec2(-5,-3), vec2(5,-7), vec2(-5,-7)], .2, GREEN);
|
|
24
18
|
}
|
|
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, hasClicked;
|
|
25
25
|
|
|
26
26
|
///////////////////////////////////////////////////////////////////////////////
|
|
27
27
|
|
|
@@ -59,16 +59,14 @@ function gameInit()
|
|
|
59
59
|
///////////////////////////////////////////////////////////////////////////////
|
|
60
60
|
function gameUpdate()
|
|
61
61
|
{
|
|
62
|
-
if (LJS.mouseWasPressed(0) && !music.getSource())
|
|
63
|
-
music.play();
|
|
64
|
-
|
|
65
62
|
// mouse click = change color
|
|
66
63
|
if (LJS.mouseWasPressed(0) || LJS.mouseIsDown(2))
|
|
67
64
|
{
|
|
65
|
+
hasClicked = true;
|
|
68
66
|
spriteColor = LJS.randColor();
|
|
69
67
|
spriteAdditiveColor = LJS.randColor(rgb(.5,.5,.5, 0), rgb(0,0,0,0));
|
|
70
68
|
}
|
|
71
|
-
|
|
69
|
+
|
|
72
70
|
// right click = drop test object
|
|
73
71
|
if (LJS.mouseIsDown(2))
|
|
74
72
|
new TestObject(LJS.mousePos);
|
|
@@ -87,9 +85,18 @@ function gameUpdate()
|
|
|
87
85
|
additiveColor:spriteAdditiveColor.rgbaInt()
|
|
88
86
|
});
|
|
89
87
|
}
|
|
90
|
-
|
|
88
|
+
|
|
91
89
|
// mouse wheel = zoom
|
|
92
90
|
LJS.setCameraScale(LJS.clamp(LJS.cameraScale*(1-LJS.mouseWheel/10), 1, 1e3));
|
|
91
|
+
|
|
92
|
+
// mouse click = play music
|
|
93
|
+
if (hasClicked)
|
|
94
|
+
{
|
|
95
|
+
if (!musicInstance)
|
|
96
|
+
musicInstance = music.play();
|
|
97
|
+
else if (!musicInstance.isPlaying())
|
|
98
|
+
musicInstance.start();
|
|
99
|
+
}
|
|
93
100
|
}
|
|
94
101
|
|
|
95
102
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -162,5 +169,5 @@ LJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost,
|
|
|
162
169
|
|
|
163
170
|
///////////////////////////////////////////////////////////////////////////////
|
|
164
171
|
// music - Depp Loop
|
|
165
|
-
const music = new LJS.ZzFXMusic([[[.6,0,
|
|
172
|
+
const music = new LJS.ZzFXMusic([[[.6,0,77,,,1,1,.5,,,,,.1,,,.05,,.5,.4,.2],[,0,43,.01,,.2,2,,,,,,,,,,.01],[,0,170,.003,,.008,,.97,-35,53,,,,,,.1],[.8,0,270,,,.12,3,1.65,-2,,,,,4.5,,.02],[,0,86,,,.1,,.7,,,,.5,,6.7,1,.05],[,0,41,,.05,.4,2,0,,,9,.01,,,,.08,.02],[,0,2200,,,.04,3,2,,,800,.02,,4.8,,.01,.1],[.3,0,16,,,.3,3]],[[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,22,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,24,,,,,,,,,,,,,,,,,,,,,,,,22,,22,,22,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33],[3,1,24,,,,,,,,27,,,,,,,,,,,,,,,,27,,,,24,,,,24,,,,,,,,27,,,,,,,,,,,,,,,,24,,24,,24,,,,],[5,-1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[,1,21,,,,,,,,,,,,,,,,,,,,,,,,,,,,24,,,,23,,,,,,,,,,,,,,,,,,,,,,,,24,,23,,21,,,,],[6,1,,,34,34,34,,,,,,34,34,,,,,34,,,,34,34,,,,,34,,,,34,,,,34,34,34,,,,,,34,,,,,,34,34,,,34,34,,,,,,,,,34,34],[4,1,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,,,,,,,24,,,,,,24,,24,,,,24,,,,24,,,,,,,,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,23,23,35,23,23,36,23,23,35,23,23,36,23,23,35,35,23,23,35,23,23,35,23,23,36,23,23,35,23,23,36,36],[5,-1,21,,,19,,,21,,,,,,,,,,21,,,19,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,],[3,1,24,,,24,,,24,,,,,,,,,,24,,,24,,,24,,,,24.75,24.5,24.26,24.01,24.01,24.01,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[4,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,24.75,24.5,24.26,24.01,24.01,24.01,24.01,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,23,,21,23,,35,,23,,21,23,,35,,35,,23,,21,23,,35,,21,23,,35,,21,23,,,],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,36,34,,33,34,34,36,31,36,34,,31,34,32,,33,36,34,,31,34,34,36,33,36,33,,31,,,]],[[1,-1,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,21,21,33,21,21,33,21,21,33,21,21,33,21,21,33,33,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,21,,19,21,,33,,21,,19,21,,33,,33,,21,,19,21,,33,,21,,19,21,,33,,33,,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29],[2,1,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,34,34,,34,,,],[6,1,,,36,,,,,,36,,36,,,,,,,,36,,,,,,36,,36,,,,,,,,36,,,,,,,,,,,,,,,,36,,,,,,36,,36,,,,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,25,,,25,,,,,,,,25,,,,,,,,25,25,25,25]],[[1,-1,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,14,14,26,14,14,26,14,14,26,14,14,26,14,14,26,26,17,17,29,17,17,29,17,17,29,17,17,29,17,17,29,29,19,19,31,19,19,31,19,19,31,19,19,31,19,19,31,31],[4,1,24,24,,24,24,,24,24,24,24,,24,24,,24,,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,24,24,24,24,,24,24,,36,,24,24,,24,24,,24,24,24,24,,24,24,,24,24],[7,-1,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,14,,14,14,26,14,14,26,17,,17,17,29,17,17,29,17,,17,17,29,17,17,29,19,,19,19,31,19,19,31,19,,19,19,31,19,19,31],[2,1,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,36,36,,36,,,],[3,1,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25,,,,,25,,,,,,,,25,,,,,,,,25,,,,,,,,25,25,25,25],[6,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,34,,,,,,34,,34,,,,,,,,34,,,,,,34,,34,,,,,,]]],[0,1,1,2,3,4,4]]);
|
|
166
173
|
</script>
|
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; }
|
|
@@ -23,7 +23,7 @@ fs.rmSync(BUILD_FOLDER, { recursive: true, force: true });
|
|
|
23
23
|
console.log(`Compiling TypeScript...`);
|
|
24
24
|
// Compile all TypeScript files at once
|
|
25
25
|
const tsFiles = tsSourceFiles.join(' ');
|
|
26
|
-
child_process.execSync(`npx tsc ${tsFiles} --outDir
|
|
26
|
+
child_process.execSync(`npx tsc ${tsFiles} --outDir './${BUILD_FOLDER}' --target es2020 --module es2020`, {stdio: 'inherit'});
|
|
27
27
|
console.log(`TypeScript built in ${((Date.now() - startTime)/1e3).toFixed(2)} seconds!`);
|
|
28
28
|
|
|
29
29
|
console.log(`Moving js files back to root...`);
|
|
@@ -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);
|
package/package.json
CHANGED
package/plugins/box2d.js
CHANGED
|
@@ -88,14 +88,14 @@ class Box2dObject extends EngineObject
|
|
|
88
88
|
if (this.tileInfo)
|
|
89
89
|
super.render();
|
|
90
90
|
else
|
|
91
|
-
this.drawFixtures(this.color, this.lineColor, this.lineWidth
|
|
91
|
+
this.drawFixtures(this.color, this.lineColor, this.lineWidth);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/** Render debug info */
|
|
95
95
|
renderDebugInfo()
|
|
96
96
|
{
|
|
97
97
|
const isAsleep = !this.getIsAwake();
|
|
98
|
-
const isStatic = this.getBodyType()
|
|
98
|
+
const isStatic = this.getBodyType() === box2d.bodyTypeStatic;
|
|
99
99
|
const color = rgb(isAsleep?1:0, isAsleep?1:0, isStatic?1:0, .5);
|
|
100
100
|
this.drawFixtures(color);
|
|
101
101
|
}
|
|
@@ -1563,7 +1563,7 @@ class Box2dPlugin
|
|
|
1563
1563
|
queryCallback.ReportFixture = function(fixturePointer)
|
|
1564
1564
|
{
|
|
1565
1565
|
const fixture = box2d.instance.wrapPointer(fixturePointer, box2d.instance.b2Fixture);
|
|
1566
|
-
if (dynamicOnly && fixture.GetBody().GetType()
|
|
1566
|
+
if (dynamicOnly && fixture.GetBody().GetType() !== box2d.instance.b2_dynamicBody)
|
|
1567
1567
|
return true; // continue getting results
|
|
1568
1568
|
if (!fixture.TestPoint(box2d.vec2dTo(pos)))
|
|
1569
1569
|
return true; // continue getting results
|
|
@@ -1592,7 +1592,7 @@ class Box2dPlugin
|
|
|
1592
1592
|
* @param {Color} [lineColor]
|
|
1593
1593
|
* @param {number} [lineWidth]
|
|
1594
1594
|
* @param {CanvasRenderingContext2D} [context] */
|
|
1595
|
-
drawFixture(fixture, pos, angle, color=WHITE, lineColor=BLACK, lineWidth=.1, context
|
|
1595
|
+
drawFixture(fixture, pos, angle, color=WHITE, lineColor=BLACK, lineWidth=.1, context)
|
|
1596
1596
|
{
|
|
1597
1597
|
const shape = box2d.castObjectType(fixture.GetShape());
|
|
1598
1598
|
switch (shape.GetType())
|
|
@@ -1602,20 +1602,20 @@ class Box2dPlugin
|
|
|
1602
1602
|
let points = [];
|
|
1603
1603
|
for (let i=shape.GetVertexCount(); i--;)
|
|
1604
1604
|
points.push(box2d.vec2From(shape.GetVertex(i)));
|
|
1605
|
-
drawPoly(points, color, lineWidth, lineColor, pos, angle
|
|
1605
|
+
drawPoly(points, color, lineWidth, lineColor, pos, angle);
|
|
1606
1606
|
break;
|
|
1607
1607
|
}
|
|
1608
1608
|
case box2d.instance.b2Shape.e_circle:
|
|
1609
1609
|
{
|
|
1610
1610
|
const radius = shape.get_m_radius();
|
|
1611
|
-
drawCircle(pos, radius, color, lineWidth, lineColor
|
|
1611
|
+
drawCircle(pos, radius*2, color, lineWidth, lineColor);
|
|
1612
1612
|
break;
|
|
1613
1613
|
}
|
|
1614
1614
|
case box2d.instance.b2Shape.e_edge:
|
|
1615
1615
|
{
|
|
1616
1616
|
const v1 = box2d.vec2From(shape.get_m_vertex1());
|
|
1617
1617
|
const v2 = box2d.vec2From(shape.get_m_vertex2());
|
|
1618
|
-
drawLine(v1, v2, lineWidth, lineColor, pos, angle
|
|
1618
|
+
drawLine(v1, v2, lineWidth, lineColor, pos, angle);
|
|
1619
1619
|
break;
|
|
1620
1620
|
}
|
|
1621
1621
|
}
|
|
@@ -1694,7 +1694,9 @@ class Box2dPlugin
|
|
|
1694
1694
|
}
|
|
1695
1695
|
|
|
1696
1696
|
///////////////////////////////////////////////////////////////////////////////
|
|
1697
|
-
/** Box2d Init - Call with await
|
|
1697
|
+
/** Box2d Init - Call with await to init box2d
|
|
1698
|
+
* @example
|
|
1699
|
+
* await box2dInit();
|
|
1698
1700
|
* @return {Promise<Box2dPlugin>}
|
|
1699
1701
|
* @memberof Box2D */
|
|
1700
1702
|
async function box2dInit()
|
|
@@ -1757,14 +1759,14 @@ async function box2dInit()
|
|
|
1757
1759
|
{
|
|
1758
1760
|
color = getDebugColor(color);
|
|
1759
1761
|
center = box2d.vec2FromPointer(center);
|
|
1760
|
-
drawCircle(center, radius, CLEAR_WHITE, debugLineWidth, color, false, false, overlayContext);
|
|
1762
|
+
drawCircle(center, radius*2, CLEAR_WHITE, debugLineWidth, color, false, false, overlayContext);
|
|
1761
1763
|
};
|
|
1762
1764
|
debugDraw.DrawSolidCircle = function(center, radius, axis, color)
|
|
1763
1765
|
{
|
|
1764
1766
|
color = getDebugColor(color);
|
|
1765
1767
|
center = box2d.vec2FromPointer(center);
|
|
1766
1768
|
axis = box2d.vec2FromPointer(axis).scale(radius);
|
|
1767
|
-
drawCircle(center, radius, color, debugLineWidth, color, false, false, overlayContext);
|
|
1769
|
+
drawCircle(center, radius*2, color, debugLineWidth, color, false, false, overlayContext);
|
|
1768
1770
|
drawLine(vec2(), axis, debugLineWidth, color, center, 0, false, false, overlayContext);
|
|
1769
1771
|
};
|
|
1770
1772
|
debugDraw.DrawTransform = function(transform)
|