littlejsengine 1.14.11 → 1.14.19
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 +303 -137
- package/dist/littlejs.esm.js +936 -463
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +934 -462
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +859 -417
- package/examples/box2d/game.js +3 -2
- package/examples/box2d/gameObjects.js +2 -2
- package/examples/box2d/tiles.png +0 -0
- package/examples/breakout/game.js +5 -5
- 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 +4 -4
- package/examples/electron/index.html +2 -2
- package/examples/electron/package.json +1 -8
- package/examples/index.html +67 -56
- package/examples/module/game.js +4 -4
- package/examples/platformer/gameEffects.js +5 -5
- package/examples/platformer/gameLevel.js +1 -1
- package/examples/platformer/gameObjects.js +4 -4
- 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 +11 -8
- package/examples/shorts/medals.js +4 -4
- package/examples/shorts/music.js +29 -56
- package/examples/shorts/musicPlayer.js +135 -0
- package/examples/shorts/nineSlice.js +34 -15
- package/examples/shorts/parallax.js +5 -4
- package/examples/shorts/particles.js +15 -15
- package/examples/shorts/piano.js +15 -21
- package/examples/shorts/pongGame.js +6 -4
- package/examples/shorts/raycasting.js +9 -4
- package/examples/shorts/sequencer.js +122 -0
- package/examples/shorts/shader.js +29 -0
- package/examples/shorts/shapes.js +7 -4
- package/examples/shorts/slidingPuzzle.js +4 -2
- 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 +24 -5
- 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 +4 -4
- package/examples/starter/index.html +2 -2
- package/examples/style.css +1 -0
- package/examples/typescript/game.js +4 -4
- package/examples/typescript/game.ts +4 -4
- package/examples/uiSystem/game.js +4 -3
- package/package.json +4 -2
- package/plugins/box2d.js +17 -2
- package/plugins/newgrounds.js +7 -5
- package/plugins/postProcess.js +76 -53
- package/plugins/uiSystem.js +192 -53
- package/plugins/zzfxm.js +5 -1
- package/reference.md +1 -1
- package/src/engine.js +60 -23
- package/src/engineAudio.js +44 -17
- package/src/engineDebug.js +75 -45
- package/src/engineDraw.js +94 -59
- package/src/engineExport.js +2 -1
- package/src/engineMedals.js +10 -2
- package/src/engineObject.js +14 -10
- package/src/engineParticles.js +60 -47
- package/src/engineSettings.js +7 -7
- package/src/engineTileLayer.js +73 -56
- package/src/engineUtilities.js +67 -20
- package/src/engineWebGL.js +134 -63
|
@@ -3,19 +3,38 @@ function gameRender()
|
|
|
3
3
|
const nineSliceTile = tile(16);
|
|
4
4
|
const threeSliceTile = tile(19);
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
6
|
+
{
|
|
7
|
+
// draw nine slice with thin border and color
|
|
8
|
+
const pos = vec2(-7,4);
|
|
9
|
+
const size = vec2(11+wave(.5,2), 6);
|
|
10
|
+
const color = hsl(.1,.5,.9);
|
|
11
|
+
const border = .5;
|
|
12
|
+
drawNineSlice(pos, size, nineSliceTile, color, border);
|
|
13
|
+
drawTextOverlay('Nine Slice\nThin Border', pos, 1, BLACK);
|
|
14
|
+
}
|
|
15
|
+
{
|
|
16
|
+
// draw nine slice in screen space with thick border and rotation
|
|
17
|
+
const pos = vec2(700,150);
|
|
18
|
+
const size = vec2(250);
|
|
19
|
+
const border = 32;
|
|
20
|
+
const angle = time/2;
|
|
21
|
+
drawNineSliceScreen(pos, size, nineSliceTile, border, 2, angle);
|
|
22
|
+
drawTextScreen('Nine Slice\nScreen Space', pos, 30, BLACK);
|
|
23
|
+
}
|
|
24
|
+
{
|
|
25
|
+
// draw three slice with variable border and additive color
|
|
26
|
+
const pos = vec2(-7,-4);
|
|
27
|
+
const size = vec2(9, 7);
|
|
28
|
+
const border = 2 + wave(.2)*2;
|
|
29
|
+
const additive = hsl(time/30,.5,.5);
|
|
30
|
+
drawThreeSlice(pos, size, threeSliceTile, WHITE, border, additive);
|
|
31
|
+
drawTextOverlay('Three Slice\nVariable\nBorder', pos, 1, BLACK);
|
|
32
|
+
}
|
|
33
|
+
{
|
|
34
|
+
// draw three slice in screen space with changing size
|
|
35
|
+
const pos = vec2(700,420);
|
|
36
|
+
const size = vec2(350-wave(.3,90),120+wave(.3,60));
|
|
37
|
+
drawThreeSliceScreen(pos, size, threeSliceTile);
|
|
38
|
+
drawTextScreen('Three Slice\nScreen Space', pos, 30, BLACK);
|
|
39
|
+
}
|
|
21
40
|
}
|
|
@@ -23,7 +23,7 @@ class ParallaxLayer extends CanvasLayer
|
|
|
23
23
|
const w = canvasSize.x, h = canvasSize.y;
|
|
24
24
|
for (let i = h; i--;)
|
|
25
25
|
{
|
|
26
|
-
// draw a 1 pixel gradient line on the left side
|
|
26
|
+
// draw a 1 pixel gradient line on the left side
|
|
27
27
|
const p = i/h;
|
|
28
28
|
this.context.fillStyle = topColor.lerp(bottomColor, p);
|
|
29
29
|
this.context.fillRect(0, i, 1, 1);
|
|
@@ -34,7 +34,8 @@ class ParallaxLayer extends CanvasLayer
|
|
|
34
34
|
const levelness = .005; // how much the mountains level out
|
|
35
35
|
const slopeRange = 1; // max slope of the mountains
|
|
36
36
|
const startGroundLevel = h/2;
|
|
37
|
-
let y = startGroundLevel
|
|
37
|
+
let y = startGroundLevel;
|
|
38
|
+
let groundSlope = rand(-slopeRange, slopeRange);
|
|
38
39
|
for (let x=w; x--;)
|
|
39
40
|
{
|
|
40
41
|
// pull slope towards start ground level
|
|
@@ -45,14 +46,14 @@ class ParallaxLayer extends CanvasLayer
|
|
|
45
46
|
groundSlope = rand(-slopeRange, slopeRange);
|
|
46
47
|
|
|
47
48
|
// draw 1 pixel wide vertical slice of mountain
|
|
48
|
-
this.context.drawImage(this.canvas, 0,
|
|
49
|
+
this.context.drawImage(this.canvas, 0,0,1,h,x,y,1,h-y);
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
// remove gradient sliver from left side
|
|
52
53
|
this.context.clearRect(0,0,1,h);
|
|
53
54
|
|
|
54
55
|
// make WebGL texture
|
|
55
|
-
this.useWebGL(
|
|
56
|
+
this.useWebGL();
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
render()
|
|
@@ -4,25 +4,25 @@ function gameInit()
|
|
|
4
4
|
|
|
5
5
|
// fire
|
|
6
6
|
new ParticleEmitter(
|
|
7
|
-
vec2(-5,-2), 0,
|
|
8
|
-
2, 0, 200, PI,
|
|
9
|
-
tile(0),
|
|
10
|
-
rgb(1,.5,.1), rgb(1,.1,.1),
|
|
11
|
-
rgb(1,.5,.1,0), rgb(1,.1,.1,0)
|
|
12
|
-
.7, 2, 0, .2, .05,
|
|
13
|
-
.9, 1, -1, PI, .05
|
|
14
|
-
.5, 0, 1, 0
|
|
7
|
+
vec2(-5,-2), 0, // pos, angle
|
|
8
|
+
2, 0, 200, PI, // emitSize, emitTime, rate, cone
|
|
9
|
+
tile(0), // tileInfo
|
|
10
|
+
rgb(1,.5,.1), rgb(1,.1,.1), // colorStartA, colorStartB
|
|
11
|
+
rgb(1,.5,.1,0), rgb(1,.1,.1,0),// colorEndA, colorEndB
|
|
12
|
+
.7, 2, 0, .2, .05, // time, sizeStart, sizeEnd, speed, angleSpeed
|
|
13
|
+
.9, 1, -1, PI, .05,// damp, angleDamp, gravity, particleCone, fade
|
|
14
|
+
.5, 0, 1, 0 // randomness, collide, additive, colorLinear
|
|
15
15
|
);
|
|
16
16
|
|
|
17
17
|
// smoke
|
|
18
18
|
new ParticleEmitter(
|
|
19
19
|
vec2(5,-2), 0, // pos, angle
|
|
20
|
-
3, 0, 100, PI,
|
|
21
|
-
tile(0),
|
|
22
|
-
hsl(0,0,0,.5), hsl(0,0,1,.5)
|
|
23
|
-
hsl(0,0,0,0), hsl(0,0,1,0),
|
|
24
|
-
1, 1, 5, .2, .01,
|
|
25
|
-
.85, 1, -1, PI, .3
|
|
26
|
-
.5, 0, 0, 1
|
|
20
|
+
3, 0, 100, PI, // emitSize, emitTime, rate, cone
|
|
21
|
+
tile(0), // tileInfo
|
|
22
|
+
hsl(0,0,0,.5), hsl(0,0,1,.5),// colorStartA, colorStartB
|
|
23
|
+
hsl(0,0,0,0), hsl(0,0,1,0), // colorEndA, colorEndB
|
|
24
|
+
1, 1, 5, .2, .01, // time, sizeStart, sizeEnd, speed, angleSpeed
|
|
25
|
+
.85, 1, -1, PI, .3,// damp, angleDamp, gravity, particleCone, fade
|
|
26
|
+
.5, 0, 0, 1 // randomness, collide, additive, colorLinear
|
|
27
27
|
);
|
|
28
28
|
}
|
package/examples/shorts/piano.js
CHANGED
|
@@ -2,29 +2,21 @@ const pianoSound = new Sound([,0,220,,9]);
|
|
|
2
2
|
|
|
3
3
|
class PianoKey extends UIButton
|
|
4
4
|
{
|
|
5
|
-
constructor(pos, size, semitone,
|
|
5
|
+
constructor(pos, size, semitone, color, hoverColor)
|
|
6
6
|
{
|
|
7
7
|
const keySize = 65;
|
|
8
8
|
size = size.scale(keySize);
|
|
9
9
|
pos = pos.scale(keySize).add(vec2(0,size.y/2-keySize*2));
|
|
10
10
|
pos = pos.add(mainCanvasSize.scale(.5));
|
|
11
|
-
super(pos, size, '',
|
|
12
|
-
|
|
11
|
+
super(pos, size, '', color);
|
|
12
|
+
|
|
13
13
|
this.dragActivate = true;
|
|
14
|
-
this.
|
|
14
|
+
this.semitone = semitone;
|
|
15
|
+
this.hoverColor = hoverColor;
|
|
15
16
|
this.activeColor = RED;
|
|
16
17
|
}
|
|
17
|
-
onPress()
|
|
18
|
-
{
|
|
19
|
-
if (!this.soundInstance)
|
|
20
|
-
this.soundInstance = pianoSound.playNote(this.semitone);
|
|
21
|
-
}
|
|
22
|
-
onRelease()
|
|
23
|
-
{
|
|
24
|
-
if (this.soundInstance)
|
|
25
|
-
this.soundInstance.stop(.2);
|
|
26
|
-
this.soundInstance = 0;
|
|
27
|
-
}
|
|
18
|
+
onPress() { this.sound = pianoSound.playNote(this.semitone); }
|
|
19
|
+
onRelease() { this.sound.stop(.2); }
|
|
28
20
|
}
|
|
29
21
|
|
|
30
22
|
function gameInit()
|
|
@@ -35,16 +27,18 @@ function gameInit()
|
|
|
35
27
|
// create piano keyboard
|
|
36
28
|
for (let i=15; i--;)
|
|
37
29
|
{
|
|
38
|
-
|
|
39
|
-
const
|
|
30
|
+
// white keys
|
|
31
|
+
const pos = vec2(i-7, 0);
|
|
32
|
+
const size = vec2(1, 4);
|
|
40
33
|
const semitone = [0,2,4,5,7,9,11][i%7]+(i/7|0)*12;
|
|
41
|
-
new PianoKey(pos, size, semitone,
|
|
34
|
+
new PianoKey(pos, size, semitone, WHITE, hsl(0,1,.9));
|
|
42
35
|
}
|
|
43
36
|
for (let i=10; i--;)
|
|
44
37
|
{
|
|
45
|
-
|
|
46
|
-
const
|
|
38
|
+
// black keys
|
|
39
|
+
const pos = vec2([1,2,4,5,6][i%5]+(i/5|0)*7-7.5, 0)
|
|
40
|
+
const size = vec2(1, 2);
|
|
47
41
|
const semitone = [1,3,6,8,10][i%5]+(i/5|0)*12;
|
|
48
|
-
new PianoKey(pos, size, semitone);
|
|
42
|
+
new PianoKey(pos, size, semitone, hsl(0,0,.3), hsl(0,1,.3));
|
|
49
43
|
}
|
|
50
44
|
}
|
|
@@ -18,10 +18,12 @@ function gameInit()
|
|
|
18
18
|
canvasFixedSize = vec2(1280, 720); // use a 720p fixed size canvas
|
|
19
19
|
|
|
20
20
|
// create objects
|
|
21
|
-
paddle = new PhysicsObject(vec2(0,1), vec2(6,1)); //
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
new PhysicsObject(vec2(
|
|
21
|
+
paddle = new PhysicsObject(vec2(0,1), vec2(6,1)); // player
|
|
22
|
+
|
|
23
|
+
const w = levelSize.x, h = levelSize.y;
|
|
24
|
+
new PhysicsObject(vec2(-.5,h/2), vec2(1,100)); // left wall
|
|
25
|
+
new PhysicsObject(vec2(w+.5,h/2), vec2(1,100)); // right wall
|
|
26
|
+
new PhysicsObject(vec2(w/2,h+.5), vec2(100,1)); // top wall
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
function gameUpdate()
|
|
@@ -45,7 +45,7 @@ function gameRender()
|
|
|
45
45
|
{
|
|
46
46
|
// draw horizontal slizes to create floor and ceiling
|
|
47
47
|
const h = 9;
|
|
48
|
-
let pos = vec2(), size = vec2(39, .15), color =
|
|
48
|
+
let pos = vec2(), size = vec2(39, .15), color = rgb();
|
|
49
49
|
for (let y=-h; y<h; y+=.1)
|
|
50
50
|
{
|
|
51
51
|
const p = 1.01-abs(y/h)
|
|
@@ -57,7 +57,7 @@ function gameRender()
|
|
|
57
57
|
{
|
|
58
58
|
// draw vertical slices to create the walls
|
|
59
59
|
const w = 20;
|
|
60
|
-
const pos = vec2(), size = vec2(.15), color =
|
|
60
|
+
const pos = vec2(), size = vec2(.15), color = rgb();
|
|
61
61
|
for (let x=-w; x<w; x+=.1)
|
|
62
62
|
{
|
|
63
63
|
const p = raycast(playerPos, playerAngle + x/w);
|
|
@@ -68,7 +68,12 @@ function gameRender()
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
// draw instructions and pointer lock status
|
|
71
|
-
const instructions = pointerLockIsActive() ?
|
|
71
|
+
const instructions = pointerLockIsActive() ?
|
|
72
|
+
'Mouse Control Active - ESC To Exit' :
|
|
73
|
+
'Click To Enable Mouse Control';
|
|
74
|
+
const textPos = vec2(mainCanvasSize.x/2, 50);
|
|
75
|
+
const textSize = 24;
|
|
76
|
+
const textColor = pointerLockIsActive() ? GREEN : WHITE;
|
|
72
77
|
if (!isTouchDevice)
|
|
73
|
-
drawTextScreen(instructions,
|
|
78
|
+
drawTextScreen(instructions, textPos, textSize, textColor);
|
|
74
79
|
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
const stepCount = 8, trackCount = 12, sequencer = [];
|
|
2
|
+
let currentStep = 0, stepTime = 0, tempo = 240;
|
|
3
|
+
let isPlaying = false, eraseMode = false;
|
|
4
|
+
|
|
5
|
+
// sound sequencer instruments
|
|
6
|
+
const sound_piano = new Sound([.3,0,220,,.1]);
|
|
7
|
+
const sound_drumKick = new Sound([,,99,,,.02,,,,,,,,2]);
|
|
8
|
+
const sound_drumHat = new Sound([,,1e3,,,.01,4,,,,,,,,,,,,,,4e3]);
|
|
9
|
+
|
|
10
|
+
// musical note scales
|
|
11
|
+
const majorScale = [0,2,4,5,7,9,11];
|
|
12
|
+
const minorScale = [0,2,3,5,7,8,10];
|
|
13
|
+
const pentatonicScale = [0,3,5,7,10];
|
|
14
|
+
const scale = majorScale;
|
|
15
|
+
|
|
16
|
+
class UISequencerButton extends UIButton
|
|
17
|
+
{
|
|
18
|
+
constructor(step, track)
|
|
19
|
+
{
|
|
20
|
+
const size = vec2(68, 35);
|
|
21
|
+
let pos = vec2(step, trackCount-1-track);
|
|
22
|
+
pos = pos.multiply(size);
|
|
23
|
+
pos = pos.add(vec2(240, 40));
|
|
24
|
+
super(pos, size);
|
|
25
|
+
|
|
26
|
+
this.step = step;
|
|
27
|
+
this.track = track;
|
|
28
|
+
this.cornerRadius = 0;
|
|
29
|
+
this.dragActivate = true;
|
|
30
|
+
this.isOn = false;
|
|
31
|
+
|
|
32
|
+
// set instrument and color based on track
|
|
33
|
+
const pianoStart = 2;
|
|
34
|
+
this.hue = track*.15;
|
|
35
|
+
if (track >= pianoStart)
|
|
36
|
+
{
|
|
37
|
+
const octave = Math.floor((track-pianoStart) / scale.length);
|
|
38
|
+
const scaleNote = (track-pianoStart) % scale.length;
|
|
39
|
+
this.semitone = scale[scaleNote] + 12*octave;
|
|
40
|
+
this.sound = sound_piano;
|
|
41
|
+
this.hue = .6 - scaleNote/40 + octave*.2;
|
|
42
|
+
}
|
|
43
|
+
else
|
|
44
|
+
this.sound = [sound_drumKick, sound_drumHat][track];
|
|
45
|
+
}
|
|
46
|
+
onPress()
|
|
47
|
+
{
|
|
48
|
+
// set the button on/off and update sequencer table
|
|
49
|
+
if (mouseWasPressed(0))
|
|
50
|
+
eraseMode = this.isOn;
|
|
51
|
+
this.isOn = !eraseMode;
|
|
52
|
+
eraseMode || this.playSound();
|
|
53
|
+
const index = this.step + this.track*stepCount;
|
|
54
|
+
sequencer[index] = eraseMode ? 0 : this;
|
|
55
|
+
}
|
|
56
|
+
render()
|
|
57
|
+
{
|
|
58
|
+
this.activeColor = eraseMode ? RED : WHITE;
|
|
59
|
+
this.color = this.isActiveObject() ? BLACK :
|
|
60
|
+
hsl(this.hue, this.isOn ? 1 : .5, this.isOn ? .5 : .15);
|
|
61
|
+
if (isPlaying && this.step == currentStep)
|
|
62
|
+
this.color = this.color.lerp(WHITE, .5);
|
|
63
|
+
super.render();
|
|
64
|
+
}
|
|
65
|
+
playSound() { this.sound.playNote(this.semitone); }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function gameInit()
|
|
69
|
+
{
|
|
70
|
+
// initialize UI system
|
|
71
|
+
new UISystemPlugin;
|
|
72
|
+
uiSystem.defaultCornerRadius = 8;
|
|
73
|
+
canvasClearColor = hsl(0,0,.3);
|
|
74
|
+
|
|
75
|
+
// create sequencer buttons
|
|
76
|
+
for (let step=stepCount; step--;)
|
|
77
|
+
for (let track=trackCount; track--;)
|
|
78
|
+
new UISequencerButton(step, track);
|
|
79
|
+
|
|
80
|
+
// create play/stop button
|
|
81
|
+
const playButton = new UIButton(vec2(660,500), vec2(180,60), 'PLAY');
|
|
82
|
+
playButton.onClick = ()=>
|
|
83
|
+
{
|
|
84
|
+
isPlaying = !isPlaying;
|
|
85
|
+
currentStep = stepTime = 0;
|
|
86
|
+
playButton.text = isPlaying ? 'STOP' : 'PLAY';
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// create tempo slider
|
|
90
|
+
const minTempo = 120, maxTempo = 480;
|
|
91
|
+
const tempoPercent = percent(tempo, minTempo, maxTempo);
|
|
92
|
+
const tempoSlider = new UIScrollbar(vec2(380,500), vec2(340,40), tempoPercent);
|
|
93
|
+
tempoSlider.onChange = ()=>
|
|
94
|
+
{
|
|
95
|
+
tempo = lerp(minTempo, maxTempo, tempoSlider.value);
|
|
96
|
+
tempo = Math.floor(tempo/10) * 10; // round to nearest 10th
|
|
97
|
+
tempoSlider.text = `${tempo} BPM`;
|
|
98
|
+
};
|
|
99
|
+
tempoSlider.onChange();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function gameUpdate()
|
|
103
|
+
{
|
|
104
|
+
if (!isPlaying)
|
|
105
|
+
return;
|
|
106
|
+
|
|
107
|
+
// update step time based on tempo
|
|
108
|
+
const lastStepTime = stepTime;
|
|
109
|
+
const lastStep = currentStep;
|
|
110
|
+
stepTime += timeDelta*tempo/60;
|
|
111
|
+
currentStep = Math.floor(stepTime) % stepCount;
|
|
112
|
+
if (currentStep == lastStep && lastStepTime)
|
|
113
|
+
return;
|
|
114
|
+
|
|
115
|
+
// play sounds when step changes
|
|
116
|
+
for (let i=trackCount; i--;)
|
|
117
|
+
{
|
|
118
|
+
const index = currentStep + i*stepCount;
|
|
119
|
+
const noteButton = sequencer[index];
|
|
120
|
+
noteButton && noteButton.playSound();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const shader = `
|
|
2
|
+
void mainImage(out vec4 c, vec2 p)
|
|
3
|
+
{
|
|
4
|
+
// normalize coordinates
|
|
5
|
+
vec2 uv = (p - iResolution.xy * .5) / iResolution.y;
|
|
6
|
+
|
|
7
|
+
// get distance and angle from center
|
|
8
|
+
float distance = length(uv);
|
|
9
|
+
float angle = atan(uv.y, uv.x);
|
|
10
|
+
|
|
11
|
+
// color based on angle and distance
|
|
12
|
+
c.rgb = vec3(
|
|
13
|
+
.5 + .5 * sin(angle + iTime),
|
|
14
|
+
.5 + .5 * sin(angle + iTime * 2.),
|
|
15
|
+
.5 + .5 * sin(distance * 5. - iTime)
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
// apply glow in center
|
|
19
|
+
c += .1 / (distance + .1);
|
|
20
|
+
|
|
21
|
+
// apply sine wave brightness
|
|
22
|
+
c *= .5 + .5 * sin(distance * 20. - iTime * 3.);
|
|
23
|
+
}
|
|
24
|
+
`;
|
|
25
|
+
|
|
26
|
+
function gameInit()
|
|
27
|
+
{
|
|
28
|
+
new PostProcessPlugin(shader);
|
|
29
|
+
}
|
|
@@ -7,12 +7,15 @@ function gameRender()
|
|
|
7
7
|
|
|
8
8
|
// polygon shapes
|
|
9
9
|
drawRectGradient(vec2(-6,0), vec2(5,4), RED, BLUE)
|
|
10
|
-
drawRegularPoly(vec2(0,0), vec2(4), 3, PURPLE, .
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
drawRegularPoly(vec2(0,0), vec2(4), 3, PURPLE, .3, WHITE, time);
|
|
11
|
+
let starPath = []
|
|
12
|
+
for (let i=10; i--;)
|
|
13
|
+
starPath.push(vec2(0,2*(i%2?.4:1)).rotate(i/10*PI*2));
|
|
14
|
+
drawPoly(starPath, BLUE, .1, GREEN, vec2(6, 0));
|
|
13
15
|
|
|
14
16
|
// rects and lines
|
|
15
17
|
drawRect(vec2(0,-5), vec2(4,3), ORANGE, time);
|
|
16
18
|
drawLine(vec2(-5,-7), vec2(5,-3), 1, hsl(0,0,1,.5));
|
|
17
|
-
|
|
19
|
+
const zPath = [vec2(5,-3), vec2(-5,-3), vec2(5,-7), vec2(-5,-7)];
|
|
20
|
+
drawLineList(zPath, .4, MAGENTA);
|
|
18
21
|
}
|
|
@@ -19,7 +19,8 @@ class PuzzlePiece extends EngineObject
|
|
|
19
19
|
{
|
|
20
20
|
const deltaX = emptyGridPos.x - this.gridPos.x;
|
|
21
21
|
const deltaY = emptyGridPos.y - this.gridPos.y;
|
|
22
|
-
if (mouseWasPressed(0)
|
|
22
|
+
if (mouseWasPressed(0))
|
|
23
|
+
if (isOverlapping(this.pos, this.size, mousePos))
|
|
23
24
|
if (abs(deltaX) + abs(deltaY) === 1)
|
|
24
25
|
{
|
|
25
26
|
// swap with empty space when clicked on
|
|
@@ -32,7 +33,8 @@ class PuzzlePiece extends EngineObject
|
|
|
32
33
|
|
|
33
34
|
render()
|
|
34
35
|
{
|
|
35
|
-
const
|
|
36
|
+
const movePercent = this.moveTimer.getPercent();
|
|
37
|
+
const pos = this.lastPos.lerp(this.pos, movePercent);
|
|
36
38
|
drawRect(pos, this.size, this.color);
|
|
37
39
|
drawTextOverlay(this.text, pos, 2.5, BLACK);
|
|
38
40
|
}
|
package/examples/shorts/sound.js
CHANGED
|
@@ -14,13 +14,22 @@ function gameInit()
|
|
|
14
14
|
button.textHeight = 100;
|
|
15
15
|
button.onClick = ()=> sound.play();
|
|
16
16
|
}
|
|
17
|
-
makeSoundButton(vec2(-1, 1),'💰',
|
|
18
|
-
|
|
19
|
-
makeSoundButton(vec2(
|
|
20
|
-
|
|
21
|
-
makeSoundButton(vec2(
|
|
22
|
-
|
|
23
|
-
makeSoundButton(vec2(-1
|
|
24
|
-
|
|
25
|
-
makeSoundButton(vec2(
|
|
17
|
+
makeSoundButton(vec2(-1, 1),'💰',
|
|
18
|
+
new Sound([,,1675,,.06,.24,1,1.82,,,837,.06]));
|
|
19
|
+
makeSoundButton(vec2( 0, 1),'🥊',
|
|
20
|
+
new Sound([,,925,.04,.3,.6,1,.3,,6.27,-184,.09,.17]));
|
|
21
|
+
makeSoundButton(vec2( 1, 1),'✨',
|
|
22
|
+
new Sound([,,539,0,.04,.29,1,1.92,,,567,.02,.02,,,,.04]));
|
|
23
|
+
makeSoundButton(vec2(-1, 0),'🐁',
|
|
24
|
+
new Sound([,.2,1e3,.02,,.01,2,,18,,475,.01,.01]));
|
|
25
|
+
makeSoundButton(vec2( 0, 0),'🎹',
|
|
26
|
+
new Sound([1.5,.5,270,,.1,,1,1.5,,,,,,,,.1,.01]));
|
|
27
|
+
makeSoundButton(vec2( 1, 0),'🏌️',
|
|
28
|
+
new Sound([,,150,.05,,.05,,1.3,,,,,,3]));
|
|
29
|
+
makeSoundButton(vec2(-1,-1),'🌊',
|
|
30
|
+
new Sound([,.2,40,.5,,1.5,,11,,,,,,199]));
|
|
31
|
+
makeSoundButton(vec2( 0,-1),'🛰️',
|
|
32
|
+
new Sound([,.5,847,.02,.3,.9,1,1.67,,,-294,.04,.13,,,,.1]));
|
|
33
|
+
makeSoundButton(vec2( 1,-1),'⚡',
|
|
34
|
+
new Sound([,,471,,.09,.47,4,1.06,-6.7,,,,,.9,61,.1,,.82,.1]));
|
|
26
35
|
}
|
|
@@ -15,13 +15,16 @@ class Player extends EngineObject
|
|
|
15
15
|
// space ship controls
|
|
16
16
|
const moveInput = keyDirection();
|
|
17
17
|
this.applyAngularAcceleration(moveInput.x * .005);
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const accel = vec2().setAngle(this.angle, moveInput.y*.02);
|
|
19
|
+
this.applyAcceleration(accel);
|
|
20
|
+
if (!this.shootTimer.active())
|
|
21
|
+
if (keyIsDown('Space') || mouseIsDown(0))
|
|
20
22
|
{
|
|
21
23
|
// shoot bullet
|
|
22
24
|
const pos = this.pos.add(vec2(0,1).rotate(cameraAngle));
|
|
23
|
-
const bullet = new EngineObject(pos, vec2(.2,.5), 0, this.angle
|
|
24
|
-
bullet.velocity =
|
|
25
|
+
const bullet = new EngineObject(pos, vec2(.2,.5), 0, this.angle);
|
|
26
|
+
bullet.velocity = vec2(0,.5).rotate(this.angle);
|
|
27
|
+
bullet.velocity = bullet.velocity.add(this.velocity);
|
|
25
28
|
this.shootTimer.set(.1);
|
|
26
29
|
}
|
|
27
30
|
|
|
@@ -42,14 +45,15 @@ function gameRender()
|
|
|
42
45
|
const range = 32, halfRange = range/2;
|
|
43
46
|
|
|
44
47
|
// precreate variables to avoid overhead
|
|
45
|
-
const pos = vec2(), size = vec2(), color =
|
|
48
|
+
const pos = vec2(), size = vec2(), color = rgb();
|
|
49
|
+
const x = cameraPos.x, y = cameraPos.y;
|
|
46
50
|
for (let i=1e3; i--;)
|
|
47
51
|
{
|
|
48
52
|
// use math to generate random star positions
|
|
49
53
|
const parallax = i%.13-1;
|
|
50
|
-
pos.x = mod(i**2.1 +
|
|
51
|
-
pos.y = mod(i**3.1 +
|
|
52
|
-
size.x = size.y = i%.07
|
|
54
|
+
pos.x = mod(i**2.1 + x*parallax, range) + x - halfRange;
|
|
55
|
+
pos.y = mod(i**3.1 + y*parallax, range) + y - halfRange;
|
|
56
|
+
size.x = size.y = i%.07 + .03;
|
|
53
57
|
color.a = .1+i%.9;
|
|
54
58
|
drawRect(pos, size, color);
|
|
55
59
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
let spriteAtlas;
|
|
2
|
-
canvasClearColor = GRAY;
|
|
3
2
|
|
|
4
3
|
function gameInit()
|
|
5
4
|
{
|
|
@@ -13,18 +12,19 @@ function gameInit()
|
|
|
13
12
|
circleBig: gameTile(2, 128),
|
|
14
13
|
iconBig: gameTile(3, 128),
|
|
15
14
|
};
|
|
15
|
+
canvasClearColor = GRAY;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function gameRender()
|
|
19
19
|
{
|
|
20
20
|
// draw a sprite from the atlas
|
|
21
|
-
let pos = vec2(Math.sin(time)*5,-3);// world position
|
|
22
|
-
let angle = 0; // world space angle
|
|
23
|
-
let size = vec2(9); // world size
|
|
21
|
+
let pos = vec2(Math.sin(time)*5,-3);// world position
|
|
22
|
+
let angle = 0; // world space angle
|
|
23
|
+
let size = vec2(9); // world space size
|
|
24
24
|
let mirror = 0; // should tile be mirrored?
|
|
25
|
-
let color = hsl(0,0,1); // color to multiply
|
|
26
|
-
let
|
|
27
|
-
drawTile(pos, size, spriteAtlas.iconBig, color, angle, mirror,
|
|
25
|
+
let color = hsl(0,0,1); // color to multiply by
|
|
26
|
+
let additive = hsl(0,0,0,0); // color to add to
|
|
27
|
+
drawTile(pos, size, spriteAtlas.iconBig, color, angle, mirror, additive);
|
|
28
28
|
|
|
29
29
|
// draw more sprites from the atlas
|
|
30
30
|
drawTile(vec2(-7,4), vec2(5), spriteAtlas.crate);
|
|
@@ -2,7 +2,7 @@ function gameRender()
|
|
|
2
2
|
{
|
|
3
3
|
// draw text with built in font image system font
|
|
4
4
|
const font = new FontImage;
|
|
5
|
-
font.drawText('System Font Test', cameraPos.add(vec2(0,3)), .2
|
|
5
|
+
font.drawText('System Font Test', cameraPos.add(vec2(0,3)), .2);
|
|
6
6
|
|
|
7
7
|
// show every character in the system font
|
|
8
8
|
let s = '';
|
|
@@ -12,5 +12,5 @@ function gameRender()
|
|
|
12
12
|
s += '\n';
|
|
13
13
|
s += String.fromCharCode(i);
|
|
14
14
|
}
|
|
15
|
-
font.drawText(s, cameraPos, .1
|
|
15
|
+
font.drawText(s, cameraPos, .1);
|
|
16
16
|
}
|
|
@@ -4,8 +4,8 @@ function gameRender()
|
|
|
4
4
|
let pos = vec2(0,0); // world position to draw
|
|
5
5
|
let size = vec2(15); // world size of the tile
|
|
6
6
|
let color = hsl(0,0,1); // color to multiply the tile by
|
|
7
|
-
let tilePos = vec2(0,0); // top left corner
|
|
8
|
-
let tileSize = vec2(256); // size
|
|
7
|
+
let tilePos = vec2(0,0); // top left corner in pixels
|
|
8
|
+
let tileSize = vec2(256); // source size in pixels
|
|
9
9
|
let tileInfo = new TileInfo(tilePos, tileSize); // tile info
|
|
10
10
|
drawRect(pos, size, GRAY); // draw background
|
|
11
11
|
drawTile(pos, size, tileInfo, color);
|
|
@@ -30,19 +30,19 @@ function gameUpdate()
|
|
|
30
30
|
{
|
|
31
31
|
if (mouseWasPressed(0))
|
|
32
32
|
{
|
|
33
|
-
// create particle emitter
|
|
33
|
+
// create particle emitter to test the collision
|
|
34
34
|
const hue = rand();
|
|
35
35
|
const particleEmitter = new ParticleEmitter(
|
|
36
|
-
mousePos, 0,
|
|
37
|
-
0, 0.1, 500, PI,
|
|
38
|
-
tile(0, 16),
|
|
39
|
-
hsl(hue,1,.5), hsl(hue,1,1),
|
|
40
|
-
hsl(hue,1,.5,0), hsl(hue,1,1,0),
|
|
41
|
-
2, .2, .2, .2, .05,
|
|
42
|
-
.99, 1, 1, PI,
|
|
43
|
-
.05, .8, true
|
|
36
|
+
mousePos, 0,
|
|
37
|
+
0, 0.1, 500, PI,
|
|
38
|
+
tile(0, 16),
|
|
39
|
+
hsl(hue,1,.5), hsl(hue,1,1),
|
|
40
|
+
hsl(hue,1,.5,0), hsl(hue,1,1,0),
|
|
41
|
+
2, .2, .2, .2, .05,
|
|
42
|
+
.99, 1, 1, PI,
|
|
43
|
+
.05, .8, true
|
|
44
44
|
);
|
|
45
45
|
particleEmitter.restitution = .5; // bounce when it collides
|
|
46
|
-
particleEmitter.trailScale = 2;
|
|
46
|
+
particleEmitter.trailScale = 2; // stretch as it moves
|
|
47
47
|
}
|
|
48
48
|
}
|