littlejsengine 1.9.11 → 1.10.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 +9 -13
- package/dist/littlejs.d.ts +129 -10
- package/dist/littlejs.esm.js +220 -75
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +188 -73
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +187 -72
- package/examples/box2d/game.js +4 -1
- package/examples/box2d/index.html +7 -6
- package/examples/breakout/game.js +1 -1
- package/examples/breakout/index.html +5 -4
- package/examples/breakoutTutorial/README.md +9 -7
- package/examples/breakoutTutorial/game.js +6 -6
- package/examples/breakoutTutorial/index.html +4 -3
- package/examples/electron/game.js +1 -1
- package/examples/electron/index.html +4 -3
- package/examples/empty/game.js +1 -1
- package/examples/empty/index.html +2 -1
- package/examples/htmlMenu/game.js +67 -0
- package/examples/htmlMenu/index.html +56 -0
- package/examples/htmlMenu/tiles.png +0 -0
- package/examples/index.html +33 -0
- package/examples/js13k/build/index.html +1 -0
- package/examples/js13k/build/index.js +1 -0
- package/examples/js13k/build/tiles.png +0 -0
- package/examples/js13k/game - Copy.zip +0 -0
- package/examples/js13k/game.js +1 -1
- package/examples/js13k/game.zip +0 -0
- package/examples/js13k/index.html +17 -14
- package/examples/module/game.js +1 -1
- package/examples/module/index.html +3 -2
- package/examples/particles/index.html +4 -3
- package/examples/platformer/game.js +7 -5
- package/examples/platformer/gameCharacter.js +12 -11
- package/examples/platformer/gameEffects.js +3 -4
- package/examples/platformer/gameLevel.js +18 -34
- package/examples/platformer/gameObjects.js +9 -15
- package/examples/platformer/index.html +10 -9
- package/examples/puzzle/game.js +1 -1
- package/examples/puzzle/index.html +4 -3
- package/examples/starter/build/index.html +2 -0
- package/examples/starter/build/index.js +1 -0
- package/examples/starter/build/tiles.png +0 -0
- package/examples/starter/game.js +4 -4
- package/examples/starter/game.zip +0 -0
- package/examples/starter/index.html +15 -14
- package/examples/stress/index.html +3 -2
- package/examples/typescript/build/build/littlejs.esm.js +4327 -0
- package/examples/typescript/build/dist/littlejs.esm.js +4425 -0
- package/examples/typescript/build/examples/typescript/build.js +24 -0
- package/examples/typescript/build/examples/typescript/game.js +100 -0
- package/examples/typescript/build/examples/typescript/test/build/littlejs.esm.js +3934 -0
- package/examples/typescript/build/examples/typescript/test/examples/typescript/build.js +86 -0
- package/examples/typescript/build/examples/typescript/test/examples/typescript/game.js +92 -0
- package/examples/typescript/game.js +1 -1
- package/examples/typescript/game.ts +1 -1
- package/examples/typescript/index.html +3 -2
- package/examples/uiSystem/game.js +134 -0
- package/examples/uiSystem/index.html +25 -0
- package/examples/uiSystem/tiles.png +0 -0
- package/jsconfig.json +11 -0
- package/package.json +1 -1
- package/plugins/box2d.js +2 -1
- package/plugins/postProcess.js +14 -8
- package/plugins/uiSystem.js +243 -0
- package/src/engine.js +42 -22
- package/src/engineAudio.js +10 -13
- package/src/engineDebug.js +1 -1
- package/src/engineDraw.js +102 -27
- package/src/engineExport.js +32 -2
- package/src/engineInput.js +1 -3
- package/src/engineObject.js +1 -0
- package/src/engineSettings.js +1 -1
- package/src/engineTileLayer.js +2 -1
- package/src/engineUtilities.js +2 -1
- package/src/engineWebGL.js +26 -4
|
@@ -54,7 +54,7 @@ class Ball extends EngineObject
|
|
|
54
54
|
{
|
|
55
55
|
// prevent colliding with paddle if moving upwards
|
|
56
56
|
if (o == paddle && this.velocity.y > 0)
|
|
57
|
-
return
|
|
57
|
+
return false;
|
|
58
58
|
|
|
59
59
|
// speed up
|
|
60
60
|
const speed = min(1.04*this.velocity.length(), .5);
|
|
@@ -73,10 +73,10 @@ class Ball extends EngineObject
|
|
|
73
73
|
this.velocity.y = max(-this.velocity.y, .2);
|
|
74
74
|
|
|
75
75
|
// prevent default collision code
|
|
76
|
-
return
|
|
76
|
+
return false;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
return
|
|
79
|
+
return true; // allow object to collide
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -114,15 +114,15 @@ class Brick extends EngineObject
|
|
|
114
114
|
new ParticleEmitter(
|
|
115
115
|
this.pos, 0, // pos, angle
|
|
116
116
|
this.size, .1, 200, PI, // emitSize, emitTime, emitRate, emiteCone
|
|
117
|
-
|
|
117
|
+
undefined, // tileInfo
|
|
118
118
|
color, color, // colorStartA, colorStartB
|
|
119
119
|
color.scale(1,0), color.scale(1,0), // colorEndA, colorEndB
|
|
120
120
|
.2, .5, 1, .1, .1, // time, sizeStart, sizeEnd, speed, angleSpeed
|
|
121
121
|
.99, .95, .4, PI, // damp, angleDamp, gravity, cone
|
|
122
|
-
.1, .5,
|
|
122
|
+
.1, .5, false, true // fade, randomness, collide, additive
|
|
123
123
|
);
|
|
124
124
|
|
|
125
|
-
return
|
|
125
|
+
return true; // allow object to collide
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<!DOCTYPE html><head>
|
|
2
|
-
<title>
|
|
2
|
+
<title>LittleJS Breakout Tutorial</title>
|
|
3
|
+
<meta charset=utf-8>
|
|
3
4
|
<meta name=apple-mobile-web-app-capable content=yes>
|
|
4
5
|
<meta name=mobile-web-app-capable content=yes>
|
|
5
6
|
<link rel=icon type=image/png href=../favicon.png>
|
|
6
7
|
</head><body>
|
|
7
8
|
|
|
8
|
-
<script src=../../dist/littlejs.js?
|
|
9
|
-
<script src=game.js?
|
|
9
|
+
<script src=../../dist/littlejs.js?1100></script>
|
|
10
|
+
<script src=game.js?1100></script>
|
|
@@ -125,4 +125,4 @@ function gameRenderPost()
|
|
|
125
125
|
|
|
126
126
|
///////////////////////////////////////////////////////////////////////////////
|
|
127
127
|
// Startup LittleJS Engine
|
|
128
|
-
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost);
|
|
128
|
+
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
<!DOCTYPE html><head>
|
|
2
|
-
<title>
|
|
2
|
+
<title>LittleJS Electron Demo</title>
|
|
3
|
+
<meta charset=utf-8>
|
|
3
4
|
<meta name=apple-mobile-web-app-capable content=yes>
|
|
4
5
|
<meta name=mobile-web-app-capable content=yes>
|
|
5
6
|
<link rel=icon type=image/png href=../favicon.png>
|
|
6
7
|
</head><body>
|
|
7
8
|
|
|
8
9
|
<!-- LittleJS Engine -->
|
|
9
|
-
<script src=../../dist/littlejs.js?
|
|
10
|
+
<script src=../../dist/littlejs.js?1100></script>
|
|
10
11
|
|
|
11
12
|
<!-- Add your game scripts here -->
|
|
12
|
-
<script src=game.js?
|
|
13
|
+
<script src=game.js?1100></script>
|
package/examples/empty/game.js
CHANGED
|
@@ -44,4 +44,4 @@ function gameRenderPost()
|
|
|
44
44
|
|
|
45
45
|
///////////////////////////////////////////////////////////////////////////////
|
|
46
46
|
// Startup LittleJS Engine
|
|
47
|
-
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost);
|
|
47
|
+
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Little JS HTML Menu Example Project
|
|
3
|
+
- Setup a simple html menu system
|
|
4
|
+
- Menu can be toggled
|
|
5
|
+
- Pauses game when menu is visible
|
|
6
|
+
- Shows several input types
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
'use strict';
|
|
10
|
+
|
|
11
|
+
// show the LittleJS splash screen
|
|
12
|
+
setShowSplashScreen(true);
|
|
13
|
+
|
|
14
|
+
// sound effects
|
|
15
|
+
const sound_click = new Sound([1,.5]);
|
|
16
|
+
|
|
17
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
18
|
+
function gameInit()
|
|
19
|
+
{
|
|
20
|
+
// show menu for demo
|
|
21
|
+
setMenuVisible(true);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
25
|
+
function gameUpdate()
|
|
26
|
+
{
|
|
27
|
+
// play sound when mouse is pressed
|
|
28
|
+
if (mouseWasPressed(0))
|
|
29
|
+
sound_click.play(mousePos);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
33
|
+
function gameUpdatePost()
|
|
34
|
+
{
|
|
35
|
+
// pause game when menu is visible
|
|
36
|
+
const menuVisible = getMenuVisible();
|
|
37
|
+
paused = menuVisible;
|
|
38
|
+
|
|
39
|
+
// toggle menu visibility
|
|
40
|
+
if (keyWasPressed('KeyM'))
|
|
41
|
+
setMenuVisible(!menuVisible);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
45
|
+
function gameRender()
|
|
46
|
+
{
|
|
47
|
+
// test game rendering
|
|
48
|
+
drawRect(vec2(), vec2(1e3), hsl(0,0,.2));
|
|
49
|
+
for(let i=0; i<1e3; ++i)
|
|
50
|
+
{
|
|
51
|
+
const pos = vec2(30*Math.sin(i+time/9),20*Math.sin(i*i+time/9));
|
|
52
|
+
drawTile(pos, vec2(2), tile(3,128), hsl(i/9,1,.4), time+i, !(i%2), hsl(i/9,1,.1,0));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
57
|
+
function gameRenderPost()
|
|
58
|
+
{
|
|
59
|
+
// draw to overlay canvas for hud rendering
|
|
60
|
+
drawTextScreen('LittleJS HTML Menu Example\nM = Toggle menu',
|
|
61
|
+
vec2(mainCanvasSize.x/2, 70), 60, // position, size
|
|
62
|
+
hsl(0,0,1), 6, hsl(0,0,0)); // color, outline size and color
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
66
|
+
// Startup LittleJS Engine
|
|
67
|
+
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<!DOCTYPE html><head>
|
|
2
|
+
<title>LittleJS HTML Menu Example</title>
|
|
3
|
+
<meta charset=utf-8>
|
|
4
|
+
<meta name=apple-mobile-web-app-capable content=yes>
|
|
5
|
+
<meta name=mobile-web-app-capable content=yes>
|
|
6
|
+
<link rel=icon type=image/png href=../favicon.png>
|
|
7
|
+
<style>
|
|
8
|
+
.topDiv
|
|
9
|
+
{
|
|
10
|
+
position: absolute;
|
|
11
|
+
z-index: 1;
|
|
12
|
+
width: 100%;
|
|
13
|
+
height: 100%;
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
}
|
|
18
|
+
.menuDiv
|
|
19
|
+
{
|
|
20
|
+
gap: 20px;
|
|
21
|
+
padding: 30px;
|
|
22
|
+
display: flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
flex-direction: column;
|
|
25
|
+
border: 3px solid black;
|
|
26
|
+
background-color: white;
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
29
|
+
|
|
30
|
+
</head><body>
|
|
31
|
+
|
|
32
|
+
<!-- setup html menu system -->
|
|
33
|
+
<div class="topDiv">
|
|
34
|
+
<div id="menu" class="menuDiv">
|
|
35
|
+
<h1><i style="font-size:30px">Test Menu</i></h1>
|
|
36
|
+
This is an example menu using html elements.
|
|
37
|
+
<input value="Test Input" onchange="alert('New text: ' + this.value)">
|
|
38
|
+
<input type="range" onchange="alert('New value: ' + this.value)">
|
|
39
|
+
<button onclick="alert('Button was clicked!')">Test Button</button>
|
|
40
|
+
<button onclick="setMenuVisible(false)">Exit Menu</button>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
<script>
|
|
44
|
+
|
|
45
|
+
// html menu system
|
|
46
|
+
const getMenuVisible =()=> menu.style.visibility != 'hidden';
|
|
47
|
+
const setMenuVisible =(visible)=> menu.style.visibility = visible ? '' : 'hidden';
|
|
48
|
+
|
|
49
|
+
// hide menu at start
|
|
50
|
+
setMenuVisible(false);
|
|
51
|
+
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<!-- Add your game scripts here -->
|
|
55
|
+
<script src=../../dist/littlejs.js?1100></script>
|
|
56
|
+
<script src=game.js?1100></script>
|
|
Binary file
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<head>
|
|
2
|
+
<title>LittleJS Examples</title>
|
|
3
|
+
<link rel=icon type=image/png href=../favicon.png>
|
|
4
|
+
<body>
|
|
5
|
+
<h1>All LittleJS Engine Examples</h1>
|
|
6
|
+
<p>
|
|
7
|
+
<img src=screenshot.jpg width=500>
|
|
8
|
+
</p>
|
|
9
|
+
<h2>Main Demos</h2>
|
|
10
|
+
<p>
|
|
11
|
+
<a href="starter">Starter</a> - Clean example with only a few things to get you started<br>
|
|
12
|
+
<a href="stress">Stress</a> - Max sprite/object test and music system demo<br>
|
|
13
|
+
<a href="platformer">Platformer</a> - Platformer/shooter with level data from Tiled Editor<br>
|
|
14
|
+
<a href="breakout">Breakout</a> - Block breaking game with post-processing effects<br>
|
|
15
|
+
<a href="breakoutTutorial">Breakout Tutorial</a> - Tutorial Breakout example<br>
|
|
16
|
+
<a href="puzzle">Puzzle</a> - Match 3 puzzle game with HD rendering and high score tracking<br>
|
|
17
|
+
<a href="particles">Particle Designer</a> - Particle system editor and visualizer<br>
|
|
18
|
+
<a href="js13k">JS13K Starter</a> - Special small size demo for JS13K Games<br>
|
|
19
|
+
<a href="empty">Empty</a> - A blank hello world project for LittleJS<br>
|
|
20
|
+
</p>
|
|
21
|
+
<h2>Plugin Demos</h2>
|
|
22
|
+
<p>
|
|
23
|
+
<a href="box2d">Box2D</a> - Box2D plugin demonstration and testbed<br>
|
|
24
|
+
<a href="uiSystem">UI System</a> - A simple hierarchical UI system using LittleJS rendering<br>
|
|
25
|
+
<a href="htmlMenu">HTML UI Menu</a> - Example using html to create an overlay menu<br>
|
|
26
|
+
</p>
|
|
27
|
+
<h2>Environment Demos</h2>
|
|
28
|
+
<p>
|
|
29
|
+
<a href="module">LittleJS using modules</a> - Loads LittleJS as a module<br>
|
|
30
|
+
<a href="typescript">LittleJS using TypeScript</a> - Uses LittleJS type definitions<br>
|
|
31
|
+
<a href="electron">LittleJS building with Electron</a> - Builds to an executable<br>
|
|
32
|
+
</p>
|
|
33
|
+
</body>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<body><script>const g=Math.PI;function n(t,i=0,e=1){return t<i?i:e<t?e:t}function aa(t,i,e){return(e-=i)?n((t-i)/e):0}function ba(t,i,e,a=q()){return 2*Math.abs(t.x-e.x)<i.x+a.x&&2*Math.abs(t.y-e.y)<i.y+a.y}function t(t=1,i=0){return i+Math.random()*(t-i)}function ca(i=1){return da(new v,t(2*g),i)}function ea(i=1){return 0<i?ca(i*t(0/i,1)**.5):new v}function ja(i=new w,e=new w(0,0,0,1),a=!1){return a?i.ma(e,t()):new w(t(i.r,e.r),t(i.j,e.j),t(i.b,e.b),t(i.a,e.a))}function q(t=0,i){return"number"==typeof t?new v(t,null==i?t:i):new v(t.x,t.y)}function da(t,i=0,e=1){return t.x=e*Math.sin(i),t.y=e*Math.cos(i),t}function ka(t){return t.x**2+t.y**2}function la(t,i){return(t.x-i.x)**2+(t.y-i.y)**2}function ma(t){var i=t.length();return 1<i?t.scale(1/i):t}function na(t){return Math.abs(t.x*t.y)}function pa(t,i){return 0<=t.x&&0<=t.y&&t.x<i.x&&t.y<i.y}class v{constructor(t=0,i=0){this.x=t,this.y=i}set(t=0,i=0){return this.x=t,this.y=i,this}v(){return new v(this.x,this.y)}add(t){return new v(this.x+t.x,this.y+t.y)}l(t){return new v(this.x-t.x,this.y-t.y)}multiply(t){return new v(this.x*t.x,this.y*t.y)}U(t){return new v(this.x/t.x,this.y/t.y)}scale(t){return new v(this.x*t,this.y*t)}length(){return ka(this)**.5}normalize(t=1){var i=this.length();return i?this.scale(t/i):new v(0,t)}angle(){return Math.atan2(this.x,this.y)}rotate(t){var i=Math.cos(t);return t=Math.sin(t),new v(this.x*i-this.y*t,this.x*t+this.y*i)}setDirection(t,i=1){return q(t%2?t-1?-i:i:0,t%2?0:t?-i:i)}direction(){return Math.abs(this.x)>Math.abs(this.y)?this.x<0?3:1:this.y<0?2:0}floor(){return new v(Math.floor(this.x),Math.floor(this.y))}ma(t,i){return this.add(t.l(this).scale(n(i)))}toString(){}}function qa(t){return(255*n(t.r)|0)+(255*n(t.j)<<8)+(255*n(t.b)<<16)+(255*n(t.a)<<24)}class w{constructor(t=1,i=1,e=1,a=1){this.r=t,this.j=i,this.b=e,this.a=a}set(t=1,i=1,e=1,a=1){return this.r=t,this.j=i,this.b=e,this.a=a,this}v(){return new w(this.r,this.j,this.b,this.a)}add(t){return new w(this.r+t.r,this.j+t.j,this.b+t.b,this.a+t.a)}l(t){return new w(this.r-t.r,this.j-t.j,this.b-t.b,this.a-t.a)}multiply(t){return new w(this.r*t.r,this.j*t.j,this.b*t.b,this.a*t.a)}U(t){return new w(this.r/t.r,this.j/t.j,this.b/t.b,this.a/t.a)}scale(t,i=t){return new w(this.r*t,this.j*t,this.b*t,this.a*i)}ma(t,i){return this.add(t.l(this).scale(n(i)))}toString(t=!0){var i=t=>((t=255*t|0)<16?"0":"")+t.toString(16);return"#"+i(this.r)+i(this.j)+i(this.b)+(t?i(this.a):"")}}class ra{constructor(){this.setTime=this.time=void 0}set(t=0){this.time=x+t,this.setTime=t}active(){return x<this.time}get(){return null!=this.time?x-this.time:0}toString(){}valueOf(){return this.get()}}function ua(t){var i,e=t.parent;e&&(i=e.o?-1:1,t.i=t.Ca.multiply(q(i,1)).rotate(-e.angle).add(e.i),t.angle=i*t.Ba+e.angle);for(const a of t.children)ua(a)}function va(t){if(!t.A){t.A=1,t.parent&&t.parent.removeChild(t);for(const i of t.children)va(i,i.parent=0)}}class wa{constructor(t=q(),i=q(1),e,a=0,s,h=0){this.i=t.v(),this.size=i,this.xa=void 0,this.s=e,this.angle=a,this.color=s,this.va=void 0,this.o=!1,this.h=xa,this.m=ya,this.K=za,this.u=Aa,this.X=Ba,this.B=1,this.P=h,this.g=q(),this.R=0,this.ua=x,this.children=[],this.ba=!0,this.parent=void 0,this.Ca=q(),this.Ba=0,this.la=this.ca=this.L=!1,y.push(this)}update(){var t;if(!this.parent&&(this.ba?(this.g.x=n(this.g.x,-z,z),this.g.y=n(this.g.y,-z,z)):(t=ka(this.g))>z*z&&(t=z/t**.5,this.g.x*=t,this.g.y*=t),t=this.i.v(),this.g.y+=Ca*this.B,this.i.x+=this.g.x*=this.m,this.i.y+=this.g.y*=this.m,this.angle+=this.R*=this.K,Da&&this.h)){var i,e,a,s,h,r,o=this.g.y<0;if(this.C&&(i=this.C.g?this.C.g.x:0,this.g.x=i+(this.g.x-i)*this.X,this.C=0),this.ca)for(var c of Ea)!this.la&&!c.la||c.A||c.parent||c==this||ba(this.i,this.size,c.i,c.size)&&(ba(t,this.size,c.i,c.size)?(i=(e=(i=t.l(c.i)).length())<.01?ca(.001):i.scale(.001/e),this.g=this.g.add(i),c.h&&(c.g=c.g.l(i))):(e=this.size.add(c.size),a=2*(t.y-c.i.y)>e.y+Ca,s=2*Math.abs(t.y-c.i.y)<e.y,h=2*Math.abs(t.x-c.i.x)<e.x,i=Math.max(this.u,c.u),!a&&!h&&s||(this.i.y=c.i.y+(e.y/2+.001)*Math.sign(t.y-c.i.y),c.C&&o||!c.h?(o&&(this.C=c),this.g.y*=-i):c.h&&(h=(this.h*this.g.y+c.h*c.g.y)/(this.h+c.h),r=c.g.y*(c.h-this.h)/(this.h+c.h)+2*this.g.y*this.h/(this.h+c.h),this.g.y=h+n(i)*(this.g.y*(this.h-c.h)/(this.h+c.h)+2*c.g.y*c.h/(this.h+c.h)-h),c.g.y=h+n(i)*(r-h))),!a&&s&&(this.i.x=c.i.x+(e.x/2+.001)*Math.sign(t.x-c.i.x),c.h?(e=(this.h*this.g.x+c.h*c.g.x)/(this.h+c.h),a=c.g.x*(c.h-this.h)/(this.h+c.h)+2*this.g.x*this.h/(this.h+c.h),this.g.x=e+n(i)*(this.g.x*(this.h-c.h)/(this.h+c.h)+2*c.g.x*c.h/(this.h+c.h)-e),c.g.x=e+n(i)*(a-e)):this.g.x*=-i)));this.L&&Fa(this.i,this.size,this)&&!Fa(t,this.size,this)&&(c=Fa(q(this.i.x,t.y),this.size,this),!Fa(q(t.x,this.i.y),this.size,this)&&c||(this.C=o,this.g.y*=-this.u,(o=(t.y-this.size.y/2|0)-(t.y-this.size.y/2))<0&&o>this.m*this.g.y+Ca*this.B&&(this.g.y=this.m?(o-Ca*this.B)/this.m:0),this.i.y=t.y),c)&&(this.i.x=t.x,this.g.x*=-this.u)}}H(){Ga(this.i,this.xa||this.size,this.s,this.color,this.angle,this.o,this.va)}removeChild(t){t.parent==this&&this.children.includes(t),this.children.splice(this.children.indexOf(t),1),t.parent=0}toString(){}}let B,C,D,Ha,E=q(),Na=[];function Oa(t=q(),i=Pa,e=0){var a;return F?new Qa:("number"==typeof i&&(i=q(i)),"number"==typeof t&&(t=q(t%(a=Na[e].size.x/i.x|0)*i.x,(t/a|0)*i.y)),new Qa(t,i,e))}class Qa{constructor(t=q(),i=Pa,e=0){this.i=t.v(),this.size=i.v(),this.$=e}offset(t){return new Qa(this.i.add(t),this.size,this.$)}frame(t){return this.offset(q(t*this.size.x,0))}}class Ra{constructor(t){var i;this.image=t,this.size=q(t.width,t.height),(i=Sa)&&(i=G.createTexture(),G.bindTexture(3553,i),t&&G.texImage2D(3553,0,6408,6408,5121,t),t=Ta?9728:9729,G.texParameteri(3553,10241,t),G.texParameteri(3553,10240,t)),this.ja=i,this.ya=q(Ua).U(this.size)}}function Va(t){return new v((t.x-I.x)*J+E.x/2-.5,(t.y-I.y)*-J+E.y/2-.5)}function Ga(t,i=q(1),h,n=new w,e=0,a,s=new w(0,0,0,0),r=Sa){const o=h&&Na[h.$];var c,u,l,b;r?o?(r=h.i.x/o.size.x,c=h.i.y/o.size.y,u=h.size.x/o.size.x,l=h.size.y/o.size.y,b=o.ya,Wa(o.ja),Xa(t.x,t.y,a?-i.x:i.x,i.y,e,r+b.x,c+b.y,r-b.x+u,c-b.y+l,qa(n),qa(s))):Xa(t.x,t.y,i.x,i.y,e,0,0,0,0,0,qa(n)):ab(t,i,e,a,t=>{var i,e,a,s;o?(i=h.i.x+Ua,e=h.i.y+Ua,a=h.size.x-2*Ua,s=h.size.y-2*Ua,t.globalAlpha=n.a,t.drawImage(o.image,i,e,a,s,-.5,-.5,1,1),t.globalAlpha=1):(t.fillStyle=n,t.fillRect(-.5,-.5,1,1))})}function ab(t,i,e,a,s){var h=C;t=Va(t),i=i.scale(J),h.save(),h.translate(t.x+.5,t.y+.5),h.rotate(e),h.scale(a?-i.x:i.x,-i.y),s(h),h.restore()}function bb(t){var i;Sa?cb=t:(i||=C).globalCompositeOperation=t?"lighter":"source-over"}function db(){var i=q(E.x/2,70),t=new w(0,0,0),e=eb,a=Ha;a.fillStyle=(new w).toString(),a.lineWidth=0,a.strokeStyle=t.toString(),a.textAlign="center",a.font="80px "+e,a.textBaseline="middle",a.lineJoin="round",i=i.v(),["LittleJS JS13K Demo"].forEach(t=>{a.fillText(t,i.x,i.y),i.y+=80})}function fb(t,i=0){return K[i]&&!!(1&K[i][t])}let gb=q(),hb=q(),ib=!1;function jb(t,i=0){return fb(t,i+1)}let K=[[]];function kb(){var t;F||(N&&lb||document.hasFocus()||(K=[[]]),t=hb,gb=new v((t.x-E.x/2+.5)/J+I.x,(t.y-E.y/2+.5)/-J+I.y),mb&&nb())}function ob(){if(!F)for(const t of K)for(const i in t)t[i]&=1}function pb(){function i(t){return qb?"KeyW"==t?"ArrowUp":"KeyS"==t?"ArrowDown":"KeyA"==t?"ArrowLeft":"KeyD"==t?"ArrowRight":t:t}F||(onkeydown=t=>{t.repeat||(ib=!1,K[0][t.code]=3,qb&&(K[0][i(t.code)]=3))},onkeyup=t=>{K[0][t.code]=4,qb&&(K[0][i(t.code)]=4)},onmousedown=t=>{ib=!1,K[0][t.button]=3,hb=rb(t),t.button&&t.preventDefault()},onmouseup=t=>K[0][t.button]=2&K[0][t.button]|4,onmousemove=t=>hb=rb(t),onwheel=t=>t.ctrlKey?0:Math.sign(t.deltaY),oncontextmenu=()=>!1,lb&&N&&!F&&sb())}function rb(t){var i;return!B||F?q():(i=B.getBoundingClientRect(),q(B.width,B.height).multiply(q(aa(t.x,i.left,i.right),aa(t.y,i.top,i.bottom))))}const tb=[];function nb(){var t=t=>{var i=t=>.3<t?aa(t,.3,.8):t<-.3?-aa(-t,.3,.8):0;return ma(q(i(t.x),i(-t.y)))};if(ub&&lb&&null!=Ab.time){(i=tb[0]||(tb[0]=[]))[0]=q(),Bb?i[0]=t(O):.3<ka(O)&&(i[0].x=Math.round(O.x),i[0].y=-Math.round(O.y),i[0]=ma(i[0]));for(var i=K[1]||(K[1]=[]),e=10;e--;){var a=3==e?2:2==e?3:e,s=jb(a,0);i[a]=Q[e]?s?1:3:s?4:0}}if(mb&&mb&&navigator&&navigator.getGamepads&&document.hasFocus())for(e=(i=navigator.getGamepads()).length;e--;){var s=i[e],h=K[e+1]||(K[e+1]=[]),a=tb[e]||(tb[e]=[]);if(s){for(var n=0;n<s.axes.length-1;n+=2)a[n>>1]=t(q(s.axes[n],s.axes[n+1]));for(n=s.buttons.length;n--;){var r=s.buttons[n],o=jb(n,e);h[n]=r.pressed?o?1:3:o?4:0,ib||=!e&&r.pressed}Cb&&ka(s=q((jb(15,e)&&1)-(jb(14,e)&&1),(jb(12,e)&&1)-(jb(13,e)&&1)))&&(a[0]=ma(s)),ub&&ib&&(Ab.time=void 0)}}}const lb=void 0!==window.ontouchstart;let Ab=new ra,Q,O;function sb(){function n(t){Db&&R&&"running"!=R.state&&new Eb([0]).play();var i=t.touches.length;return i?(hb=rb(q(t.touches[0].clientX,t.touches[0].clientY)),e?ib=!1:K[0][0]=3):e&&(K[0][0]=2&K[0][0]|4),e=i,document.hasFocus()&&t.preventDefault(),!0}let i=n;ub&&(i=function(t){if(O=q(),Q=[],ib=!0,!t.touches.length||(Ab.set(),!Fb)){var i=q(S,E.y-S),e=E.l(q(S,S)),a=E.scale(.5);for(const h of t.touches){var s=rb(q(h.clientX,h.clientY));la(s,i)**.5<S?O=ma(s.l(i).scale(2/S)):la(s,e)**.5<S?(s=s.l(e).direction(),Q[s]=1):la(s,a)**.5<S&&(Q[9]=1)}return n(t),!0}Q[9]=1},Q=[],O=q()),document.addEventListener("touchstart",t=>i(t),{passive:!1}),document.addEventListener("touchmove",t=>i(t),{passive:!1}),document.addEventListener("touchend",t=>i(t),{passive:!1}),onmousedown=onmouseup=()=>0;let e}function Gb(){if(N&&lb&&!F&&ub&&null!=Ab.time){var t=aa(Ab.get(),4,3);if(t&&!Fb){var i=Ha;if(i.save(),i.globalAlpha=t*Hb,i.strokeStyle="#fff",i.lineWidth=3,i.fillStyle=0<ka(O)?"#fff":"#000",i.beginPath(),t=q(S,E.y-S),Bb)i.arc(t.x,t.y,S/2,0,9),i.fill();else for(var e=10;e--;){var a=e*g/4;i.arc(t.x,t.y,.6*S,a+g/8,a+g/8),e%2&&i.arc(t.x,t.y,.33*S,a,a),1==e&&i.fill()}for(i.stroke(),t=q(E.x-S,E.y-S),e=4;e--;)a=t.add(q().setDirection(e,S/2)),i.fillStyle=Q[e]?"#fff":"#000",i.beginPath(),i.arc(a.x,a.y,S/4,0,9),i.fill(),i.stroke();i.restore()}}}let R,Ib;class Eb{constructor(t){var i=Jb,e=Kb;Db&&!F&&(this.Fa=i,this.Ja=e,this.O=0,t)&&(this.O=t[1]||.05,this.ta=[Lb(...t)],this.sampleRate=44100)}play(i,e=1,a=1,s=1,h=!1){if(Db&&!F&&this.ta){var n;if(i){if(n=this.Fa){var r=la(I,i);if(n*n<r)return;e*=aa(r**.5,n,n*this.Ja)}n=2*Va(i).x/B.width-1}return i=a+a*this.O*s*t(-1,1),this.za=R.createGain(),this.source=Mb(this.ta,e,i,n,h,this.sampleRate,this.za)}}stop(){this.source&&this.source.stop(),this.source=void 0}}let Nb=!1;function Mb(t,i=1,e=1,a=0,s=!1,h=44100,r){if(Db&&!F){var o,c=Nb;if(!(Nb="running"!=R.state)||(R.resume(),!c))return o=R.createBuffer(t.length,t[0].length,h),h=R.createBufferSource(),t.forEach((t,i)=>o.getChannelData(i).set(t)),h.buffer=o,h.playbackRate.value=e,h.loop=s,(r=r||R.createGain()).gain.value=i,r.connect(Ib),h.connect(new StereoPannerNode(R,{pan:n(a,-1,1)})).connect(r),h.start(),h}}function Lb(t=1,i,e=220,a=0,s=0,h=.1,r=0,o=1,c=0,u=0,l=0,b=0,f=0,d=0,y=0,x=0,v=0,m=1,w=0,p=0,q=0){let O=c*=500*(i=2*g)/44100/44100,S=e*=i/44100,z=[],G=0,k=0,M=0,B=1,U=0,J=0,D=0;var F=i*Math.abs(q)*2/44100,C=Math.cos(F),E=1+(A=Math.sin(F)/2/2),F=-2*C/E,A=(1-A)/E;let j=(1+Math.sign(q)*C)/2/E,P=-(Math.sign(q)+C)/E,T=0,K=0,I=0,R=0;for(u*=500*i/44100**3,y*=i/44100,l*=i/44100,b*=44100,f=44100*f|0,E=(a=44100*a+9)+(w*=44100)+(s*=44100)+(h*=44100)+(v*=44100)|0;M<E;z[M++]=D*t)++J%(100*x|0)||(D=r?1<r?2<r?3<r?Math.sin(G**3):n(Math.tan(G),1,-1):1-(2*G/i%2+2)%2:1-4*Math.abs(Math.round(G/i)-G/i):Math.sin(G),D=(f?1-p+p*Math.sin(i*M/f):1)*Math.sign(D)*Math.abs(D)**o*(M<a?M/a:M<a+w?1-(M-a)/w*(1-m):M<a+w+s?m:M<E-v?(E-M-v)/h*m:0),D=v?D/2+(v>M?0:(M<E-v?1:(E-M)/v)*z[M-v|0]/2/t):D,q&&(D=R=j*T+P*(T=K)+j*(K=D)-A*I-F*(I=R))),C=(e+=c+=u)*Math.cos(y*k++),G+=C+C*d*Math.sin(M**5),B&&++B>b&&(e+=l,S+=l,B=0),!f||++U%f||(e=S,c=O,B=B||1);return z}let Ob=[],T=q();function Fa(t,i=q(),e){var a=Math.max(t.x-i.x/2|0,0),s=Math.max(t.y-i.y/2|0,0),h=Math.min(t.x+i.x/2,T.x);for(t=Math.min(t.y+i.y/2,T.y);s<t;++s)for(i=a;i<h;++i){var n=Ob[s*T.x+i];if(n&&(!e||0<n))return!0}}class Pb{constructor(t,i=0,e=!1,a=new w){this.aa=t,this.direction=i,this.o=e,this.color=a}clear(){this.aa=this.direction=0,this.o=!1,this.color=new w}}class Qb extends wa{constructor(t,i=T){var e=q(1);for(super(t,i,Oa(),0,void 0,0),this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),this.scale=e,this.ka=!1,this.data=[],t=na(this.size);t--;)this.data.push(new Pb);F&&(this.qa=()=>{},this.H=()=>{},this.sa=()=>{},this.ra=()=>{},this.V=()=>{})}setData(t,i,e=!1){pa(t,this.size)&&(this.data[(0|t.y)*this.size.x+t.x|0]=i,e)&&this.V(t)}getData(t){return pa(t,this.size)&&this.data[(0|t.y)*this.size.x+t.x|0]}update(){}H(){Rb||this.ka||Sb();var t=Va(this.i.add(q(0,this.size.y*this.scale.y)));(this.ka?Ha:C).drawImage(this.canvas,t.x,t.y,J*this.size.x*this.scale.x,J*this.size.y*this.scale.y)}qa(){this.sa(!0);for(let i=this.size.x;i--;)for(let t=this.size.y;t--;)this.V(q(i,t),!1);this.ra()}sa(t=!1){this.Ga=[B,C,E,I,J],B=this.canvas,C=this.context,E=this.size.multiply(this.s.size),I=this.size.scale(.5),J=this.s.size.x,t&&(B.width=E.x,B.height=E.y),this.context.imageSmoothingEnabled=!Ta,Tb()}ra(){Sb(!0),[B,C,E,I,J]=this.Ga}V(t,i=!0){var e=this.s.size;i&&(i=t.multiply(e),this.context.clearRect(i.x,this.canvas.height-i.y,e.x,-e.y)),null!=(i=this.getData(t)).aa&&Ga(t=this.i.add(t).add(q(.5)),q(1),Oa(i.aa,e,this.s.$),i.color,i.direction*g/2,i.o)}}function Ub(i){var e="number"==typeof i.W?ea(i.W/2):q(t(-.5,.5),t(-.5,.5)).multiply(i.W).rotate(i.angle);let a=t(i.na,-i.na);i.Y||(e=i.i.add(e),a+=i.angle);const s=i.O;var h=(c=i=>i+i*t(s,-s))(i.Ea),n=c(i.Z),r=c(i.Ha),o=c(i.speed),c=c(i.wa)*(2*Math.floor(t(2,0))-1),u=t(i.ga,-i.ga),l=ja(i.S,i.T,i.pa),b=ja(i.da,i.ea,i.pa),u=i.Y?u:i.angle+u;(e=new Vb(e,i.s,a,l,b,h,n,r,i.G,i.J,i.I,i.Y&&i,i.Da)).g=da(q(),u,o),e.R=c,e.G=i.G,e.m=i.m,e.K=i.K,e.u=i.u,e.X=i.X,e.B=i.B,e.L=i.L,e.P=i.P,e.o=!!Math.floor(t(2,0)),i.oa&&i.oa(e)}class Wb extends wa{constructor(t,i,e=0,a=0,s=100,h=g,n,r=new w,o=new w,c=new w(1,1,1,0),u=new w(1,1,1,0),l=.5,b=.1,f=1,d=.1,y=.05,x=1,v=1,m=0,p=g,S=.1,z=.2,G=!1,M=!1,B=!0,D=M?1e9:0,F=!1){super(t,q(),n,i,void 0,D),this.W=e,this.ia=a,this.ha=s,this.ga=h,this.S=r,this.T=o,this.da=c,this.ea=u,this.pa=B,this.Ea=l,this.Z=b,this.Ha=f,this.speed=d,this.wa=y,this.m=x,this.K=v,this.B=m,this.na=p,this.G=S,this.O=z,this.L=G,this.J=M,this.Y=F,this.I=0,this.oa=this.Da=void 0,this.F=0}update(){if(this.parent&&super.update(),!this.ia||x-this.ua<=this.ia){if(this.ha*Xb){var t=1/this.ha/Xb;for(this.F+=Yb;0<this.F;this.F-=t)Ub(this)}}else va(this)}H(){}}class Vb extends wa{constructor(t,i,e,a,s,h,n,r,o,c,u,l,b){super(t,q(),i,e),this.N=a,this.M=s.l(a),this.Aa=h,this.Z=n,this.Ia=r-n,this.G=o,this.J=c,this.I=u,this.D=l,this.fa=b,this.ba=!1}H(){var t=Math.min((x-this.ua)/this.Aa,1),i=q(this.Z+t*this.Ia),e=this.G/2,e=new w(this.N.r+t*this.M.r,this.N.j+t*this.M.j,this.N.b+t*this.M.b,(this.N.a+t*this.M.a)*(t<e?t/e:1-e<t?(1-t)/e:1));this.J&&bb(!0);let a=this.i;var s,h,n=this.angle;this.D&&(a=this.D.i.add(a.rotate(-this.D.angle)),n+=this.D.angle),this.I?(s=this.g,(n=(s=this.D?s.rotate(-this.D.angle):s).length())&&(s=s.scale(1/n),h=n*this.I,i.y=Math.max(i.x,h),n=s.angle(),Ga(a.add(s.multiply(q(0,-h/2))),i,this.s,e,n,this.o))):Ga(a,i,this.s,e,n,this.o),this.J&&bb(),1==t&&(this.color=e,this.size=i,this.fa&&this.fa(this),this.A=1)}}let U,G,Zb,$b,ac,bc,V,cc,W,cb,dc;function ec(){var t;Sa&&!F&&(U=document.createElement("canvas"),G=U.getContext("webgl2"),Rb&&document.body.appendChild(U),t=G.createProgram(),G.attachShader(t,ic("#version 300 es\nprecision highp float;uniform mat4 m;in vec2 g;in vec4 p,u,c,a;in float r;out vec2 v;out vec4 d,e;void main(){vec2 s=(g-.5)*p.zw;gl_Position=m*vec4(p.xy+s*cos(r)-vec2(-s.y,s)*sin(r),1,1);v=mix(u.xw,u.zy,g);d=c;e=a;}",35633)),G.attachShader(t,ic("#version 300 es\nprecision highp float;uniform sampler2D s;in vec2 v;in vec4 d,e;out vec4 c;void main(){c=texture(s,v)*d+e;}",35632)),G.linkProgram(t),Zb=t,t=new ArrayBuffer(44e4),V=new Float32Array(t),cc=new Uint32Array(t),ac=G.createBuffer(),bc=G.createBuffer(),t=new Float32Array([W=0,0,1,0,0,1,1,1]),G.bindBuffer(34962,bc),G.bufferData(34962,t,35044))}function Tb(){var r,t,i;Sa&&!F&&(G.viewport(0,0,U.width=B.width,U.height=B.height),G.clear(16384),G.useProgram(Zb),G.activeTexture(33984),G.bindTexture(3553,$b=Na[0].ja),r=cb=dc=0,t=(t,i,e,a)=>{t=G.getAttribLocation(Zb,t);var s=e&&44,h=e&&1,n=1==e;G.enableVertexAttribArray(t),G.vertexAttribPointer(t,a,i,n,s,r),G.vertexAttribDivisor(t,h),r+=a*e},G.bindBuffer(34962,bc),t("g",5126,0,2),G.bindBuffer(34962,ac),G.bufferData(34962,44e4,35048),t("p",5126,4,4),t("u",5126,4,4),t("c",5121,1,4),t("a",5121,1,4),t("r",5126,4,1),t=q(2*J).U(E),i=q(-1).l(I.multiply(t)),G.uniformMatrix4fv(G.getUniformLocation(Zb,"m"),!1,[t.x,0,0,0,0,t.y,0,0,1,1,1,1,i.x,i.y,0,0]))}function Wa(t){F||t==$b||(jc(),G.bindTexture(3553,$b=t))}function ic(t,i){return i=G.createShader(i),G.shaderSource(i,t),G.compileShader(i),i}function jc(){var t;W&&(t=dc?1:771,G.blendFuncSeparate(770,t,1,t),G.enable(3042),G.bufferSubData(34962,0,V),G.drawArraysInstanced(5,0,4,W),W=0,dc=cb)}function Sb(t=!1){var i=C;Sa&&(W||t)&&(jc(),Rb&&!t||i.drawImage(U,0,0))}function Xa(t,i,e,a,s,h,n,r,o,c,u=0){(1e4<=W||dc!=cb)&&jc();var l=11*W;V[l++]=t,V[l++]=i,V[l++]=e,V[l++]=a,V[l++]=h,V[l++]=n,V[l++]=r,V[l++]=o,cc[l++]=c,cc[l++]=u,V[+l]=s,W++}const Yb=1/60;let y=[],Ea=[],kc=0,x=0,Fb=!1,lc=0,X=0;const mc=[],nc=[];function oc(){Ea=y.filter(t=>t.ca);for(const t of y)t.parent||(function t(i){if(!i.A){i.update();for(const e of i.children)t(e)}}(t),ua(t));y=y.filter(t=>!t.A)}let I=q(),J=32,pc=q(1920,1080),qc=q(),Ta=!0,eb="arial",F=!1,Sa=!0,Rb=!0,Pa=q(16),Ua=.5,Da=!0,xa=1,ya=1,za=1,Aa=0,Ba=.8,z=1,Ca=0,Xb=1,mb=!1,Cb=!(mb=!1),qb=!0,N=!1,ub=N=N=!1,Bb=!0,S=99,Hb=.3,Db=!0,rc=.3,Jb=40,Kb=.7;function sc(){var t=rc;rc=t,Db&&!F&&Ib&&(Ib.gain.value=t)}let Y;qb=N=!1;const tc=new Eb([1,.5]);!function(s,h,n,r,i=["tiles.png"]){function o(t=0){var i=t-lc;if(lc=t,X+=Fb?0:i,X=Math.min(X,50),c(),Fb){for(const e of y)e.parent||ua(e);kb(),h(),ob()}else{for(t=0,X<0&&-9<X&&(t=X,X=0);0<=X;X-=1e3/60)x=kc++/60,kb(),s(),mc.forEach(t=>t()),oc(),h(),ob();X+=t}if(!F){E=q(B.width,B.height),C.imageSmoothingEnabled=!Ta,Tb(),n(),y.sort((t,i)=>t.P-i.P);for(const a of y)a.A||a.H();r(),nc.forEach(t=>t()),Gb(),Sb()}requestAnimationFrame(o)}function c(){var t,i;F||(qc.x?(B.width=qc.x,B.height=qc.y,t=innerWidth/innerHeight,i=B.width/B.height,(U||B).style.width=B.style.width=D.style.width=t<i?"100%":"",(U||B).style.height=B.style.height=D.style.height=t<i?"":"100%"):(B.width=Math.min(innerWidth,pc.x),B.height=Math.min(innerHeight,pc.y)),D.width=B.width,D.height=B.height,E=q(B.width,B.height))}function e(){{T=q(32,16);for(var i=(Ob=[]).length=na(T);i--;)Ob[i]=0;i=q();var e=new Qb(i,T),a=Na[0].image,s=(C.drawImage(a,0,0),C.getImageData(0,0,a.width,a.height).data),h,n,r;for(i.x=T.x;i.x--;)for(i.y=T.y;i.y--;)s[4*(i.x+a.width*(15+T.y-i.y))]&&(h=Math.floor(t(4,0)),n=Math.floor(t(2,0)),r=ja(),e.setData(i,new Pb(1,h,n,r)),pa(i,T))&&(Ob[(0|i.y)*T.x+i.x|0]=1);e.qa(),I=q(16,8),Ca=-.01,(Y=new Wb(q(16,9),0,1,0,500,g,Oa(0,16),new w(1,1,1),new w(0,0,0),new w(0,0,0,0),new w(0,0,0,0),2,.2,.2,.1,.05,.99,1,1,g,.05,.5,1,1)).u=.3,Y.I=2}o()}F?e():(document.body.style.cssText="margin:0;overflow:hidden;background:#000;user-select:none;-webkit-user-select:none;"+(N?"touch-action:none;-webkit-touch-callout:none":""),document.body.appendChild(B=document.createElement("canvas")),C=B.getContext("2d"),pb(),Db&&!F&&(R=new AudioContext,(Ib=R.createGain()).connect(R.destination),sc()),ec(),document.body.appendChild(D=document.createElement("canvas")),Ha=D.getContext("2d"),(U||B).style.cssText=B.style.cssText=D.style.cssText="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)",c(),i=i.map((e,a)=>new Promise(t=>{const i=new Image;i.onerror=i.onload=()=>{Na[a]=new Ra(i),t()},i.src=e})),Promise.all(i).then(e))}(function(){K[0]&&2&K[0][0]&&(tc.play(gb),Y.S=new w,Y.T=ja(),Y.da=Y.S.scale(1,0),Y.ea=Y.T.scale(1,0)),hb.x&&(Y.i=gb)},function(){},function(){Ga(q(16,8),q(20,14),void 0,new w(.6,.6,.6),0,!1,void 0,0)},function(){db()});</script>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const g=Math.PI;function n(t,i=0,e=1){return t<i?i:e<t?e:t}function aa(t,i,e){return(e-=i)?n((t-i)/e):0}function ba(t,i,e,a=q()){return 2*Math.abs(t.x-e.x)<i.x+a.x&&2*Math.abs(t.y-e.y)<i.y+a.y}function t(t=1,i=0){return i+Math.random()*(t-i)}function ca(i=1){return da(new v,t(2*g),i)}function ea(i=1){return 0<i?ca(i*t(0/i,1)**.5):new v}function ja(i=new w,e=new w(0,0,0,1),a=!1){return a?i.ma(e,t()):new w(t(i.r,e.r),t(i.j,e.j),t(i.b,e.b),t(i.a,e.a))}function q(t=0,i){return"number"==typeof t?new v(t,null==i?t:i):new v(t.x,t.y)}function da(t,i=0,e=1){return t.x=e*Math.sin(i),t.y=e*Math.cos(i),t}function ka(t){return t.x**2+t.y**2}function la(t,i){return(t.x-i.x)**2+(t.y-i.y)**2}function ma(t){var i=t.length();return 1<i?t.scale(1/i):t}function na(t){return Math.abs(t.x*t.y)}function pa(t,i){return 0<=t.x&&0<=t.y&&t.x<i.x&&t.y<i.y}class v{constructor(t=0,i=0){this.x=t,this.y=i}set(t=0,i=0){return this.x=t,this.y=i,this}v(){return new v(this.x,this.y)}add(t){return new v(this.x+t.x,this.y+t.y)}l(t){return new v(this.x-t.x,this.y-t.y)}multiply(t){return new v(this.x*t.x,this.y*t.y)}U(t){return new v(this.x/t.x,this.y/t.y)}scale(t){return new v(this.x*t,this.y*t)}length(){return ka(this)**.5}normalize(t=1){var i=this.length();return i?this.scale(t/i):new v(0,t)}angle(){return Math.atan2(this.x,this.y)}rotate(t){var i=Math.cos(t);return t=Math.sin(t),new v(this.x*i-this.y*t,this.x*t+this.y*i)}setDirection(t,i=1){return q(t%2?t-1?-i:i:0,t%2?0:t?-i:i)}direction(){return Math.abs(this.x)>Math.abs(this.y)?this.x<0?3:1:this.y<0?2:0}floor(){return new v(Math.floor(this.x),Math.floor(this.y))}ma(t,i){return this.add(t.l(this).scale(n(i)))}toString(){}}function qa(t){return(255*n(t.r)|0)+(255*n(t.j)<<8)+(255*n(t.b)<<16)+(255*n(t.a)<<24)}class w{constructor(t=1,i=1,e=1,a=1){this.r=t,this.j=i,this.b=e,this.a=a}set(t=1,i=1,e=1,a=1){return this.r=t,this.j=i,this.b=e,this.a=a,this}v(){return new w(this.r,this.j,this.b,this.a)}add(t){return new w(this.r+t.r,this.j+t.j,this.b+t.b,this.a+t.a)}l(t){return new w(this.r-t.r,this.j-t.j,this.b-t.b,this.a-t.a)}multiply(t){return new w(this.r*t.r,this.j*t.j,this.b*t.b,this.a*t.a)}U(t){return new w(this.r/t.r,this.j/t.j,this.b/t.b,this.a/t.a)}scale(t,i=t){return new w(this.r*t,this.j*t,this.b*t,this.a*i)}ma(t,i){return this.add(t.l(this).scale(n(i)))}toString(t=!0){var i=t=>((t=255*t|0)<16?"0":"")+t.toString(16);return"#"+i(this.r)+i(this.j)+i(this.b)+(t?i(this.a):"")}}class ra{constructor(){this.setTime=this.time=void 0}set(t=0){this.time=x+t,this.setTime=t}active(){return x<this.time}get(){return null!=this.time?x-this.time:0}toString(){}valueOf(){return this.get()}}function ua(t){var i,e=t.parent;e&&(i=e.o?-1:1,t.i=t.Ca.multiply(q(i,1)).rotate(-e.angle).add(e.i),t.angle=i*t.Ba+e.angle);for(const a of t.children)ua(a)}function va(t){if(!t.A){t.A=1,t.parent&&t.parent.removeChild(t);for(const i of t.children)va(i,i.parent=0)}}class wa{constructor(t=q(),i=q(1),e,a=0,s,h=0){this.i=t.v(),this.size=i,this.xa=void 0,this.s=e,this.angle=a,this.color=s,this.va=void 0,this.o=!1,this.h=xa,this.m=ya,this.K=za,this.u=Aa,this.X=Ba,this.B=1,this.P=h,this.g=q(),this.R=0,this.ua=x,this.children=[],this.ba=!0,this.parent=void 0,this.Ca=q(),this.Ba=0,this.la=this.ca=this.L=!1,y.push(this)}update(){var t;if(!this.parent&&(this.ba?(this.g.x=n(this.g.x,-z,z),this.g.y=n(this.g.y,-z,z)):(t=ka(this.g))>z*z&&(t=z/t**.5,this.g.x*=t,this.g.y*=t),t=this.i.v(),this.g.y+=Ca*this.B,this.i.x+=this.g.x*=this.m,this.i.y+=this.g.y*=this.m,this.angle+=this.R*=this.K,Da&&this.h)){var i,e,a,s,h,r,o=this.g.y<0;if(this.C&&(i=this.C.g?this.C.g.x:0,this.g.x=i+(this.g.x-i)*this.X,this.C=0),this.ca)for(var c of Ea)!this.la&&!c.la||c.A||c.parent||c==this||ba(this.i,this.size,c.i,c.size)&&(ba(t,this.size,c.i,c.size)?(i=(e=(i=t.l(c.i)).length())<.01?ca(.001):i.scale(.001/e),this.g=this.g.add(i),c.h&&(c.g=c.g.l(i))):(e=this.size.add(c.size),a=2*(t.y-c.i.y)>e.y+Ca,s=2*Math.abs(t.y-c.i.y)<e.y,h=2*Math.abs(t.x-c.i.x)<e.x,i=Math.max(this.u,c.u),!a&&!h&&s||(this.i.y=c.i.y+(e.y/2+.001)*Math.sign(t.y-c.i.y),c.C&&o||!c.h?(o&&(this.C=c),this.g.y*=-i):c.h&&(h=(this.h*this.g.y+c.h*c.g.y)/(this.h+c.h),r=c.g.y*(c.h-this.h)/(this.h+c.h)+2*this.g.y*this.h/(this.h+c.h),this.g.y=h+n(i)*(this.g.y*(this.h-c.h)/(this.h+c.h)+2*c.g.y*c.h/(this.h+c.h)-h),c.g.y=h+n(i)*(r-h))),!a&&s&&(this.i.x=c.i.x+(e.x/2+.001)*Math.sign(t.x-c.i.x),c.h?(e=(this.h*this.g.x+c.h*c.g.x)/(this.h+c.h),a=c.g.x*(c.h-this.h)/(this.h+c.h)+2*this.g.x*this.h/(this.h+c.h),this.g.x=e+n(i)*(this.g.x*(this.h-c.h)/(this.h+c.h)+2*c.g.x*c.h/(this.h+c.h)-e),c.g.x=e+n(i)*(a-e)):this.g.x*=-i)));this.L&&Fa(this.i,this.size,this)&&!Fa(t,this.size,this)&&(c=Fa(q(this.i.x,t.y),this.size,this),!Fa(q(t.x,this.i.y),this.size,this)&&c||(this.C=o,this.g.y*=-this.u,(o=(t.y-this.size.y/2|0)-(t.y-this.size.y/2))<0&&o>this.m*this.g.y+Ca*this.B&&(this.g.y=this.m?(o-Ca*this.B)/this.m:0),this.i.y=t.y),c)&&(this.i.x=t.x,this.g.x*=-this.u)}}H(){Ga(this.i,this.xa||this.size,this.s,this.color,this.angle,this.o,this.va)}removeChild(t){t.parent==this&&this.children.includes(t),this.children.splice(this.children.indexOf(t),1),t.parent=0}toString(){}}let B,C,D,Ha,E=q(),Na=[];function Oa(t=q(),i=Pa,e=0){var a;return F?new Qa:("number"==typeof i&&(i=q(i)),"number"==typeof t&&(t=q(t%(a=Na[e].size.x/i.x|0)*i.x,(t/a|0)*i.y)),new Qa(t,i,e))}class Qa{constructor(t=q(),i=Pa,e=0){this.i=t.v(),this.size=i.v(),this.$=e}offset(t){return new Qa(this.i.add(t),this.size,this.$)}frame(t){return this.offset(q(t*this.size.x,0))}}class Ra{constructor(t){var i;this.image=t,this.size=q(t.width,t.height),(i=Sa)&&(i=G.createTexture(),G.bindTexture(3553,i),t&&G.texImage2D(3553,0,6408,6408,5121,t),t=Ta?9728:9729,G.texParameteri(3553,10241,t),G.texParameteri(3553,10240,t)),this.ja=i,this.ya=q(Ua).U(this.size)}}function Va(t){return new v((t.x-I.x)*J+E.x/2-.5,(t.y-I.y)*-J+E.y/2-.5)}function Ga(t,i=q(1),h,n=new w,e=0,a,s=new w(0,0,0,0),r=Sa){const o=h&&Na[h.$];var c,u,l,b;r?o?(r=h.i.x/o.size.x,c=h.i.y/o.size.y,u=h.size.x/o.size.x,l=h.size.y/o.size.y,b=o.ya,Wa(o.ja),Xa(t.x,t.y,a?-i.x:i.x,i.y,e,r+b.x,c+b.y,r-b.x+u,c-b.y+l,qa(n),qa(s))):Xa(t.x,t.y,i.x,i.y,e,0,0,0,0,0,qa(n)):ab(t,i,e,a,t=>{var i,e,a,s;o?(i=h.i.x+Ua,e=h.i.y+Ua,a=h.size.x-2*Ua,s=h.size.y-2*Ua,t.globalAlpha=n.a,t.drawImage(o.image,i,e,a,s,-.5,-.5,1,1),t.globalAlpha=1):(t.fillStyle=n,t.fillRect(-.5,-.5,1,1))})}function ab(t,i,e,a,s){var h=C;t=Va(t),i=i.scale(J),h.save(),h.translate(t.x+.5,t.y+.5),h.rotate(e),h.scale(a?-i.x:i.x,-i.y),s(h),h.restore()}function bb(t){var i;Sa?cb=t:(i||=C).globalCompositeOperation=t?"lighter":"source-over"}function db(){var i=q(E.x/2,70),t=new w(0,0,0),e=eb,a=Ha;a.fillStyle=(new w).toString(),a.lineWidth=0,a.strokeStyle=t.toString(),a.textAlign="center",a.font="80px "+e,a.textBaseline="middle",a.lineJoin="round",i=i.v(),["LittleJS JS13K Demo"].forEach(t=>{a.fillText(t,i.x,i.y),i.y+=80})}function fb(t,i=0){return K[i]&&!!(1&K[i][t])}let gb=q(),hb=q(),ib=!1;function jb(t,i=0){return fb(t,i+1)}let K=[[]];function kb(){var t;F||(N&&lb||document.hasFocus()||(K=[[]]),t=hb,gb=new v((t.x-E.x/2+.5)/J+I.x,(t.y-E.y/2+.5)/-J+I.y),mb&&nb())}function ob(){if(!F)for(const t of K)for(const i in t)t[i]&=1}function pb(){function i(t){return qb?"KeyW"==t?"ArrowUp":"KeyS"==t?"ArrowDown":"KeyA"==t?"ArrowLeft":"KeyD"==t?"ArrowRight":t:t}F||(onkeydown=t=>{t.repeat||(ib=!1,K[0][t.code]=3,qb&&(K[0][i(t.code)]=3))},onkeyup=t=>{K[0][t.code]=4,qb&&(K[0][i(t.code)]=4)},onmousedown=t=>{ib=!1,K[0][t.button]=3,hb=rb(t),t.button&&t.preventDefault()},onmouseup=t=>K[0][t.button]=2&K[0][t.button]|4,onmousemove=t=>hb=rb(t),onwheel=t=>t.ctrlKey?0:Math.sign(t.deltaY),oncontextmenu=()=>!1,lb&&N&&!F&&sb())}function rb(t){var i;return!B||F?q():(i=B.getBoundingClientRect(),q(B.width,B.height).multiply(q(aa(t.x,i.left,i.right),aa(t.y,i.top,i.bottom))))}const tb=[];function nb(){var t=t=>{var i=t=>.3<t?aa(t,.3,.8):t<-.3?-aa(-t,.3,.8):0;return ma(q(i(t.x),i(-t.y)))};if(ub&&lb&&null!=Ab.time){(i=tb[0]||(tb[0]=[]))[0]=q(),Bb?i[0]=t(O):.3<ka(O)&&(i[0].x=Math.round(O.x),i[0].y=-Math.round(O.y),i[0]=ma(i[0]));for(var i=K[1]||(K[1]=[]),e=10;e--;){var a=3==e?2:2==e?3:e,s=jb(a,0);i[a]=Q[e]?s?1:3:s?4:0}}if(mb&&mb&&navigator&&navigator.getGamepads&&document.hasFocus())for(e=(i=navigator.getGamepads()).length;e--;){var s=i[e],h=K[e+1]||(K[e+1]=[]),a=tb[e]||(tb[e]=[]);if(s){for(var n=0;n<s.axes.length-1;n+=2)a[n>>1]=t(q(s.axes[n],s.axes[n+1]));for(n=s.buttons.length;n--;){var r=s.buttons[n],o=jb(n,e);h[n]=r.pressed?o?1:3:o?4:0,ib||=!e&&r.pressed}Cb&&ka(s=q((jb(15,e)&&1)-(jb(14,e)&&1),(jb(12,e)&&1)-(jb(13,e)&&1)))&&(a[0]=ma(s)),ub&&ib&&(Ab.time=void 0)}}}const lb=void 0!==window.ontouchstart;let Ab=new ra,Q,O;function sb(){function n(t){Db&&R&&"running"!=R.state&&new Eb([0]).play();var i=t.touches.length;return i?(hb=rb(q(t.touches[0].clientX,t.touches[0].clientY)),e?ib=!1:K[0][0]=3):e&&(K[0][0]=2&K[0][0]|4),e=i,document.hasFocus()&&t.preventDefault(),!0}let i=n;ub&&(i=function(t){if(O=q(),Q=[],ib=!0,!t.touches.length||(Ab.set(),!Fb)){var i=q(S,E.y-S),e=E.l(q(S,S)),a=E.scale(.5);for(const h of t.touches){var s=rb(q(h.clientX,h.clientY));la(s,i)**.5<S?O=ma(s.l(i).scale(2/S)):la(s,e)**.5<S?(s=s.l(e).direction(),Q[s]=1):la(s,a)**.5<S&&(Q[9]=1)}return n(t),!0}Q[9]=1},Q=[],O=q()),document.addEventListener("touchstart",t=>i(t),{passive:!1}),document.addEventListener("touchmove",t=>i(t),{passive:!1}),document.addEventListener("touchend",t=>i(t),{passive:!1}),onmousedown=onmouseup=()=>0;let e}function Gb(){if(N&&lb&&!F&&ub&&null!=Ab.time){var t=aa(Ab.get(),4,3);if(t&&!Fb){var i=Ha;if(i.save(),i.globalAlpha=t*Hb,i.strokeStyle="#fff",i.lineWidth=3,i.fillStyle=0<ka(O)?"#fff":"#000",i.beginPath(),t=q(S,E.y-S),Bb)i.arc(t.x,t.y,S/2,0,9),i.fill();else for(var e=10;e--;){var a=e*g/4;i.arc(t.x,t.y,.6*S,a+g/8,a+g/8),e%2&&i.arc(t.x,t.y,.33*S,a,a),1==e&&i.fill()}for(i.stroke(),t=q(E.x-S,E.y-S),e=4;e--;)a=t.add(q().setDirection(e,S/2)),i.fillStyle=Q[e]?"#fff":"#000",i.beginPath(),i.arc(a.x,a.y,S/4,0,9),i.fill(),i.stroke();i.restore()}}}let R,Ib;class Eb{constructor(t){var i=Jb,e=Kb;Db&&!F&&(this.Fa=i,this.Ja=e,this.O=0,t)&&(this.O=t[1]||.05,this.ta=[Lb(...t)],this.sampleRate=44100)}play(i,e=1,a=1,s=1,h=!1){if(Db&&!F&&this.ta){var n;if(i){if(n=this.Fa){var r=la(I,i);if(n*n<r)return;e*=aa(r**.5,n,n*this.Ja)}n=2*Va(i).x/B.width-1}return i=a+a*this.O*s*t(-1,1),this.za=R.createGain(),this.source=Mb(this.ta,e,i,n,h,this.sampleRate,this.za)}}stop(){this.source&&this.source.stop(),this.source=void 0}}let Nb=!1;function Mb(t,i=1,e=1,a=0,s=!1,h=44100,r){if(Db&&!F){var o,c=Nb;if(!(Nb="running"!=R.state)||(R.resume(),!c))return o=R.createBuffer(t.length,t[0].length,h),h=R.createBufferSource(),t.forEach((t,i)=>o.getChannelData(i).set(t)),h.buffer=o,h.playbackRate.value=e,h.loop=s,(r=r||R.createGain()).gain.value=i,r.connect(Ib),h.connect(new StereoPannerNode(R,{pan:n(a,-1,1)})).connect(r),h.start(),h}}function Lb(t=1,i,e=220,a=0,s=0,h=.1,r=0,o=1,c=0,u=0,l=0,b=0,f=0,d=0,y=0,x=0,v=0,m=1,w=0,p=0,q=0){let O=c*=500*(i=2*g)/44100/44100,S=e*=i/44100,z=[],G=0,k=0,M=0,B=1,U=0,J=0,D=0;var F=i*Math.abs(q)*2/44100,C=Math.cos(F),E=1+(A=Math.sin(F)/2/2),F=-2*C/E,A=(1-A)/E;let j=(1+Math.sign(q)*C)/2/E,P=-(Math.sign(q)+C)/E,T=0,K=0,I=0,R=0;for(u*=500*i/44100**3,y*=i/44100,l*=i/44100,b*=44100,f=44100*f|0,E=(a=44100*a+9)+(w*=44100)+(s*=44100)+(h*=44100)+(v*=44100)|0;M<E;z[M++]=D*t)++J%(100*x|0)||(D=r?1<r?2<r?3<r?Math.sin(G**3):n(Math.tan(G),1,-1):1-(2*G/i%2+2)%2:1-4*Math.abs(Math.round(G/i)-G/i):Math.sin(G),D=(f?1-p+p*Math.sin(i*M/f):1)*Math.sign(D)*Math.abs(D)**o*(M<a?M/a:M<a+w?1-(M-a)/w*(1-m):M<a+w+s?m:M<E-v?(E-M-v)/h*m:0),D=v?D/2+(v>M?0:(M<E-v?1:(E-M)/v)*z[M-v|0]/2/t):D,q&&(D=R=j*T+P*(T=K)+j*(K=D)-A*I-F*(I=R))),C=(e+=c+=u)*Math.cos(y*k++),G+=C+C*d*Math.sin(M**5),B&&++B>b&&(e+=l,S+=l,B=0),!f||++U%f||(e=S,c=O,B=B||1);return z}let Ob=[],T=q();function Fa(t,i=q(),e){var a=Math.max(t.x-i.x/2|0,0),s=Math.max(t.y-i.y/2|0,0),h=Math.min(t.x+i.x/2,T.x);for(t=Math.min(t.y+i.y/2,T.y);s<t;++s)for(i=a;i<h;++i){var n=Ob[s*T.x+i];if(n&&(!e||0<n))return!0}}class Pb{constructor(t,i=0,e=!1,a=new w){this.aa=t,this.direction=i,this.o=e,this.color=a}clear(){this.aa=this.direction=0,this.o=!1,this.color=new w}}class Qb extends wa{constructor(t,i=T){var e=q(1);for(super(t,i,Oa(),0,void 0,0),this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),this.scale=e,this.ka=!1,this.data=[],t=na(this.size);t--;)this.data.push(new Pb);F&&(this.qa=()=>{},this.H=()=>{},this.sa=()=>{},this.ra=()=>{},this.V=()=>{})}setData(t,i,e=!1){pa(t,this.size)&&(this.data[(0|t.y)*this.size.x+t.x|0]=i,e)&&this.V(t)}getData(t){return pa(t,this.size)&&this.data[(0|t.y)*this.size.x+t.x|0]}update(){}H(){Rb||this.ka||Sb();var t=Va(this.i.add(q(0,this.size.y*this.scale.y)));(this.ka?Ha:C).drawImage(this.canvas,t.x,t.y,J*this.size.x*this.scale.x,J*this.size.y*this.scale.y)}qa(){this.sa(!0);for(let i=this.size.x;i--;)for(let t=this.size.y;t--;)this.V(q(i,t),!1);this.ra()}sa(t=!1){this.Ga=[B,C,E,I,J],B=this.canvas,C=this.context,E=this.size.multiply(this.s.size),I=this.size.scale(.5),J=this.s.size.x,t&&(B.width=E.x,B.height=E.y),this.context.imageSmoothingEnabled=!Ta,Tb()}ra(){Sb(!0),[B,C,E,I,J]=this.Ga}V(t,i=!0){var e=this.s.size;i&&(i=t.multiply(e),this.context.clearRect(i.x,this.canvas.height-i.y,e.x,-e.y)),null!=(i=this.getData(t)).aa&&Ga(t=this.i.add(t).add(q(.5)),q(1),Oa(i.aa,e,this.s.$),i.color,i.direction*g/2,i.o)}}function Ub(i){var e="number"==typeof i.W?ea(i.W/2):q(t(-.5,.5),t(-.5,.5)).multiply(i.W).rotate(i.angle);let a=t(i.na,-i.na);i.Y||(e=i.i.add(e),a+=i.angle);const s=i.O;var h=(c=i=>i+i*t(s,-s))(i.Ea),n=c(i.Z),r=c(i.Ha),o=c(i.speed),c=c(i.wa)*(2*Math.floor(t(2,0))-1),u=t(i.ga,-i.ga),l=ja(i.S,i.T,i.pa),b=ja(i.da,i.ea,i.pa),u=i.Y?u:i.angle+u;(e=new Vb(e,i.s,a,l,b,h,n,r,i.G,i.J,i.I,i.Y&&i,i.Da)).g=da(q(),u,o),e.R=c,e.G=i.G,e.m=i.m,e.K=i.K,e.u=i.u,e.X=i.X,e.B=i.B,e.L=i.L,e.P=i.P,e.o=!!Math.floor(t(2,0)),i.oa&&i.oa(e)}class Wb extends wa{constructor(t,i,e=0,a=0,s=100,h=g,n,r=new w,o=new w,c=new w(1,1,1,0),u=new w(1,1,1,0),l=.5,b=.1,f=1,d=.1,y=.05,x=1,v=1,m=0,p=g,S=.1,z=.2,G=!1,M=!1,B=!0,D=M?1e9:0,F=!1){super(t,q(),n,i,void 0,D),this.W=e,this.ia=a,this.ha=s,this.ga=h,this.S=r,this.T=o,this.da=c,this.ea=u,this.pa=B,this.Ea=l,this.Z=b,this.Ha=f,this.speed=d,this.wa=y,this.m=x,this.K=v,this.B=m,this.na=p,this.G=S,this.O=z,this.L=G,this.J=M,this.Y=F,this.I=0,this.oa=this.Da=void 0,this.F=0}update(){if(this.parent&&super.update(),!this.ia||x-this.ua<=this.ia){if(this.ha*Xb){var t=1/this.ha/Xb;for(this.F+=Yb;0<this.F;this.F-=t)Ub(this)}}else va(this)}H(){}}class Vb extends wa{constructor(t,i,e,a,s,h,n,r,o,c,u,l,b){super(t,q(),i,e),this.N=a,this.M=s.l(a),this.Aa=h,this.Z=n,this.Ia=r-n,this.G=o,this.J=c,this.I=u,this.D=l,this.fa=b,this.ba=!1}H(){var t=Math.min((x-this.ua)/this.Aa,1),i=q(this.Z+t*this.Ia),e=this.G/2,e=new w(this.N.r+t*this.M.r,this.N.j+t*this.M.j,this.N.b+t*this.M.b,(this.N.a+t*this.M.a)*(t<e?t/e:1-e<t?(1-t)/e:1));this.J&&bb(!0);let a=this.i;var s,h,n=this.angle;this.D&&(a=this.D.i.add(a.rotate(-this.D.angle)),n+=this.D.angle),this.I?(s=this.g,(n=(s=this.D?s.rotate(-this.D.angle):s).length())&&(s=s.scale(1/n),h=n*this.I,i.y=Math.max(i.x,h),n=s.angle(),Ga(a.add(s.multiply(q(0,-h/2))),i,this.s,e,n,this.o))):Ga(a,i,this.s,e,n,this.o),this.J&&bb(),1==t&&(this.color=e,this.size=i,this.fa&&this.fa(this),this.A=1)}}let U,G,Zb,$b,ac,bc,V,cc,W,cb,dc;function ec(){var t;Sa&&!F&&(U=document.createElement("canvas"),G=U.getContext("webgl2"),Rb&&document.body.appendChild(U),t=G.createProgram(),G.attachShader(t,ic("#version 300 es\nprecision highp float;uniform mat4 m;in vec2 g;in vec4 p,u,c,a;in float r;out vec2 v;out vec4 d,e;void main(){vec2 s=(g-.5)*p.zw;gl_Position=m*vec4(p.xy+s*cos(r)-vec2(-s.y,s)*sin(r),1,1);v=mix(u.xw,u.zy,g);d=c;e=a;}",35633)),G.attachShader(t,ic("#version 300 es\nprecision highp float;uniform sampler2D s;in vec2 v;in vec4 d,e;out vec4 c;void main(){c=texture(s,v)*d+e;}",35632)),G.linkProgram(t),Zb=t,t=new ArrayBuffer(44e4),V=new Float32Array(t),cc=new Uint32Array(t),ac=G.createBuffer(),bc=G.createBuffer(),t=new Float32Array([W=0,0,1,0,0,1,1,1]),G.bindBuffer(34962,bc),G.bufferData(34962,t,35044))}function Tb(){var r,t,i;Sa&&!F&&(G.viewport(0,0,U.width=B.width,U.height=B.height),G.clear(16384),G.useProgram(Zb),G.activeTexture(33984),G.bindTexture(3553,$b=Na[0].ja),r=cb=dc=0,t=(t,i,e,a)=>{t=G.getAttribLocation(Zb,t);var s=e&&44,h=e&&1,n=1==e;G.enableVertexAttribArray(t),G.vertexAttribPointer(t,a,i,n,s,r),G.vertexAttribDivisor(t,h),r+=a*e},G.bindBuffer(34962,bc),t("g",5126,0,2),G.bindBuffer(34962,ac),G.bufferData(34962,44e4,35048),t("p",5126,4,4),t("u",5126,4,4),t("c",5121,1,4),t("a",5121,1,4),t("r",5126,4,1),t=q(2*J).U(E),i=q(-1).l(I.multiply(t)),G.uniformMatrix4fv(G.getUniformLocation(Zb,"m"),!1,[t.x,0,0,0,0,t.y,0,0,1,1,1,1,i.x,i.y,0,0]))}function Wa(t){F||t==$b||(jc(),G.bindTexture(3553,$b=t))}function ic(t,i){return i=G.createShader(i),G.shaderSource(i,t),G.compileShader(i),i}function jc(){var t;W&&(t=dc?1:771,G.blendFuncSeparate(770,t,1,t),G.enable(3042),G.bufferSubData(34962,0,V),G.drawArraysInstanced(5,0,4,W),W=0,dc=cb)}function Sb(t=!1){var i=C;Sa&&(W||t)&&(jc(),Rb&&!t||i.drawImage(U,0,0))}function Xa(t,i,e,a,s,h,n,r,o,c,u=0){(1e4<=W||dc!=cb)&&jc();var l=11*W;V[l++]=t,V[l++]=i,V[l++]=e,V[l++]=a,V[l++]=h,V[l++]=n,V[l++]=r,V[l++]=o,cc[l++]=c,cc[l++]=u,V[+l]=s,W++}const Yb=1/60;let y=[],Ea=[],kc=0,x=0,Fb=!1,lc=0,X=0;const mc=[],nc=[];function oc(){Ea=y.filter(t=>t.ca);for(const t of y)t.parent||(function t(i){if(!i.A){i.update();for(const e of i.children)t(e)}}(t),ua(t));y=y.filter(t=>!t.A)}let I=q(),J=32,pc=q(1920,1080),qc=q(),Ta=!0,eb="arial",F=!1,Sa=!0,Rb=!0,Pa=q(16),Ua=.5,Da=!0,xa=1,ya=1,za=1,Aa=0,Ba=.8,z=1,Ca=0,Xb=1,mb=!1,Cb=!(mb=!1),qb=!0,N=!1,ub=N=N=!1,Bb=!0,S=99,Hb=.3,Db=!0,rc=.3,Jb=40,Kb=.7;function sc(){var t=rc;rc=t,Db&&!F&&Ib&&(Ib.gain.value=t)}let Y;qb=N=!1;const tc=new Eb([1,.5]);!function(s,h,n,r,i=["tiles.png"]){function o(t=0){var i=t-lc;if(lc=t,X+=Fb?0:i,X=Math.min(X,50),c(),Fb){for(const e of y)e.parent||ua(e);kb(),h(),ob()}else{for(t=0,X<0&&-9<X&&(t=X,X=0);0<=X;X-=1e3/60)x=kc++/60,kb(),s(),mc.forEach(t=>t()),oc(),h(),ob();X+=t}if(!F){E=q(B.width,B.height),C.imageSmoothingEnabled=!Ta,Tb(),n(),y.sort((t,i)=>t.P-i.P);for(const a of y)a.A||a.H();r(),nc.forEach(t=>t()),Gb(),Sb()}requestAnimationFrame(o)}function c(){var t,i;F||(qc.x?(B.width=qc.x,B.height=qc.y,t=innerWidth/innerHeight,i=B.width/B.height,(U||B).style.width=B.style.width=D.style.width=t<i?"100%":"",(U||B).style.height=B.style.height=D.style.height=t<i?"":"100%"):(B.width=Math.min(innerWidth,pc.x),B.height=Math.min(innerHeight,pc.y)),D.width=B.width,D.height=B.height,E=q(B.width,B.height))}function e(){{T=q(32,16);for(var i=(Ob=[]).length=na(T);i--;)Ob[i]=0;i=q();var e=new Qb(i,T),a=Na[0].image,s=(C.drawImage(a,0,0),C.getImageData(0,0,a.width,a.height).data),h,n,r;for(i.x=T.x;i.x--;)for(i.y=T.y;i.y--;)s[4*(i.x+a.width*(15+T.y-i.y))]&&(h=Math.floor(t(4,0)),n=Math.floor(t(2,0)),r=ja(),e.setData(i,new Pb(1,h,n,r)),pa(i,T))&&(Ob[(0|i.y)*T.x+i.x|0]=1);e.qa(),I=q(16,8),Ca=-.01,(Y=new Wb(q(16,9),0,1,0,500,g,Oa(0,16),new w(1,1,1),new w(0,0,0),new w(0,0,0,0),new w(0,0,0,0),2,.2,.2,.1,.05,.99,1,1,g,.05,.5,1,1)).u=.3,Y.I=2}o()}F?e():(document.body.style.cssText="margin:0;overflow:hidden;background:#000;user-select:none;-webkit-user-select:none;"+(N?"touch-action:none;-webkit-touch-callout:none":""),document.body.appendChild(B=document.createElement("canvas")),C=B.getContext("2d"),pb(),Db&&!F&&(R=new AudioContext,(Ib=R.createGain()).connect(R.destination),sc()),ec(),document.body.appendChild(D=document.createElement("canvas")),Ha=D.getContext("2d"),(U||B).style.cssText=B.style.cssText=D.style.cssText="position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)",c(),i=i.map((e,a)=>new Promise(t=>{const i=new Image;i.onerror=i.onload=()=>{Na[a]=new Ra(i),t()},i.src=e})),Promise.all(i).then(e))}(function(){K[0]&&2&K[0][0]&&(tc.play(gb),Y.S=new w,Y.T=ja(),Y.da=Y.S.scale(1,0),Y.ea=Y.T.scale(1,0)),hb.x&&(Y.i=gb)},function(){},function(){Ga(q(16,8),q(20,14),void 0,new w(.6,.6,.6),0,!1,void 0,0)},function(){db()});
|
|
Binary file
|
|
Binary file
|
package/examples/js13k/game.js
CHANGED
|
@@ -112,4 +112,4 @@ function gameRenderPost()
|
|
|
112
112
|
|
|
113
113
|
///////////////////////////////////////////////////////////////////////////////
|
|
114
114
|
// Startup LittleJS Engine
|
|
115
|
-
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost);
|
|
115
|
+
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
|
|
Binary file
|
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
<head
|
|
1
|
+
<head>
|
|
2
|
+
<title>LittleJS JS13K Project</title>
|
|
3
|
+
<meta charset=utf-8>
|
|
4
|
+
</head><body>
|
|
2
5
|
|
|
3
6
|
<!-- LittleJS Engine -->
|
|
4
|
-
<script src=../../src/engineDebug.js?
|
|
5
|
-
<script src=../../src/engineUtilities.js?
|
|
6
|
-
<script src=../../src/engineSettings.js?
|
|
7
|
-
<script src=../../src/engineObject.js?
|
|
8
|
-
<script src=../../src/engineDraw.js?
|
|
9
|
-
<script src=../../src/engineInput.js?
|
|
10
|
-
<script src=../../src/engineAudio.js?
|
|
11
|
-
<script src=../../src/engineTileLayer.js?
|
|
12
|
-
<script src=../../src/engineParticles.js?
|
|
13
|
-
<script src=../../src/engineMedals.js?
|
|
14
|
-
<script src=../../src/engineWebGL.js?
|
|
15
|
-
<script src=../../src/engine.js?
|
|
7
|
+
<script src=../../src/engineDebug.js?1100></script>
|
|
8
|
+
<script src=../../src/engineUtilities.js?1100></script>
|
|
9
|
+
<script src=../../src/engineSettings.js?1100></script>
|
|
10
|
+
<script src=../../src/engineObject.js?1100></script>
|
|
11
|
+
<script src=../../src/engineDraw.js?1100></script>
|
|
12
|
+
<script src=../../src/engineInput.js?1100></script>
|
|
13
|
+
<script src=../../src/engineAudio.js?1100></script>
|
|
14
|
+
<script src=../../src/engineTileLayer.js?1100></script>
|
|
15
|
+
<script src=../../src/engineParticles.js?1100></script>
|
|
16
|
+
<script src=../../src/engineMedals.js?1100></script>
|
|
17
|
+
<script src=../../src/engineWebGL.js?1100></script>
|
|
18
|
+
<script src=../../src/engine.js?1100></script>
|
|
16
19
|
|
|
17
20
|
<!-- Add your game scripts here -->
|
|
18
|
-
<script src=game.js?
|
|
21
|
+
<script src=game.js?1100></script>
|
package/examples/module/game.js
CHANGED
|
@@ -128,4 +128,4 @@ function gameRenderPost()
|
|
|
128
128
|
|
|
129
129
|
///////////////////////////////////////////////////////////////////////////////
|
|
130
130
|
// Startup LittleJS Engine
|
|
131
|
-
LittleJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost);
|
|
131
|
+
LittleJS.engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<!DOCTYPE html><head>
|
|
2
|
-
<title>
|
|
2
|
+
<title>LittleJS Module Demo</title>
|
|
3
|
+
<meta charset=utf-8>
|
|
3
4
|
<meta name=apple-mobile-web-app-capable content=yes>
|
|
4
5
|
<meta name=mobile-web-app-capable content=yes>
|
|
5
6
|
<link rel=icon type=image/png href=../favicon.png>
|
|
6
7
|
</head><body>
|
|
7
8
|
|
|
8
9
|
<!-- Add your game scripts here -->
|
|
9
|
-
<script src=game.js?
|
|
10
|
+
<script src=game.js?1100 type=module></script>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<!DOCTYPE html><head>
|
|
2
|
-
<title>
|
|
2
|
+
<title>LittleJS Particle System Designer</title>
|
|
3
|
+
<meta charset=utf-8>
|
|
3
4
|
<meta name=apple-mobile-web-app-capable content=yes>
|
|
4
5
|
<meta name=mobile-web-app-capable content=yes>
|
|
5
6
|
<link rel=icon type=image/png href=../favicon.png>
|
|
@@ -9,7 +10,7 @@ button { margin:1px; }
|
|
|
9
10
|
</style>
|
|
10
11
|
</head><body>
|
|
11
12
|
|
|
12
|
-
<script src=../../dist/littlejs.js?
|
|
13
|
+
<script src=../../dist/littlejs.js?1100></script>
|
|
13
14
|
<script>
|
|
14
15
|
|
|
15
16
|
'use strict';
|
|
@@ -390,6 +391,6 @@ function gameRenderPost()
|
|
|
390
391
|
|
|
391
392
|
///////////////////////////////////////////////////////////////////////////////
|
|
392
393
|
// Startup LittleJS Engine
|
|
393
|
-
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost);
|
|
394
|
+
engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
|
|
394
395
|
|
|
395
396
|
</script>
|
|
@@ -13,6 +13,12 @@ setShowSplashScreen(true);
|
|
|
13
13
|
|
|
14
14
|
let spriteAtlas, score, deaths;
|
|
15
15
|
|
|
16
|
+
// enable touch gamepad on touch devices
|
|
17
|
+
touchGamepadEnable = true;
|
|
18
|
+
|
|
19
|
+
// fix texture bleeding by shrinking tile slightly
|
|
20
|
+
tileFixBleedScale = .1;
|
|
21
|
+
|
|
16
22
|
///////////////////////////////////////////////////////////////////////////////
|
|
17
23
|
function gameInit()
|
|
18
24
|
{
|
|
@@ -30,10 +36,6 @@ function gameInit()
|
|
|
30
36
|
gun: tile(2,8),
|
|
31
37
|
grenade: tile(3,8),
|
|
32
38
|
};
|
|
33
|
-
|
|
34
|
-
// enable touch gamepad on touch devices
|
|
35
|
-
touchGamepadEnable = true;
|
|
36
|
-
|
|
37
39
|
// setup level
|
|
38
40
|
buildLevel();
|
|
39
41
|
|
|
@@ -81,7 +83,7 @@ function gameUpdate()
|
|
|
81
83
|
function getCameraTarget()
|
|
82
84
|
{
|
|
83
85
|
// camera is above player
|
|
84
|
-
const offset =
|
|
86
|
+
const offset = 200/cameraScale*percent(mainCanvasSize.y, 300, 600);
|
|
85
87
|
return player.pos.add(vec2(0, offset));
|
|
86
88
|
}
|
|
87
89
|
|
|
@@ -31,6 +31,7 @@ class Character extends GameObject
|
|
|
31
31
|
this.renderOrder = 10;
|
|
32
32
|
this.walkCyclePercent = 0;
|
|
33
33
|
this.health = 1;
|
|
34
|
+
this.climbingLadder = false;
|
|
34
35
|
this.setCollision(true,false);
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -102,9 +103,9 @@ class Character extends GameObject
|
|
|
102
103
|
touchingLadder ||= collisionData == tileType_ladder;
|
|
103
104
|
}
|
|
104
105
|
if (!touchingLadder)
|
|
105
|
-
this.climbingLadder =
|
|
106
|
+
this.climbingLadder = false;
|
|
106
107
|
else if (moveInput.y)
|
|
107
|
-
this.climbingLadder =
|
|
108
|
+
this.climbingLadder = true;
|
|
108
109
|
|
|
109
110
|
if (this.weapon) // update weapon trigger
|
|
110
111
|
this.weapon.triggerIsDown = this.holdingShoot && !this.dodgeTimer.active();
|
|
@@ -236,10 +237,10 @@ class Character extends GameObject
|
|
|
236
237
|
damage(damage, damagingObject)
|
|
237
238
|
{
|
|
238
239
|
if (this.isDead() || this.getAliveTime() < 1 || this.dodgeTimer.active())
|
|
239
|
-
return;
|
|
240
|
+
return 0;
|
|
240
241
|
|
|
241
242
|
makeBlood(damagingObject ? damagingObject.pos : this.pos);
|
|
242
|
-
super.damage(damage, damagingObject);
|
|
243
|
+
return super.damage(damage, damagingObject);
|
|
243
244
|
}
|
|
244
245
|
|
|
245
246
|
kill(damagingObject)
|
|
@@ -251,31 +252,31 @@ class Character extends GameObject
|
|
|
251
252
|
sound_die.play(this.pos);
|
|
252
253
|
|
|
253
254
|
this.health = 0;
|
|
254
|
-
if (this.weapon)
|
|
255
|
-
this.weapon.destroy();
|
|
256
255
|
this.deadTimer.set();
|
|
257
256
|
this.size = this.size.scale(.5);
|
|
258
257
|
const fallDirection = damagingObject ? sign(damagingObject.velocity.x) : randSign();
|
|
259
258
|
this.angleVelocity = fallDirection*rand(.22,.14);
|
|
260
259
|
this.angleDamping = .9;
|
|
261
260
|
this.renderOrder = -1; // move to back layer
|
|
261
|
+
if (this.weapon)
|
|
262
|
+
this.weapon.destroy();
|
|
262
263
|
}
|
|
263
264
|
|
|
264
265
|
collideWithTile(data, pos)
|
|
265
266
|
{
|
|
266
267
|
if (!data)
|
|
267
|
-
return;
|
|
268
|
+
return false;
|
|
268
269
|
|
|
269
270
|
if (data == tileType_ladder)
|
|
270
271
|
{
|
|
271
272
|
// handle ladder collisions
|
|
272
273
|
if (pos.y + 1 > this.lastPos.y - this.size.y/2)
|
|
273
|
-
return;
|
|
274
|
+
return false;
|
|
274
275
|
|
|
275
276
|
if (getTileCollisionData(pos.add(vec2(0,1))) // above
|
|
276
277
|
&& !getTileCollisionData(pos.add(vec2(1,0))) // left
|
|
277
278
|
&& !getTileCollisionData(pos.add(vec2(1,0)))) // right
|
|
278
|
-
return; // dont collide if something above it and nothing to left or right
|
|
279
|
+
return false; // dont collide if something above it and nothing to left or right
|
|
279
280
|
|
|
280
281
|
// allow standing on top of ladders
|
|
281
282
|
return !this.climbingLadder;
|
|
@@ -287,9 +288,9 @@ class Character extends GameObject
|
|
|
287
288
|
{
|
|
288
289
|
// break blocks above
|
|
289
290
|
this.velocity.y = 0;
|
|
290
|
-
return;
|
|
291
|
+
return false;
|
|
291
292
|
}
|
|
292
293
|
|
|
293
|
-
return
|
|
294
|
+
return true;
|
|
294
295
|
}
|
|
295
296
|
}
|
|
@@ -129,13 +129,13 @@ function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
|
|
|
129
129
|
// destroy tile
|
|
130
130
|
const tileType = getTileCollisionData(pos);
|
|
131
131
|
if (!tileType)
|
|
132
|
-
return
|
|
132
|
+
return true;
|
|
133
133
|
|
|
134
134
|
const tileLayer = tileLayers[foregroundLayerIndex];
|
|
135
135
|
const centerPos = pos.add(vec2(.5));
|
|
136
136
|
const layerData = tileLayer.getData(pos);
|
|
137
137
|
if (!layerData || tileType == tileType_solid)
|
|
138
|
-
return;
|
|
138
|
+
return false;
|
|
139
139
|
|
|
140
140
|
// create effects
|
|
141
141
|
makeDebris(centerPos, layerData.color.mutate());
|
|
@@ -144,7 +144,6 @@ function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
|
|
|
144
144
|
// set and clear tile
|
|
145
145
|
tileLayer.setData(pos, new TileLayerData, 1);
|
|
146
146
|
setTileCollisionData(pos, tileType_empty);
|
|
147
|
-
setTileData(pos, foregroundLayerIndex, 0);
|
|
148
147
|
|
|
149
148
|
// cleanup neighbors
|
|
150
149
|
if (cleanNeighbors)
|
|
@@ -154,7 +153,7 @@ function destroyTile(pos, makeSound = 1, cleanNeighbors = 1)
|
|
|
154
153
|
decorateTile(pos.add(vec2(i,j)));
|
|
155
154
|
}
|
|
156
155
|
|
|
157
|
-
return
|
|
156
|
+
return true;
|
|
158
157
|
}
|
|
159
158
|
|
|
160
159
|
///////////////////////////////////////////////////////////////////////////////
|