littlejsengine 1.11.13 → 1.12.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/dist/littlejs.d.ts +1418 -109
- package/dist/littlejs.esm.js +3495 -581
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +3258 -399
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +3147 -379
- package/examples/box2d/game.js +73 -45
- package/examples/box2d/gameObjects.js +96 -92
- package/examples/box2d/index.html +2 -7
- package/examples/box2d/scenes.js +82 -92
- package/examples/breakout/game.js +62 -30
- package/examples/breakout/gameObjects.js +45 -47
- package/examples/breakout/index.html +1 -5
- package/examples/breakoutTutorial/game.js +36 -29
- package/examples/breakoutTutorial/index.html +1 -3
- package/examples/empty/game.js +5 -2
- package/examples/empty/index.html +1 -3
- package/examples/htmlMenu/game.js +25 -19
- package/examples/htmlMenu/index.html +5 -7
- package/examples/index.html +2 -3
- package/examples/module/game.js +32 -34
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +27 -22
- package/examples/platformer/game.js +71 -48
- package/examples/platformer/gameCharacter.js +42 -34
- package/examples/platformer/gameEffects.js +82 -75
- package/examples/platformer/gameLevel.js +67 -38
- package/examples/platformer/{gameLevelData.js → gameLevelData.json} +1 -11
- package/examples/platformer/gameObjects.js +70 -64
- package/examples/platformer/gamePlayer.js +12 -7
- package/examples/platformer/index.html +1 -9
- package/examples/puzzle/game.js +58 -42
- package/examples/puzzle/index.html +1 -3
- package/examples/shorts/base.html +2 -2
- package/examples/shorts/particles.js +1 -1
- package/examples/shorts/platformer.js +1 -1
- package/examples/shorts/tileLayer.js +5 -6
- package/examples/shorts/tiles.png +0 -0
- package/examples/starter/build.js +4 -4
- package/examples/starter/game.js +9 -12
- package/examples/starter/index.html +13 -13
- package/examples/stress/index.html +44 -43
- package/examples/typescript/build.js +17 -18
- package/examples/typescript/game.js +32 -34
- package/examples/typescript/game.ts +32 -34
- package/examples/typescript/index.html +1 -1
- package/examples/uiSystem/game.js +33 -36
- package/examples/uiSystem/index.html +1 -5
- package/package.json +3 -3
- package/plugins/box2d.js +1556 -640
- package/plugins/{Box2D_v2.3.1_min.wasm.js → box2d.wasm.js} +1 -1
- package/plugins/newgrounds.js +7 -8
- package/plugins/pluginExport.js +50 -0
- package/plugins/postProcess.js +94 -93
- package/plugins/uiSystem.js +145 -161
- package/plugins/zzfxm.js +163 -0
- package/reference.md +29 -27
- package/src/engine.js +15 -20
- package/src/engineAudio.js +74 -204
- package/src/engineBuild.js +29 -4
- package/src/engineDebug.js +105 -9
- package/src/engineDraw.js +27 -14
- package/src/engineExport.js +12 -8
- package/src/engineInput.js +3 -1
- package/src/engineObject.js +18 -14
- package/src/engineParticles.js +6 -1
- package/src/engineRelease.js +6 -1
- package/src/engineSettings.js +8 -8
- package/src/engineTileLayer.js +179 -96
- package/src/engineUtilities.js +5 -11
- package/src/engineWebGL.js +19 -7
- package/examples/starter/build/index.html +0 -2
- package/examples/starter/build/index.js +0 -1
- package/examples/starter/build/tiles.png +0 -0
- package/examples/starter/game.zip +0 -0
- package/examples/typescript/build/dist/littlejs.esm.js +0 -4834
- package/examples/typescript/build/examples/typescript/build.js +0 -24
- package/examples/typescript/build/examples/typescript/game.js +0 -102
- /package/plugins/{Box2D_v2.3.1_min.wasm.wasm → box2d.wasm.wasm} +0 -0
package/examples/box2d/game.js
CHANGED
|
@@ -11,25 +11,54 @@
|
|
|
11
11
|
|
|
12
12
|
'use strict';
|
|
13
13
|
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
// import LittleJS module
|
|
15
|
+
import * as LJS from '../../dist/littlejs.esm.js';
|
|
16
|
+
import * as GameObjects from './gameObjects.js';
|
|
17
|
+
import * as Scenes from './scenes.js';
|
|
18
|
+
const {vec2, hsl} = LJS;
|
|
17
19
|
|
|
20
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
18
21
|
// game variables
|
|
22
|
+
|
|
23
|
+
//LJS.box2dSetDebug(true); // enable box2d debug draw
|
|
24
|
+
|
|
19
25
|
const maxScenes = 11;
|
|
20
|
-
let scene = 0;
|
|
21
|
-
let
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
export let scene = 0, sceneName;
|
|
27
|
+
export let spriteAtlas, groundObject, car, mouseJoint, repeatSpawnTimer = new LJS.Timer;
|
|
28
|
+
const sound_click = new LJS.Sound([.2,.1,,,,.01,,,,,,,,,,,,,,,-500]);
|
|
29
|
+
|
|
30
|
+
export function setSceneName(name) { sceneName = name; }
|
|
31
|
+
export function setCarObject(carObject) { car = carObject; }
|
|
32
|
+
|
|
33
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
34
|
+
function setScene(_scene)
|
|
35
|
+
{
|
|
36
|
+
scene = _scene;
|
|
37
|
+
|
|
38
|
+
// setup
|
|
39
|
+
LJS.setCameraPos(vec2(20,10));
|
|
40
|
+
LJS.setGravity(vec2(0,-20));
|
|
41
|
+
|
|
42
|
+
// destroy old scene
|
|
43
|
+
LJS.engineObjectsDestroy();
|
|
44
|
+
mouseJoint = 0;
|
|
45
|
+
car = 0;
|
|
46
|
+
|
|
47
|
+
// create walls
|
|
48
|
+
groundObject = GameObjects.spawnBox(vec2(0,-4), vec2(1e3,8), hsl(0,0,.2), LJS.box2d.bodyTypeStatic);
|
|
49
|
+
GameObjects.spawnBox(vec2(-4, 0), vec2(8,1e3), LJS.BLACK, LJS.box2d.bodyTypeStatic);
|
|
50
|
+
GameObjects.spawnBox(vec2(44, 0), vec2(8,1e3), LJS.BLACK, LJS.box2d.bodyTypeStatic);
|
|
51
|
+
GameObjects.spawnBox(vec2(0,100), vec2(1e3,8), LJS.BLACK, LJS.box2d.bodyTypeStatic);
|
|
52
|
+
|
|
53
|
+
// load the scene
|
|
54
|
+
Scenes.loadScene(scene);
|
|
55
|
+
}
|
|
27
56
|
|
|
28
57
|
///////////////////////////////////////////////////////////////////////////////
|
|
29
58
|
function gameInit()
|
|
30
59
|
{
|
|
31
60
|
// create a table of all sprites
|
|
32
|
-
const gameTile = (i)=>
|
|
61
|
+
const gameTile = (i)=> LJS.tile(i, 16, 0, 1);
|
|
33
62
|
spriteAtlas =
|
|
34
63
|
{
|
|
35
64
|
circle: gameTile(0),
|
|
@@ -41,65 +70,64 @@ function gameInit()
|
|
|
41
70
|
squareOutline2: gameTile(6),
|
|
42
71
|
};
|
|
43
72
|
|
|
44
|
-
|
|
73
|
+
setScene(scene);
|
|
45
74
|
}
|
|
46
75
|
|
|
47
76
|
///////////////////////////////////////////////////////////////////////////////
|
|
48
77
|
function gameUpdate()
|
|
49
78
|
{
|
|
50
79
|
// scale canvas to fit based on 1080p
|
|
51
|
-
|
|
80
|
+
LJS.setCameraScale(LJS.mainCanvasSize.y * 48 / 1080);
|
|
52
81
|
|
|
53
82
|
// mouse controls
|
|
54
|
-
if (mouseWasPressed(0))
|
|
83
|
+
if (LJS.mouseWasPressed(0))
|
|
55
84
|
{
|
|
56
85
|
// grab object
|
|
57
|
-
sound_click.play(mousePos);
|
|
58
|
-
const object =
|
|
86
|
+
sound_click.play(LJS.mousePos);
|
|
87
|
+
const object = LJS.box2d.pointCast(LJS.mousePos);
|
|
59
88
|
if (object)
|
|
60
|
-
mouseJoint =
|
|
89
|
+
mouseJoint = new LJS.Box2dTargetJoint(object, groundObject, LJS.mousePos);
|
|
61
90
|
}
|
|
62
|
-
if (mouseWasReleased(0))
|
|
91
|
+
if (LJS.mouseWasReleased(0))
|
|
63
92
|
{
|
|
64
93
|
// release object
|
|
65
|
-
sound_click.play(mousePos, 1, .5);
|
|
94
|
+
sound_click.play(LJS.mousePos, 1, .5);
|
|
66
95
|
if (mouseJoint)
|
|
67
96
|
{
|
|
68
|
-
|
|
97
|
+
mouseJoint.destroy();
|
|
69
98
|
mouseJoint = 0;
|
|
70
99
|
}
|
|
71
100
|
}
|
|
72
|
-
if (mouseIsDown(1) || mouseIsDown('KeyZ'))
|
|
101
|
+
if (LJS.mouseIsDown(1) || LJS.mouseIsDown('KeyZ'))
|
|
73
102
|
{
|
|
74
103
|
const isSet = repeatSpawnTimer.isSet();
|
|
75
104
|
if (!isSet || repeatSpawnTimer.elapsed())
|
|
76
105
|
{
|
|
77
106
|
// spawn continuously after a delay
|
|
78
107
|
isSet || repeatSpawnTimer.set(.5);
|
|
79
|
-
spawnRandomObject(mousePos);
|
|
108
|
+
GameObjects.spawnRandomObject(LJS.mousePos);
|
|
80
109
|
}
|
|
81
110
|
}
|
|
82
111
|
else
|
|
83
112
|
repeatSpawnTimer.unset();
|
|
84
|
-
if (mouseWasPressed(2) || keyWasPressed('KeyX'))
|
|
85
|
-
explosion(mousePos);
|
|
113
|
+
if (LJS.mouseWasPressed(2) || LJS.keyWasPressed('KeyX'))
|
|
114
|
+
GameObjects.explosion(LJS.mousePos);
|
|
86
115
|
if (mouseJoint)
|
|
87
|
-
mouseJoint.
|
|
116
|
+
mouseJoint.setTarget(LJS.mousePos);
|
|
88
117
|
|
|
89
|
-
if (keyWasPressed('KeyR'))
|
|
90
|
-
|
|
91
|
-
if (keyWasPressed('ArrowUp') || keyWasPressed('ArrowDown'))
|
|
118
|
+
if (LJS.keyWasPressed('KeyR'))
|
|
119
|
+
setScene(scene); // reset scene
|
|
120
|
+
if (LJS.keyWasPressed('ArrowUp') || LJS.keyWasPressed('ArrowDown'))
|
|
92
121
|
{
|
|
93
122
|
// change scene
|
|
94
|
-
scene += keyWasPressed('ArrowUp') ? 1 : -1;
|
|
95
|
-
scene = mod(scene, maxScenes);
|
|
96
|
-
|
|
123
|
+
scene += LJS.keyWasPressed('ArrowUp') ? 1 : -1;
|
|
124
|
+
scene = LJS.mod(scene, maxScenes);
|
|
125
|
+
setScene(scene);
|
|
97
126
|
}
|
|
98
|
-
|
|
99
127
|
if (car)
|
|
100
128
|
{
|
|
101
|
-
// update car
|
|
102
|
-
const input = keyDirection();
|
|
129
|
+
// update car controls
|
|
130
|
+
const input = LJS.keyDirection();
|
|
103
131
|
car.applyMotorInput(-input.x);
|
|
104
132
|
}
|
|
105
133
|
}
|
|
@@ -114,7 +142,7 @@ function gameUpdatePost()
|
|
|
114
142
|
function gameRender()
|
|
115
143
|
{
|
|
116
144
|
// draw a grey square in the background without using webgl
|
|
117
|
-
drawRect(vec2(20,8), vec2(100), hsl(0,0,.8), 0, 0);
|
|
145
|
+
LJS.drawRect(vec2(20,8), vec2(100), hsl(0,0,.8), 0, 0);
|
|
118
146
|
|
|
119
147
|
if (scene == 5)
|
|
120
148
|
{
|
|
@@ -123,11 +151,11 @@ function gameRender()
|
|
|
123
151
|
const distance = 10;
|
|
124
152
|
for (let i=count;i--;)
|
|
125
153
|
{
|
|
126
|
-
const start = mousePos;
|
|
127
|
-
const end =
|
|
128
|
-
const result =
|
|
154
|
+
const start = LJS.mousePos;
|
|
155
|
+
const end = start.add(vec2(distance,0).rotate(i/count*LJS.PI*2));
|
|
156
|
+
const result = LJS.box2d.raycast(start, end);
|
|
129
157
|
const color = result ? hsl(0,1,.5,.5) : hsl(.5,1,.5,.5);
|
|
130
|
-
drawLine(start, result ? result.point : end, .1, color);
|
|
158
|
+
LJS.drawLine(start, result ? result.point : end, .1, color);
|
|
131
159
|
}
|
|
132
160
|
}
|
|
133
161
|
}
|
|
@@ -138,13 +166,13 @@ function gameRenderPost()
|
|
|
138
166
|
if (mouseJoint)
|
|
139
167
|
{
|
|
140
168
|
// draw mouse joint
|
|
141
|
-
const ab =
|
|
142
|
-
drawTile(ab, vec2(.3), spriteAtlas.circle, BLACK);
|
|
143
|
-
drawLine(mousePos, ab, .1, BLACK);
|
|
169
|
+
const ab = mouseJoint.getAnchorB();
|
|
170
|
+
LJS.drawTile(ab, vec2(.3), spriteAtlas.circle, LJS.BLACK);
|
|
171
|
+
LJS.drawLine(LJS.mousePos, ab, .1, LJS.BLACK);
|
|
144
172
|
}
|
|
145
173
|
|
|
146
174
|
// draw to overlay canvas for hud rendering
|
|
147
|
-
const pos = vec2(mainCanvasSize.x/2, 50);
|
|
175
|
+
const pos = vec2(LJS.mainCanvasSize.x/2, 50);
|
|
148
176
|
drawText('LittleJS Box2D Demo', 80, 80);
|
|
149
177
|
drawText(sceneName, 60, 100);
|
|
150
178
|
if (scene == 0)
|
|
@@ -161,10 +189,10 @@ function gameRenderPost()
|
|
|
161
189
|
}
|
|
162
190
|
|
|
163
191
|
function drawText(text, size=40, gap=50)
|
|
164
|
-
{ drawTextScreen(text, pos, size, WHITE, size*.1); pos.y += gap; }
|
|
192
|
+
{ LJS.drawTextScreen(text, pos, size, LJS.WHITE, size*.1); pos.y += gap; }
|
|
165
193
|
}
|
|
166
194
|
|
|
167
195
|
///////////////////////////////////////////////////////////////////////////////
|
|
168
196
|
// Startup LittleJS Engine with Box2D
|
|
169
197
|
|
|
170
|
-
box2dEngineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
|
|
198
|
+
LJS.box2dEngineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, ['tiles.png']);
|
|
@@ -6,97 +6,102 @@
|
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
8
8
|
|
|
9
|
+
// import LittleJS module
|
|
10
|
+
import * as LJS from '../../dist/littlejs.esm.js';
|
|
11
|
+
import * as Game from './game.js';
|
|
12
|
+
const {vec2, hsl} = LJS;
|
|
13
|
+
|
|
9
14
|
///////////////////////////////////////////////////////////////////////////////
|
|
10
15
|
// spawn object functions
|
|
11
16
|
|
|
12
|
-
function spawnBox(pos, size=1, color=WHITE, type=
|
|
17
|
+
export function spawnBox(pos, size=1, color=LJS.WHITE, type=LJS.box2d.bodyTypeDynamic, applyTexture=true, angle=0)
|
|
13
18
|
{
|
|
14
19
|
size = typeof size == 'number' ? vec2(size) : size; // square
|
|
15
|
-
const o = new Box2dObject(pos, size, applyTexture && spriteAtlas.squareOutline, angle, color, type);
|
|
20
|
+
const o = new LJS.Box2dObject(pos, size, applyTexture && Game.spriteAtlas.squareOutline, angle, color, type);
|
|
16
21
|
o.drawSize = size.scale(1.02); // slightly enlarge to cover gaps
|
|
17
22
|
o.addBox(size);
|
|
18
23
|
return o;
|
|
19
24
|
}
|
|
20
25
|
|
|
21
|
-
function spawnCircle(pos, diameter=1, color=WHITE, type=
|
|
26
|
+
export function spawnCircle(pos, diameter=1, color=LJS.WHITE, type=LJS.box2d.bodyTypeDynamic, applyTexture=true, angle=0)
|
|
22
27
|
{
|
|
23
28
|
const size = vec2(diameter);
|
|
24
|
-
const o = new Box2dObject(pos, size, applyTexture && spriteAtlas.circleOutline, angle, color, type);
|
|
29
|
+
const o = new LJS.Box2dObject(pos, size, applyTexture && Game.spriteAtlas.circleOutline, angle, color, type);
|
|
25
30
|
o.addCircle(diameter);
|
|
26
31
|
return o;
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
function spawnRandomPoly(pos, diameter=1, color=WHITE, type=
|
|
34
|
+
export function spawnRandomPoly(pos, diameter=1, color=LJS.WHITE, type=LJS.box2d.bodyTypeDynamic, angle=0)
|
|
30
35
|
{
|
|
31
|
-
const o = new Box2dObject(pos, vec2(), 0, angle, color, type);
|
|
36
|
+
const o = new LJS.Box2dObject(pos, vec2(), 0, angle, color, type);
|
|
32
37
|
o.addRandomPoly(diameter);
|
|
33
38
|
return o;
|
|
34
39
|
}
|
|
35
40
|
|
|
36
|
-
function spawnRandomObject(pos, scale=1, type=
|
|
41
|
+
export function spawnRandomObject(pos, scale=1, type=LJS.box2d.bodyTypeDynamic, angle=0)
|
|
37
42
|
{
|
|
38
|
-
if (randInt(2))
|
|
43
|
+
if (LJS.randInt(2))
|
|
39
44
|
{
|
|
40
|
-
const size = vec2(scale*rand(.5,1), scale*rand(.5,1));
|
|
41
|
-
return spawnBox(pos, size, randColor(), type, true, angle);
|
|
45
|
+
const size = vec2(scale*LJS.rand(.5,1), scale*LJS.rand(.5,1));
|
|
46
|
+
return spawnBox(pos, size, LJS.randColor(), type, true, angle);
|
|
42
47
|
}
|
|
43
48
|
else
|
|
44
49
|
{
|
|
45
|
-
const diameter = scale*rand(.5,1);
|
|
46
|
-
return spawnCircle(pos, diameter, randColor(), type, true, angle);
|
|
50
|
+
const diameter = scale*LJS.rand(.5,1);
|
|
51
|
+
return spawnCircle(pos, diameter, LJS.randColor(), type, true, angle);
|
|
47
52
|
}
|
|
48
53
|
}
|
|
49
54
|
|
|
50
|
-
function spawnPyramid(pos, count)
|
|
55
|
+
export function spawnPyramid(pos, count)
|
|
51
56
|
{
|
|
52
57
|
for (let i=count+1;i--;)
|
|
53
58
|
for (let j=i;j--;)
|
|
54
|
-
spawnBox(pos.add(vec2(j-i/2+.5,count-i+.5)), 1, randColor());
|
|
59
|
+
spawnBox(pos.add(vec2(j-i/2+.5,count-i+.5)), 1, LJS.randColor());
|
|
55
60
|
}
|
|
56
61
|
|
|
57
|
-
function spawnDominoes(pos, count, size=vec2(.5,2))
|
|
62
|
+
export function spawnDominoes(pos, count, size=vec2(.5,2))
|
|
58
63
|
{
|
|
59
64
|
for (let i=count; i--;)
|
|
60
|
-
spawnBox(pos.add(vec2(i*size.y*.9,size.y/2)), size, randColor());
|
|
65
|
+
spawnBox(pos.add(vec2(i*size.y*.9,size.y/2)), size, LJS.randColor());
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
function spawnRandomEdges()
|
|
68
|
+
export function spawnRandomEdges()
|
|
64
69
|
{
|
|
65
70
|
// edge list along bottom
|
|
66
71
|
const edgePoints = [];
|
|
67
72
|
edgePoints.push(vec2(40,0));
|
|
68
73
|
for (let i=40, y=0; i--;)
|
|
69
|
-
edgePoints.push(vec2(i, y=clamp(y+rand(-2,2),0,5)));
|
|
74
|
+
edgePoints.push(vec2(i, y=LJS.clamp(y+LJS.rand(-2,2),0,5)));
|
|
70
75
|
edgePoints.push(vec2(0,0));
|
|
71
|
-
const o = new Box2dObject(vec2(), vec2(), 0, 0, BLACK,
|
|
76
|
+
const o = new LJS.Box2dObject(vec2(), vec2(), 0, 0, LJS.BLACK, LJS.box2d.bodyTypeStatic);
|
|
72
77
|
o.addEdgeList(edgePoints);
|
|
73
78
|
}
|
|
74
79
|
|
|
75
|
-
function spawnRope(startPos, count, angle=PI, color=WHITE, size=vec2(.3,1))
|
|
80
|
+
export function spawnRope(startPos, count, angle=PI, color=LJS.WHITE, size=vec2(.3,1))
|
|
76
81
|
{
|
|
77
|
-
let lastObject = groundObject;
|
|
82
|
+
let lastObject = Game.groundObject;
|
|
78
83
|
for (let i=0; i<count; ++i)
|
|
79
84
|
{
|
|
80
85
|
const pos = startPos.add(size.multiply(vec2(0,i+.5)).rotate(-angle));
|
|
81
|
-
const o = spawnBox(pos, size, color,
|
|
86
|
+
const o = spawnBox(pos, size, color, LJS.box2d.bodyTypeDynamic, false, angle);
|
|
82
87
|
o.setFilterData(2, 2);
|
|
83
88
|
const anchorPos = pos.add(vec2(0,-size.y/2).rotate(-angle));
|
|
84
|
-
|
|
89
|
+
new LJS.Box2dRevoluteJoint(lastObject, o, anchorPos);
|
|
85
90
|
lastObject = o;
|
|
86
91
|
}
|
|
87
92
|
const endPos = lastObject.localToWorld(vec2(0,-size.y/2));
|
|
88
|
-
|
|
93
|
+
new LJS.Box2dRopeJoint(Game.groundObject, lastObject, startPos, endPos);
|
|
89
94
|
return lastObject;
|
|
90
95
|
}
|
|
91
96
|
|
|
92
97
|
///////////////////////////////////////////////////////////////////////////////
|
|
93
98
|
|
|
94
99
|
// simple car vehicle using wheel joints
|
|
95
|
-
class CarObject extends Box2dObject
|
|
100
|
+
export class CarObject extends LJS.Box2dObject
|
|
96
101
|
{
|
|
97
102
|
constructor(pos)
|
|
98
103
|
{
|
|
99
|
-
super(pos, vec2(), 0, 0, randColor());
|
|
104
|
+
super(pos, vec2(), 0, 0, LJS.randColor());
|
|
100
105
|
const carPoints = [
|
|
101
106
|
vec2(-1.5,-.5),
|
|
102
107
|
vec2(1.5, -.5),
|
|
@@ -116,22 +121,22 @@ class CarObject extends Box2dObject
|
|
|
116
121
|
const damping = .7;
|
|
117
122
|
const frequencyHz = 4;
|
|
118
123
|
const maxTorque = 50;
|
|
119
|
-
const sprite = spriteAtlas.wheel;
|
|
124
|
+
const sprite = Game.spriteAtlas.wheel;
|
|
120
125
|
|
|
121
126
|
// create wheels
|
|
122
127
|
this.wheels = [];
|
|
123
128
|
const makeWheel = (pos, isMotor) =>
|
|
124
129
|
{
|
|
125
|
-
const wheel = new Box2dObject(pos, vec2(diameter), sprite);
|
|
130
|
+
const wheel = new LJS.Box2dObject(pos, vec2(diameter), sprite);
|
|
126
131
|
wheel.addCircle(diameter, vec2(), density, friction, restitution);
|
|
127
132
|
this.wheels.push(wheel);
|
|
128
|
-
const joint =
|
|
129
|
-
joint.
|
|
130
|
-
joint.
|
|
133
|
+
const joint = new LJS.Box2dWheelJoint(this, wheel);
|
|
134
|
+
joint.setSpringDampingRatio(damping);
|
|
135
|
+
joint.setSpringFrequencyHz(frequencyHz);
|
|
131
136
|
if (isMotor)
|
|
132
137
|
{
|
|
133
|
-
joint.
|
|
134
|
-
joint.
|
|
138
|
+
joint.setMaxMotorTorque(maxTorque);
|
|
139
|
+
joint.enableMotor(true);
|
|
135
140
|
this.wheelMotorJoint = joint;
|
|
136
141
|
}
|
|
137
142
|
}
|
|
@@ -144,9 +149,9 @@ class CarObject extends Box2dObject
|
|
|
144
149
|
{
|
|
145
150
|
const maxSpeed = 40;
|
|
146
151
|
const brakeAmount = .8;
|
|
147
|
-
let s = this.wheelMotorJoint.
|
|
148
|
-
s = input ? clamp(s + input, -maxSpeed, maxSpeed) : s * brakeAmount;
|
|
149
|
-
this.wheelMotorJoint.
|
|
152
|
+
let s = this.wheelMotorJoint.getMotorSpeed();
|
|
153
|
+
s = input ? LJS.clamp(s + input, -maxSpeed, maxSpeed) : s * brakeAmount;
|
|
154
|
+
this.wheelMotorJoint.setMotorSpeed(s);
|
|
150
155
|
}
|
|
151
156
|
destroy()
|
|
152
157
|
{
|
|
@@ -158,27 +163,27 @@ class CarObject extends Box2dObject
|
|
|
158
163
|
///////////////////////////////////////////////////////////////////////////////
|
|
159
164
|
|
|
160
165
|
// changes objects color when touched
|
|
161
|
-
class ContactTester extends Box2dObject
|
|
166
|
+
export class ContactTester extends LJS.Box2dObject
|
|
162
167
|
{
|
|
163
168
|
constructor(pos, size, color, contactColor, isCircle=true, isSensor=true)
|
|
164
169
|
{
|
|
165
|
-
super(pos, size, 0, 0, color,
|
|
170
|
+
super(pos, size, 0, 0, color, LJS.box2d.bodyTypeStatic);
|
|
166
171
|
isCircle ? this.addCircle(size.x) : this.addBox(size);
|
|
167
172
|
this.setSensor(isSensor);
|
|
168
173
|
this.contactColor = contactColor;
|
|
169
174
|
}
|
|
170
175
|
beginContact(other) { other.color = this.contactColor; }
|
|
171
|
-
endContact(other) { other.color = WHITE; }
|
|
176
|
+
endContact(other) { other.color = LJS.WHITE; }
|
|
172
177
|
}
|
|
173
178
|
|
|
174
179
|
///////////////////////////////////////////////////////////////////////////////
|
|
175
180
|
|
|
176
181
|
// balanced recursive mobile object with revolve joints
|
|
177
|
-
class MobileObject extends Box2dObject
|
|
182
|
+
export class MobileObject extends LJS.Box2dObject
|
|
178
183
|
{
|
|
179
184
|
constructor(anchor, w, h, depth)
|
|
180
185
|
{
|
|
181
|
-
super(anchor, vec2(w, h), 0, 0, randColor());
|
|
186
|
+
super(anchor, vec2(w, h), 0, 0, LJS.randColor());
|
|
182
187
|
this.addBox(vec2(h/4, h), vec2(0, -h/2));
|
|
183
188
|
this.childMobiles = [];
|
|
184
189
|
if (--depth)
|
|
@@ -190,7 +195,7 @@ class MobileObject extends Box2dObject
|
|
|
190
195
|
// spawn smaller mobiles attached to each side
|
|
191
196
|
const a = anchor.add(vec2( w/(i?2:-2), -h));
|
|
192
197
|
const o = new MobileObject(a, w/2, h, depth);
|
|
193
|
-
|
|
198
|
+
new LJS.Box2dRevoluteJoint(this, o, a);
|
|
194
199
|
this.childMobiles.push(o);
|
|
195
200
|
}
|
|
196
201
|
}
|
|
@@ -205,11 +210,11 @@ class MobileObject extends Box2dObject
|
|
|
205
210
|
///////////////////////////////////////////////////////////////////////////////
|
|
206
211
|
|
|
207
212
|
// pulley object renders a rope to connected point
|
|
208
|
-
class PulleyJointObjects extends Box2dObject
|
|
213
|
+
export class PulleyJointObjects extends LJS.Box2dObject
|
|
209
214
|
{
|
|
210
215
|
constructor(pos, size, color, connectionPos)
|
|
211
216
|
{
|
|
212
|
-
super(pos, size, spriteAtlas.squareOutline, 0, color);
|
|
217
|
+
super(pos, size, Game.spriteAtlas.squareOutline, 0, color);
|
|
213
218
|
this.addBox(size);
|
|
214
219
|
this.connectionPos = connectionPos;
|
|
215
220
|
}
|
|
@@ -217,7 +222,7 @@ class PulleyJointObjects extends Box2dObject
|
|
|
217
222
|
{
|
|
218
223
|
// draw rope
|
|
219
224
|
const topPos = this.localToWorld(vec2(0,this.size.y/2));
|
|
220
|
-
drawLine(topPos, this.connectionPos, .2, BLACK);
|
|
225
|
+
LJS.drawLine(topPos, this.connectionPos, .2, LJS.BLACK);
|
|
221
226
|
super.render();
|
|
222
227
|
}
|
|
223
228
|
}
|
|
@@ -225,22 +230,22 @@ class PulleyJointObjects extends Box2dObject
|
|
|
225
230
|
///////////////////////////////////////////////////////////////////////////////
|
|
226
231
|
|
|
227
232
|
// motor object renders a rope to connected point
|
|
228
|
-
class MotorJointObject extends Box2dObject
|
|
233
|
+
export class MotorJointObject extends LJS.Box2dObject
|
|
229
234
|
{
|
|
230
235
|
constructor(pos, size, color, otherObject)
|
|
231
236
|
{
|
|
232
|
-
super(pos, size, spriteAtlas.wheel, 0, color);
|
|
237
|
+
super(pos, size, Game.spriteAtlas.wheel, 0, color);
|
|
233
238
|
this.addCircle(size.x);
|
|
234
239
|
this.connectionPos = pos;
|
|
235
|
-
const joint =
|
|
236
|
-
joint.
|
|
237
|
-
joint.
|
|
240
|
+
const joint = new LJS.Box2dMotorJoint(otherObject, this);
|
|
241
|
+
joint.setMaxForce(500);
|
|
242
|
+
joint.setMaxTorque(500);
|
|
238
243
|
}
|
|
239
244
|
render()
|
|
240
245
|
{
|
|
241
246
|
// draw rope
|
|
242
247
|
const width = 2/(1+this.pos.distance(this.connectionPos));
|
|
243
|
-
drawLine(this.pos, this.connectionPos, width, BLACK);
|
|
248
|
+
LJS.drawLine(this.pos, this.connectionPos, width, LJS.BLACK);
|
|
244
249
|
super.render();
|
|
245
250
|
}
|
|
246
251
|
}
|
|
@@ -248,14 +253,14 @@ class MotorJointObject extends Box2dObject
|
|
|
248
253
|
///////////////////////////////////////////////////////////////////////////////
|
|
249
254
|
|
|
250
255
|
// soft body sim using grid of weld joints
|
|
251
|
-
class SoftBodyObject extends Box2dObject
|
|
256
|
+
export class SoftBodyObject extends LJS.Box2dObject
|
|
252
257
|
{
|
|
253
258
|
constructor(pos, scale, sizeCount, color)
|
|
254
259
|
{
|
|
255
260
|
super(pos, vec2());
|
|
256
261
|
const nodeSize = sizeCount.subtract(vec2(1));
|
|
257
262
|
const spacing = scale.divide(nodeSize);
|
|
258
|
-
const objectDiameter = min(spacing.x, spacing.y);
|
|
263
|
+
const objectDiameter = LJS.min(spacing.x, spacing.y);
|
|
259
264
|
this.sizeCount = sizeCount.copy();
|
|
260
265
|
|
|
261
266
|
// create nodes
|
|
@@ -266,7 +271,7 @@ class SoftBodyObject extends Box2dObject
|
|
|
266
271
|
const mass = .1;
|
|
267
272
|
const center = vec2(x-nodeSize.x/2, y-nodeSize.y/2);
|
|
268
273
|
const p = pos.add(center.multiply(spacing));
|
|
269
|
-
const o = new Box2dObject(p, vec2(objectDiameter*1.1), spriteAtlas.circle, 0, color);
|
|
274
|
+
const o = new LJS.Box2dObject(p, vec2(objectDiameter*1.1), Game.spriteAtlas.circle, 0, color);
|
|
270
275
|
o.addCircle(objectDiameter);
|
|
271
276
|
o.setMass(mass);
|
|
272
277
|
o.setAngularDamping(10);
|
|
@@ -281,7 +286,7 @@ class SoftBodyObject extends Box2dObject
|
|
|
281
286
|
const tryAddJoint = (xo, yo) =>
|
|
282
287
|
{
|
|
283
288
|
const o2 = this.getNode(x+xo, y+yo);
|
|
284
|
-
const joint = o2 ?
|
|
289
|
+
const joint = o2 ? new LJS.Box2dWeldJoint(o, o2) : 0;
|
|
285
290
|
o.joints.push(joint);
|
|
286
291
|
}
|
|
287
292
|
|
|
@@ -300,7 +305,7 @@ class SoftBodyObject extends Box2dObject
|
|
|
300
305
|
for (let y = 0; y < sy.y; ++y) poly.push(this.getNode(sx-1, y).pos);
|
|
301
306
|
for (let x = sx; x--;) poly.push(this.getNode(x, sy-1).pos);
|
|
302
307
|
for (let y = sy; y--;) poly.push(this.getNode(0, y).pos);
|
|
303
|
-
|
|
308
|
+
LJS.box2d.drawPoly(vec2(), 0, poly, LJS.BLACK)
|
|
304
309
|
}
|
|
305
310
|
getNode(x, y)
|
|
306
311
|
{
|
|
@@ -317,14 +322,14 @@ class SoftBodyObject extends Box2dObject
|
|
|
317
322
|
///////////////////////////////////////////////////////////////////////////////
|
|
318
323
|
|
|
319
324
|
// cloth sim using grid of rope joints
|
|
320
|
-
class ClothObject extends Box2dObject
|
|
325
|
+
export class ClothObject extends LJS.Box2dObject
|
|
321
326
|
{
|
|
322
327
|
constructor(pos, scale, sizeCount, color, maxJointStress=10)
|
|
323
328
|
{
|
|
324
|
-
super(pos, vec2(), 0, 0, color,
|
|
329
|
+
super(pos, vec2(), 0, 0, color, LJS.box2d.bodyTypeStatic);
|
|
325
330
|
const nodeSize = sizeCount.subtract(vec2(1));
|
|
326
331
|
const spacing = scale.divide(nodeSize);
|
|
327
|
-
const objectDiameter = min(spacing.x, spacing.y);
|
|
332
|
+
const objectDiameter = LJS.min(spacing.x, spacing.y);
|
|
328
333
|
this.sizeCount = sizeCount.copy();
|
|
329
334
|
this.maxJointStress = maxJointStress;
|
|
330
335
|
this.lineWidth = .1;
|
|
@@ -337,7 +342,7 @@ class ClothObject extends Box2dObject
|
|
|
337
342
|
const mass = .5;
|
|
338
343
|
const center = vec2(x-nodeSize.x/2, y-nodeSize.y/2);
|
|
339
344
|
const p = pos.add(center.multiply(spacing));
|
|
340
|
-
const o = new Box2dObject(p, vec2(.4), spriteAtlas.circle, 0, color);
|
|
345
|
+
const o = new LJS.Box2dObject(p, vec2(.4), Game.spriteAtlas.circle, 0, color);
|
|
341
346
|
o.addCircle(objectDiameter);
|
|
342
347
|
o.setFilterData(2, 2);
|
|
343
348
|
o.setLinearDamping(1);
|
|
@@ -357,7 +362,7 @@ class ClothObject extends Box2dObject
|
|
|
357
362
|
const tryAddJoint = (xo, yo) =>
|
|
358
363
|
{
|
|
359
364
|
const o2 = this.getNode(x2+xo, y+yo);
|
|
360
|
-
const joint = o2 ?
|
|
365
|
+
const joint = o2 ? new LJS.Box2dRopeJoint(o, o2) : 0;
|
|
361
366
|
o.joints.push(joint);
|
|
362
367
|
}
|
|
363
368
|
|
|
@@ -374,7 +379,7 @@ class ClothObject extends Box2dObject
|
|
|
374
379
|
tryAddJoint( d, 1);
|
|
375
380
|
|
|
376
381
|
// attach pin joint to top row
|
|
377
|
-
y ||
|
|
382
|
+
y || new LJS.Box2dPinJoint(this.getNode(x, y), this);
|
|
378
383
|
}
|
|
379
384
|
}
|
|
380
385
|
}
|
|
@@ -398,15 +403,15 @@ class ClothObject extends Box2dObject
|
|
|
398
403
|
const j = joints[i];
|
|
399
404
|
if (!j) continue;
|
|
400
405
|
|
|
401
|
-
const oA = j.
|
|
402
|
-
const oB = j.
|
|
406
|
+
const oA = j.getObjectA();
|
|
407
|
+
const oB = j.getObjectB();
|
|
403
408
|
const d2 = oA.pos.distanceSquared(oB.pos);
|
|
404
|
-
const maxLength2 = j.
|
|
405
|
-
const stress =
|
|
409
|
+
const maxLength2 = j.getMaxLength()**2;
|
|
410
|
+
const stress = j.getReactionForce(1).length();
|
|
406
411
|
if (stress > this.maxJointStress || d2 > maxLength2*4)
|
|
407
412
|
{
|
|
408
413
|
// remove stressed joint
|
|
409
|
-
|
|
414
|
+
j.destroy();
|
|
410
415
|
joints[i] = 0;
|
|
411
416
|
}
|
|
412
417
|
}
|
|
@@ -428,9 +433,9 @@ class ClothObject extends Box2dObject
|
|
|
428
433
|
for (const joint of o.joints)
|
|
429
434
|
{
|
|
430
435
|
if (!joint) continue;
|
|
431
|
-
const oA = joint.
|
|
432
|
-
const oB = joint.
|
|
433
|
-
drawLine(oA.pos, oB.pos, this.lineWidth, BLACK);
|
|
436
|
+
const oA = joint.getObjectA();
|
|
437
|
+
const oB = joint.getObjectB();
|
|
438
|
+
LJS.drawLine(oA.pos, oB.pos, this.lineWidth, LJS.BLACK);
|
|
434
439
|
}
|
|
435
440
|
}
|
|
436
441
|
}
|
|
@@ -444,43 +449,42 @@ class ClothObject extends Box2dObject
|
|
|
444
449
|
///////////////////////////////////////////////////////////////////////////////
|
|
445
450
|
// Effects
|
|
446
451
|
|
|
447
|
-
const
|
|
448
|
-
const sound_explosion = new Sound([.5,.2,72,.01,.01,.2,4,,,,,,,1,,.5,.1,.5,.02]);
|
|
452
|
+
const sound_explosion = new LJS.Sound([.5,.2,72,.01,.01,.2,4,,,,,,,1,,.5,.1,.5,.02]);
|
|
449
453
|
|
|
450
|
-
function explosion(pos, radius=3, strength=300)
|
|
454
|
+
export function explosion(pos, radius=3, strength=300)
|
|
451
455
|
{
|
|
452
456
|
sound_explosion.play(pos);
|
|
453
|
-
const objects =
|
|
454
|
-
const newColor = randColor();
|
|
457
|
+
const objects = LJS.box2d.circleCastAll(pos, (radius*2));
|
|
458
|
+
const newColor = LJS.randColor();
|
|
455
459
|
for (const o of objects)
|
|
456
460
|
{
|
|
457
|
-
const p = percent(o.pos.distance(pos), 2*radius, radius);
|
|
461
|
+
const p = LJS.percent(o.pos.distance(pos), 2*radius, radius);
|
|
458
462
|
const force = o.pos.subtract(pos).normalize(p*radius*strength);
|
|
459
463
|
o.applyForce(force);
|
|
460
464
|
o.color = newColor;
|
|
461
465
|
}
|
|
462
466
|
|
|
463
467
|
// smoke
|
|
464
|
-
new ParticleEmitter(
|
|
465
|
-
pos, 0,
|
|
466
|
-
radius/2, .2, 50*radius,
|
|
467
|
-
spriteAtlas.dot,
|
|
468
|
-
hsl(0,0,0), hsl(0,0,0),
|
|
469
|
-
hsl(0,0,0,0), hsl(0,0,0,0),
|
|
470
|
-
1, 1, 2, .1, .1,
|
|
471
|
-
.9, 1, -.5,
|
|
472
|
-
1, 0, 0, 0, 1e8
|
|
468
|
+
new LJS.ParticleEmitter(
|
|
469
|
+
pos, 0, // pos, angle
|
|
470
|
+
radius/2, .2, 50*radius, 3.14,// emitSize, emitTime, emitRate, emitCone
|
|
471
|
+
Game.spriteAtlas.dot, // tileInfo
|
|
472
|
+
hsl(0,0,0), hsl(0,0,0), // colorStartA, colorStartB
|
|
473
|
+
hsl(0,0,0,0), hsl(0,0,0,0), // colorEndA, colorEndB
|
|
474
|
+
1, 1, 2, .1, .1, // time, sizeStart, sizeEnd, speed, angleSpeed
|
|
475
|
+
.9, 1, -.5, 3.14, .1, // damp, angleDamp, gravity, particleCone, fade
|
|
476
|
+
1, 0, 0, 0, 1e8 // randomness, collide, additive, colorLinear, renderOrder
|
|
473
477
|
);
|
|
474
478
|
|
|
475
479
|
// fire
|
|
476
|
-
new ParticleEmitter(
|
|
480
|
+
new LJS.ParticleEmitter(
|
|
477
481
|
pos, 0, // pos, angle
|
|
478
|
-
radius, .1, 100*radius,
|
|
479
|
-
spriteAtlas.dot,
|
|
482
|
+
radius, .1, 100*radius, 3.14, // emitSize, emitTime, emitRate, emitCone
|
|
483
|
+
Game.spriteAtlas.dot, // tileInfo
|
|
480
484
|
hsl(0,1,.5), hsl(.15,1,.5), // colorStartA, colorStartB
|
|
481
485
|
hsl(0,1,.5,0), hsl(.1, 1,.5,0), // colorEndA, colorEndB
|
|
482
|
-
.7, 1, .5, .1, .1,
|
|
483
|
-
.9, 1, 0,
|
|
484
|
-
1, 0, 1, 0, 1e9
|
|
486
|
+
.7, 1, .5, .1, .1, // time, sizeStart, sizeEnd, speed, angleSpeed
|
|
487
|
+
.9, 1, 0, 3.14, .05, // damp, angleDamp, gravity, particleCone, fade
|
|
488
|
+
1, 0, 1, 0, 1e9 // randomness, collide, additive, colorLinear, renderOrder
|
|
485
489
|
);
|
|
486
|
-
}
|
|
490
|
+
}
|