littlejsengine 1.10.4 → 1.11.1
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/LittleJS.zip +0 -0
- package/README.md +8 -78
- package/dist/littlejs.d.ts +60 -25
- package/dist/littlejs.esm.js +164 -63
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +160 -62
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +160 -62
- package/examples/box2d/game.js +15 -4
- package/examples/box2d/gameObjects.js +10 -9
- package/examples/box2d/index.html +5 -5
- package/examples/box2d/scenes.js +4 -4
- package/examples/box2d/tiles.png +0 -0
- package/examples/breakout/index.html +3 -3
- package/examples/breakoutTutorial/index.html +2 -2
- package/examples/electron/game.js +3 -0
- package/examples/electron/index.html +2 -2
- package/examples/htmlMenu/index.html +3 -3
- package/examples/index.html +10 -3
- package/examples/js13k/game.js +3 -0
- package/examples/js13k/index.html +13 -13
- package/examples/module/game.js +4 -1
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +4 -1
- package/examples/platformer/game.js +19 -15
- package/examples/platformer/gameCharacter.js +3 -3
- package/examples/platformer/gameLevel.js +1 -0
- package/examples/platformer/index.html +8 -8
- package/examples/platformer/tiles.png +0 -0
- package/examples/puzzle/game.js +3 -2
- package/examples/puzzle/index.html +2 -2
- package/examples/starter/game.js +47 -10
- package/examples/starter/index.html +13 -13
- package/examples/starter/tiles.png +0 -0
- package/examples/stress/index.html +1 -1
- package/examples/typescript/game.js +2 -0
- package/examples/typescript/game.ts +3 -0
- package/examples/typescript/index.html +1 -1
- package/examples/uiSystem/game.js +23 -16
- package/examples/uiSystem/index.html +3 -14
- package/package.json +7 -2
- package/plugins/postProcess.js +2 -9
- package/plugins/uiSystem.js +85 -25
- package/reference.md +1 -1
- package/shortExamples/engine.html +71 -0
- package/shortExamples/index.html +47 -0
- package/shortExamples/index.js +0 -0
- package/shortExamples/tiles.png +0 -0
- package/src/engine.js +14 -12
- package/src/engineAudio.js +6 -9
- package/src/engineDraw.js +23 -7
- package/src/engineExport.js +4 -1
- package/src/engineInput.js +7 -3
- package/src/engineMedals.js +19 -5
- package/src/engineObject.js +8 -5
- package/src/engineSettings.js +13 -2
- package/src/engineTileLayer.js +9 -8
- package/src/engineUtilities.js +59 -10
- package/src/engineWebGL.js +1 -1
- package/examples/js13k/build/index.html +0 -1
- package/examples/js13k/build/index.js +0 -1
- package/examples/js13k/build/tiles.png +0 -0
- package/examples/js13k/game - Copy.zip +0 -0
- package/examples/js13k/game.zip +0 -0
- 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/build/littlejs.esm.js +0 -4327
- package/examples/typescript/build/dist/littlejs.esm.js +0 -4425
- package/examples/typescript/build/examples/typescript/build.js +0 -24
- package/examples/typescript/build/examples/typescript/game.js +0 -100
- package/examples/typescript/build/examples/typescript/test/build/littlejs.esm.js +0 -3934
- package/examples/typescript/build/examples/typescript/test/examples/typescript/build.js +0 -86
- package/examples/typescript/build/examples/typescript/test/examples/typescript/game.js +0 -92
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
setShowSplashScreen(true);
|
|
11
11
|
|
|
12
12
|
// sound effects
|
|
13
|
-
const
|
|
13
|
+
const sound_ui = new Sound([1,0]);
|
|
14
14
|
|
|
15
15
|
// UI system
|
|
16
16
|
let uiRoot, uiMenu;
|
|
@@ -20,7 +20,7 @@ const setMenuVisible =(visible)=> uiMenu.visible = visible;
|
|
|
20
20
|
function createUI()
|
|
21
21
|
{
|
|
22
22
|
// setup root to attach all ui elements to
|
|
23
|
-
uiRoot = new UIObject(
|
|
23
|
+
uiRoot = new UIObject();
|
|
24
24
|
const uiInfo = new UIText(vec2(0,50), vec2(1e3, 70),
|
|
25
25
|
'LittleJS UI System Example\nM = Toggle menu');
|
|
26
26
|
uiInfo.textColor = WHITE;
|
|
@@ -30,54 +30,61 @@ function createUI()
|
|
|
30
30
|
// setup example menu
|
|
31
31
|
uiMenu = new UIObject(vec2(0,450));
|
|
32
32
|
uiRoot.addChild(uiMenu);
|
|
33
|
-
const uiBackground = new UIObject(vec2(0,0), vec2(450,
|
|
33
|
+
const uiBackground = new UIObject(vec2(0,0), vec2(450,580));
|
|
34
34
|
uiMenu.addChild(uiBackground);
|
|
35
35
|
|
|
36
36
|
// example large text
|
|
37
|
-
const textTitle = new UIText(vec2(0,-
|
|
37
|
+
const textTitle = new UIText(vec2(0,-220), vec2(500, 90), 'Test Title');
|
|
38
38
|
uiMenu.addChild(textTitle);
|
|
39
39
|
textTitle.textColor = RED;
|
|
40
40
|
textTitle.lineWidth = 4;
|
|
41
41
|
textTitle.lineColor = BLUE;
|
|
42
42
|
|
|
43
43
|
// example multiline text
|
|
44
|
-
const textTest = new UIText(vec2(-60,-
|
|
44
|
+
const textTest = new UIText(vec2(-60,-140), vec2(300, 50), 'Test Text\nSecond text line.')
|
|
45
45
|
uiMenu.addChild(textTest);
|
|
46
46
|
|
|
47
47
|
// example tile image
|
|
48
|
-
const tileTest = new UITile(vec2(150,-
|
|
48
|
+
const tileTest = new UITile(vec2(150,-130), vec2(110), tile(3,128))
|
|
49
49
|
uiMenu.addChild(tileTest);
|
|
50
50
|
|
|
51
51
|
// example checkbox
|
|
52
|
-
const checkbox = new UICheckbox(vec2(-
|
|
52
|
+
const checkbox = new UICheckbox(vec2(-140,-20), vec2(40));
|
|
53
53
|
uiMenu.addChild(checkbox);
|
|
54
|
-
checkbox.
|
|
54
|
+
checkbox.onPress = ()=>
|
|
55
55
|
{
|
|
56
56
|
checkbox.checked = !checkbox.checked;
|
|
57
57
|
console.log('Checkbox clicked');
|
|
58
|
-
|
|
58
|
+
sound_ui.play(0,.5,checkbox.checked?4:1);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// text attached to checkbox
|
|
62
|
-
const checkboxText = new UIText(vec2(
|
|
62
|
+
const checkboxText = new UIText(vec2(170,0), vec2(300, 40), 'Test Checkbox');
|
|
63
63
|
checkbox.addChild(checkboxText);
|
|
64
64
|
|
|
65
|
+
// example scrollbar
|
|
66
|
+
const scrollbar = new UIScrollbar(vec2(0,60), vec2(350, 50));
|
|
67
|
+
uiMenu.addChild(scrollbar);
|
|
68
|
+
scrollbar.onChange = ()=> console.log('New scrollbar value:', scrollbar.value);
|
|
69
|
+
scrollbar.onPress = ()=> sound_ui.play(0,.3,2);
|
|
70
|
+
scrollbar.onRelease = ()=> sound_ui.play(0,.3,4);
|
|
71
|
+
|
|
65
72
|
// example button
|
|
66
|
-
const button1 = new UIButton(vec2(0,
|
|
73
|
+
const button1 = new UIButton(vec2(0,140), vec2(350, 50), 'Test Button');
|
|
67
74
|
uiMenu.addChild(button1);
|
|
68
|
-
button1.
|
|
75
|
+
button1.onPress = ()=>
|
|
69
76
|
{
|
|
70
77
|
console.log('Button 1 clicked');
|
|
71
|
-
|
|
78
|
+
sound_ui.play();
|
|
72
79
|
}
|
|
73
80
|
|
|
74
81
|
// exit button
|
|
75
|
-
const button2 = new UIButton(vec2(0,
|
|
82
|
+
const button2 = new UIButton(vec2(0,220), vec2(350, 50), 'Exit Menu');
|
|
76
83
|
uiMenu.addChild(button2);
|
|
77
|
-
button2.
|
|
84
|
+
button2.onPress = ()=>
|
|
78
85
|
{
|
|
79
86
|
console.log('Button 2 clicked');
|
|
80
|
-
|
|
87
|
+
sound_ui.play(0,.5,2);
|
|
81
88
|
setMenuVisible(false);
|
|
82
89
|
}
|
|
83
90
|
}
|
|
@@ -7,19 +7,8 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../
|
|
11
|
-
<script src=../../src/engineUtilities.js?1100></script>
|
|
12
|
-
<script src=../../src/engineSettings.js?1100></script>
|
|
13
|
-
<script src=../../src/engineObject.js?1100></script>
|
|
14
|
-
<script src=../../src/engineDraw.js?1100></script>
|
|
15
|
-
<script src=../../src/engineInput.js?1100></script>
|
|
16
|
-
<script src=../../src/engineAudio.js?1100></script>
|
|
17
|
-
<script src=../../src/engineTileLayer.js?1100></script>
|
|
18
|
-
<script src=../../src/engineParticles.js?1100></script>
|
|
19
|
-
<script src=../../src/engineMedals.js?1100></script>
|
|
20
|
-
<script src=../../src/engineWebGL.js?1100></script>
|
|
21
|
-
<script src=../../src/engine.js?1100></script>
|
|
10
|
+
<script src=../../dist/littlejs.js?1105></script>
|
|
22
11
|
|
|
23
12
|
<!-- Add your game scripts here -->
|
|
24
|
-
<script src=../../plugins/uiSystem.js?
|
|
25
|
-
<script src=game.js?
|
|
13
|
+
<script src=../../plugins/uiSystem.js?1105></script>
|
|
14
|
+
<script src=game.js?1105></script>
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "littlejsengine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.1",
|
|
4
4
|
"description": "LittleJS - Tiny and Fast HTML5 Game Engine",
|
|
5
|
-
"main": "dist/littlejs.esm.js",
|
|
5
|
+
"main": "dist/littlejs.esm.min.js",
|
|
6
6
|
"types": "dist/littlejs.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
"types": "./dist/littlejs.d.ts",
|
|
9
|
+
"production": "./dist/littlejs.esm.min.js",
|
|
10
|
+
"default": "./dist/littlejs.esm.js"
|
|
11
|
+
},
|
|
7
12
|
"repository": {
|
|
8
13
|
"type": "git",
|
|
9
14
|
"url": "git+https://github.com/KilledByAPixel/LittleJS.git"
|
package/plugins/postProcess.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* LittleJS Post Processing Plugin
|
|
3
3
|
* - Supports shadertoy style post processing shaders
|
|
4
|
-
* - call
|
|
4
|
+
* - call initPostProcess to set it up
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
'use strict';
|
|
@@ -98,11 +98,4 @@ function initPostProcess(shaderCode, includeOverlay=false)
|
|
|
98
98
|
glContext.uniform3f(uniformLocation('iResolution'), mainCanvas.width, mainCanvas.height, 1);
|
|
99
99
|
glContext.drawArrays(gl_TRIANGLE_STRIP, 0, 4);
|
|
100
100
|
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export {
|
|
104
|
-
initPostProcess,
|
|
105
|
-
glPostShader,
|
|
106
|
-
glPostTexture,
|
|
107
|
-
glPostIncludeOverlay
|
|
108
|
-
};
|
|
101
|
+
}
|
package/plugins/uiSystem.js
CHANGED
|
@@ -40,7 +40,7 @@ function initUISystem(context=overlayContext)
|
|
|
40
40
|
o.pos = o.localPos.add(o.parent.pos);
|
|
41
41
|
o.update();
|
|
42
42
|
for(const c of o.children)
|
|
43
|
-
updateObject(c)
|
|
43
|
+
updateObject(c);
|
|
44
44
|
}
|
|
45
45
|
uiObjects.forEach(o=> o.parent || updateObject(o));
|
|
46
46
|
}
|
|
@@ -50,9 +50,11 @@ function initUISystem(context=overlayContext)
|
|
|
50
50
|
{
|
|
51
51
|
if (!o.visible)
|
|
52
52
|
return;
|
|
53
|
+
if (o.parent)
|
|
54
|
+
o.pos = o.localPos.add(o.parent.pos);
|
|
53
55
|
o.render();
|
|
54
56
|
for(const c of o.children)
|
|
55
|
-
renderObject(c)
|
|
57
|
+
renderObject(c);
|
|
56
58
|
}
|
|
57
59
|
uiObjects.forEach(o=> o.parent || renderObject(o));
|
|
58
60
|
}
|
|
@@ -82,21 +84,21 @@ function drawUILine(posA, posB, thickness=uiDefaultLineWidth, color=uiDefaultLin
|
|
|
82
84
|
uiContext.stroke();
|
|
83
85
|
}
|
|
84
86
|
|
|
85
|
-
function drawUITile(pos, size, tileInfo, color=uiDefaultColor, angle=0, mirror=false
|
|
87
|
+
function drawUITile(pos, size, tileInfo, color=uiDefaultColor, angle=0, mirror=false)
|
|
86
88
|
{
|
|
87
|
-
drawTile(pos, size, tileInfo, color, angle, mirror,
|
|
89
|
+
drawTile(pos, size, tileInfo, color, angle, mirror, BLACK, false, true, uiContext);
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
function drawUIText(text, pos, size, color=uiDefaultColor, lineWidth=uiDefaultLineWidth, lineColor=uiDefaultLineColor, align='center', font=uiDefaultFont)
|
|
91
93
|
{
|
|
92
|
-
drawTextScreen(text, pos, size.y, color, lineWidth, lineColor, align, font,
|
|
94
|
+
drawTextScreen(text, pos, size.y, color, lineWidth, lineColor, align, font, size.x, uiContext);
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
///////////////////////////////////////////////////////////////////////////////
|
|
96
98
|
|
|
97
99
|
class UIObject
|
|
98
100
|
{
|
|
99
|
-
constructor(localPos, size=vec2())
|
|
101
|
+
constructor(localPos=vec2(), size=vec2())
|
|
100
102
|
{
|
|
101
103
|
this.localPos = localPos.copy();
|
|
102
104
|
this.pos = localPos.copy();
|
|
@@ -131,21 +133,28 @@ class UIObject
|
|
|
131
133
|
{
|
|
132
134
|
// track mouse input
|
|
133
135
|
const mouseWasOver = this.mouseIsOver;
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
const mouseDown = mouseIsDown(0);
|
|
137
|
+
if (!mouseDown || isTouchDevice)
|
|
138
|
+
{
|
|
139
|
+
this.mouseIsOver = isOverlapping(this.pos, this.size, mousePosScreen);
|
|
140
|
+
if (!mouseDown && isTouchDevice)
|
|
141
|
+
this.mouseIsOver = false;
|
|
142
|
+
if (this.mouseIsOver && !mouseWasOver)
|
|
143
|
+
this.onEnter();
|
|
144
|
+
if (!this.mouseIsOver && mouseWasOver)
|
|
145
|
+
this.onLeave();
|
|
146
|
+
}
|
|
139
147
|
if (mouseWasPressed(0) && this.mouseIsOver)
|
|
140
148
|
{
|
|
141
149
|
this.mouseIsHeld = true;
|
|
142
150
|
this.onPress();
|
|
151
|
+
if (isTouchDevice)
|
|
152
|
+
this.mouseIsOver = false;
|
|
143
153
|
}
|
|
144
|
-
else if (this.mouseIsHeld && !
|
|
154
|
+
else if (this.mouseIsHeld && !mouseDown)
|
|
145
155
|
{
|
|
146
156
|
this.mouseIsHeld = false;
|
|
147
|
-
|
|
148
|
-
this.onClick();
|
|
157
|
+
this.onRelease();
|
|
149
158
|
}
|
|
150
159
|
}
|
|
151
160
|
render()
|
|
@@ -155,17 +164,18 @@ class UIObject
|
|
|
155
164
|
}
|
|
156
165
|
|
|
157
166
|
// callback functions
|
|
158
|
-
onEnter()
|
|
159
|
-
onLeave()
|
|
160
|
-
onPress()
|
|
161
|
-
|
|
167
|
+
onEnter() {}
|
|
168
|
+
onLeave() {}
|
|
169
|
+
onPress() {}
|
|
170
|
+
onRelease() {}
|
|
171
|
+
onChange() {}
|
|
162
172
|
}
|
|
163
173
|
|
|
164
174
|
///////////////////////////////////////////////////////////////////////////////
|
|
165
175
|
|
|
166
176
|
class UIText extends UIObject
|
|
167
177
|
{
|
|
168
|
-
constructor(pos, size, text, align='center', font=fontDefault)
|
|
178
|
+
constructor(pos, size, text='', align='center', font=fontDefault)
|
|
169
179
|
{
|
|
170
180
|
super(pos, size);
|
|
171
181
|
|
|
@@ -184,7 +194,7 @@ class UIText extends UIObject
|
|
|
184
194
|
|
|
185
195
|
class UITile extends UIObject
|
|
186
196
|
{
|
|
187
|
-
constructor(pos, size, tileInfo, color=WHITE, angle=0, mirror=false
|
|
197
|
+
constructor(pos, size, tileInfo, color=WHITE, angle=0, mirror=false)
|
|
188
198
|
{
|
|
189
199
|
super(pos, size);
|
|
190
200
|
|
|
@@ -192,11 +202,10 @@ class UITile extends UIObject
|
|
|
192
202
|
this.color = color;
|
|
193
203
|
this.angle = angle;
|
|
194
204
|
this.mirror = mirror;
|
|
195
|
-
this.additiveColor = additiveColor;
|
|
196
205
|
}
|
|
197
206
|
render()
|
|
198
207
|
{
|
|
199
|
-
drawUITile(this.pos, this.size, this.tileInfo, this.color, this.angle, this.mirror
|
|
208
|
+
drawUITile(this.pos, this.size, this.tileInfo, this.color, this.angle, this.mirror);
|
|
200
209
|
}
|
|
201
210
|
}
|
|
202
211
|
|
|
@@ -215,8 +224,9 @@ class UIButton extends UIObject
|
|
|
215
224
|
const lineColor = this.mouseIsHeld ? this.color : this.lineColor;
|
|
216
225
|
const color = this.mouseIsOver? this.hoverColor : this.color;
|
|
217
226
|
drawUIRect(this.pos, this.size, color, this.lineWidth, lineColor);
|
|
218
|
-
|
|
219
|
-
|
|
227
|
+
const textSize = vec2(this.size.x, this.size.y*.8);
|
|
228
|
+
drawUIText(this.text, this.pos, textSize,
|
|
229
|
+
this.textColor, 0, undefined, this.align, this.font);
|
|
220
230
|
}
|
|
221
231
|
}
|
|
222
232
|
|
|
@@ -229,7 +239,11 @@ class UICheckbox extends UIObject
|
|
|
229
239
|
super(pos, size);
|
|
230
240
|
this.checked = checked;
|
|
231
241
|
}
|
|
232
|
-
|
|
242
|
+
onPress()
|
|
243
|
+
{
|
|
244
|
+
this.checked = !this.checked;
|
|
245
|
+
this.onChange();
|
|
246
|
+
}
|
|
233
247
|
render()
|
|
234
248
|
{
|
|
235
249
|
drawUIRect(this.pos, this.size, this.color, this.lineWidth, this.lineColor);
|
|
@@ -241,3 +255,49 @@ class UICheckbox extends UIObject
|
|
|
241
255
|
}
|
|
242
256
|
}
|
|
243
257
|
}
|
|
258
|
+
|
|
259
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
260
|
+
|
|
261
|
+
class UIScrollbar extends UIObject
|
|
262
|
+
{
|
|
263
|
+
constructor(pos, size, value=.5, text='')
|
|
264
|
+
{
|
|
265
|
+
super(pos, size);
|
|
266
|
+
this.value = value;
|
|
267
|
+
this.text = text;
|
|
268
|
+
this.color = uiDefaultButtonColor;
|
|
269
|
+
this.handleColor = WHITE;
|
|
270
|
+
}
|
|
271
|
+
update()
|
|
272
|
+
{
|
|
273
|
+
super.update();
|
|
274
|
+
if (this.mouseIsHeld)
|
|
275
|
+
{
|
|
276
|
+
const handleSize = vec2(this.size.y);
|
|
277
|
+
const handleWidth = this.size.x - handleSize.x;
|
|
278
|
+
const p1 = this.pos.x - handleWidth/2;
|
|
279
|
+
const p2 = this.pos.x + handleWidth/2;
|
|
280
|
+
const oldValue = this.value;
|
|
281
|
+
this.value = percent(mousePosScreen.x, p1, p2);
|
|
282
|
+
this.value == oldValue || this.onChange();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
render()
|
|
286
|
+
{
|
|
287
|
+
const lineColor = this.mouseIsHeld ? this.color : this.lineColor;
|
|
288
|
+
const color = this.mouseIsOver? this.hoverColor : this.color;
|
|
289
|
+
drawUIRect(this.pos, this.size, color, this.lineWidth, lineColor);
|
|
290
|
+
|
|
291
|
+
const handleSize = vec2(this.size.y);
|
|
292
|
+
const handleWidth = this.size.x - handleSize.x;
|
|
293
|
+
const p1 = this.pos.x - handleWidth/2;
|
|
294
|
+
const p2 = this.pos.x + handleWidth/2;
|
|
295
|
+
const handlePos = vec2(lerp(this.value, p1, p2), this.pos.y);
|
|
296
|
+
const barColor = this.mouseIsHeld ? this.color : this.handleColor;
|
|
297
|
+
drawUIRect(handlePos, handleSize, barColor, this.lineWidth, this.lineColor);
|
|
298
|
+
|
|
299
|
+
const textSize = vec2(this.size.x, this.size.y*.8);
|
|
300
|
+
drawUIText(this.text, this.pos, textSize,
|
|
301
|
+
this.textColor, 0, undefined, this.align, this.font);
|
|
302
|
+
}
|
|
303
|
+
}
|
package/reference.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
## This cheat sheet contains all LittleJS essentials.
|
|
4
4
|
- [LittleJS on GitHub](https://github.com/KilledByAPixel/LittleJS) - Official LittleJS website with more info
|
|
5
5
|
- [LittleJS Documentation](https://killedbyapixel.github.io/LittleJS/docs) - LittleJS documentation browser
|
|
6
|
-
- [Particle
|
|
6
|
+
- [Particle System Designer](https://killedbyapixel.github.io/LittleJS/examples/particles) - Editor for LittleJS Particle Systems
|
|
7
7
|
- [Sound Effect Designer](https://killedbyapixel.github.io/ZzFX) - Tool for creating ZzFX sound effects
|
|
8
8
|
- [Starter Project](https://killedbyapixel.github.io/LittleJS/examples/starter) - Simple LittleJS demo to start with
|
|
9
9
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<!DOCTYPE html><head>
|
|
2
|
+
<title>LittleJS Starter Project</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
|
+
</head><body>
|
|
8
|
+
|
|
9
|
+
<!-- LittleJS Engine -->
|
|
10
|
+
<script src=../src/engineDebug.js?1105></script>
|
|
11
|
+
<script src=../src/engineUtilities.js?1105></script>
|
|
12
|
+
<script src=../src/engineSettings.js?1105></script>
|
|
13
|
+
<script src=../src/engineObject.js?1105></script>
|
|
14
|
+
<script src=../src/engineDraw.js?1105></script>
|
|
15
|
+
<script src=../src/engineInput.js?1105></script>
|
|
16
|
+
<script src=../src/engineAudio.js?1105></script>
|
|
17
|
+
<script src=../src/engineTileLayer.js?1105></script>
|
|
18
|
+
<script src=../src/engineParticles.js?1105></script>
|
|
19
|
+
<script src=../src/engineMedals.js?1105></script>
|
|
20
|
+
<script src=../src/engineWebGL.js?1105></script>
|
|
21
|
+
<script src=../src/engine.js?1105></script>
|
|
22
|
+
|
|
23
|
+
<!-- Add your game scripts here -->
|
|
24
|
+
<script>
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
/*
|
|
30
|
+
Little JS Starter Project
|
|
31
|
+
- A simple starter project for LittleJS
|
|
32
|
+
- Demos all the main engine features
|
|
33
|
+
- Builds to a zip file
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
'use strict';
|
|
37
|
+
|
|
38
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
39
|
+
function gameInit()
|
|
40
|
+
{
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
45
|
+
function gameUpdate()
|
|
46
|
+
{
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
51
|
+
function gameUpdatePost()
|
|
52
|
+
{
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
57
|
+
function gameRender()
|
|
58
|
+
{
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
63
|
+
function gameRenderPost()
|
|
64
|
+
{
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
</script>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!DOCTYPE html><head>
|
|
2
|
+
<title>LittleJS Box2D 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
|
+
</head><body>
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
<iframe id=iframe src="engine.html"></iframe>
|
|
11
|
+
|
|
12
|
+
<script>
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
iframe.onload = function()
|
|
16
|
+
{
|
|
17
|
+
let iframeContent = iframe.contentWindow;
|
|
18
|
+
|
|
19
|
+
iframeContent.eval(`
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
function gameRender()
|
|
23
|
+
{
|
|
24
|
+
// draw to overlay canvas for hud rendering
|
|
25
|
+
drawTextScreen('TEST',
|
|
26
|
+
vec2(mainCanvasSize.x/2, 70), 80, // position, size
|
|
27
|
+
hsl(0,0,1), 6, hsl(0,0,0)); // color, outline size and color
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
`);
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
iframeContent.engineInit(iframeContent.gameInit, iframeContent.gameUpdate, iframeContent.gameUpdatePost, iframeContent.gameRender, iframeContent.gameRenderPost, ['tiles.png']);
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
iframe.src = './engine.html';
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
</body>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
</html>
|
|
File without changes
|
|
Binary file
|
package/src/engine.js
CHANGED
|
@@ -30,7 +30,7 @@ const engineName = 'LittleJS';
|
|
|
30
30
|
* @type {String}
|
|
31
31
|
* @default
|
|
32
32
|
* @memberof Engine */
|
|
33
|
-
const engineVersion = '1.
|
|
33
|
+
const engineVersion = '1.11.1';
|
|
34
34
|
|
|
35
35
|
/** Frames per second to update
|
|
36
36
|
* @type {Number}
|
|
@@ -93,6 +93,8 @@ const pluginUpdateList = [], pluginRenderList = [];
|
|
|
93
93
|
* @memberof Engine */
|
|
94
94
|
function engineAddPlugin(updateFunction, renderFunction)
|
|
95
95
|
{
|
|
96
|
+
ASSERT(!pluginUpdateList.includes(updateFunction));
|
|
97
|
+
ASSERT(!pluginRenderList.includes(renderFunction));
|
|
96
98
|
updateFunction && pluginUpdateList.push(updateFunction);
|
|
97
99
|
renderFunction && pluginRenderList.push(renderFunction);
|
|
98
100
|
}
|
|
@@ -101,12 +103,12 @@ function engineAddPlugin(updateFunction, renderFunction)
|
|
|
101
103
|
// Main engine functions
|
|
102
104
|
|
|
103
105
|
/** Startup LittleJS engine with your callback functions
|
|
104
|
-
* @param {Function} gameInit
|
|
105
|
-
* @param {Function} gameUpdate
|
|
106
|
-
* @param {Function} gameUpdatePost - Called after physics and objects are updated,
|
|
107
|
-
* @param {Function} gameRender
|
|
108
|
-
* @param {Function} gameRenderPost - Called after objects are rendered,
|
|
109
|
-
* @param {Array} [imageSources=[]] -
|
|
106
|
+
* @param {Function|function():Promise} gameInit - Called once after the engine starts up
|
|
107
|
+
* @param {Function} gameUpdate - Called every frame before objects are updated
|
|
108
|
+
* @param {Function} gameUpdatePost - Called after physics and objects are updated, even when paused
|
|
109
|
+
* @param {Function} gameRender - Called before objects are rendered, for drawing the background
|
|
110
|
+
* @param {Function} gameRenderPost - Called after objects are rendered, useful for drawing UI
|
|
111
|
+
* @param {Array} [imageSources=[]] - List of images to load
|
|
110
112
|
* @param {HTMLElement} [rootElement] - Root element to attach to, the document body by default
|
|
111
113
|
* @memberof Engine */
|
|
112
114
|
function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRenderPost, imageSources=[], rootElement=document.body)
|
|
@@ -120,7 +122,8 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
120
122
|
mainCanvasSize = vec2(mainCanvas.width, mainCanvas.height);
|
|
121
123
|
|
|
122
124
|
// disable smoothing for pixel art
|
|
123
|
-
|
|
125
|
+
overlayContext.imageSmoothingEnabled =
|
|
126
|
+
mainContext.imageSmoothingEnabled = !tilesPixelated;
|
|
124
127
|
|
|
125
128
|
// setup gl rendering if enabled
|
|
126
129
|
glPreRender();
|
|
@@ -256,8 +259,7 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
256
259
|
|
|
257
260
|
function startEngine()
|
|
258
261
|
{
|
|
259
|
-
gameInit();
|
|
260
|
-
engineUpdate();
|
|
262
|
+
new Promise((resolve) => resolve(gameInit())).then(engineUpdate);
|
|
261
263
|
}
|
|
262
264
|
|
|
263
265
|
if (headlessMode)
|
|
@@ -272,9 +274,9 @@ function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, gameRender
|
|
|
272
274
|
'width:100vw;height:100vh;' + // fill the window
|
|
273
275
|
'display:flex;' + // use flexbox
|
|
274
276
|
'align-items:center;' + // horizontal center
|
|
275
|
-
(canvasPixelated ? 'image-rendering:pixelated;' : '') + // pixel art
|
|
276
277
|
'justify-content:center;' + // vertical center
|
|
277
278
|
'background:#000;' + // set background color
|
|
279
|
+
(canvasPixelated ? 'image-rendering:pixelated;' : '') + // pixel art
|
|
278
280
|
'user-select:none;' + // prevent hold to select
|
|
279
281
|
'-webkit-user-select:none;' + // compatibility for ios
|
|
280
282
|
(!touchInputEnable ? '' : // no touch css setttings
|
|
@@ -610,4 +612,4 @@ function drawEngineSplashScreen(t)
|
|
|
610
612
|
}
|
|
611
613
|
|
|
612
614
|
x.restore();
|
|
613
|
-
}
|
|
615
|
+
}
|
package/src/engineAudio.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
/** Audio context used by the engine
|
|
15
15
|
* @type {AudioContext}
|
|
16
16
|
* @memberof Audio */
|
|
17
|
-
let audioContext;
|
|
17
|
+
let audioContext = new AudioContext;
|
|
18
18
|
|
|
19
19
|
/** Master gain node for all audio to pass through
|
|
20
20
|
* @type {GainNode}
|
|
@@ -25,14 +25,10 @@ function audioInit()
|
|
|
25
25
|
{
|
|
26
26
|
if (!soundEnable || headlessMode) return;
|
|
27
27
|
|
|
28
|
-
// create audio context
|
|
29
|
-
audioContext = new AudioContext;
|
|
30
|
-
|
|
31
|
-
// create and connect gain node
|
|
32
28
|
// (createGain is more widely spported then GainNode construtor)
|
|
33
29
|
audioGainNode = audioContext.createGain();
|
|
34
30
|
audioGainNode.connect(audioContext.destination);
|
|
35
|
-
|
|
31
|
+
audioGainNode.gain.value = soundVolume; // set starting value
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
///////////////////////////////////////////////////////////////////////////////
|
|
@@ -72,7 +68,7 @@ class Sound
|
|
|
72
68
|
{
|
|
73
69
|
// generate zzfx sound now for fast playback
|
|
74
70
|
const defaultRandomness = .05;
|
|
75
|
-
this.randomness = zzfxSound[1]
|
|
71
|
+
this.randomness = zzfxSound[1] != undefined ? zzfxSound[1] : defaultRandomness;
|
|
76
72
|
zzfxSound[1] = 0; // generate without randomness
|
|
77
73
|
this.sampleChannels = [zzfxG(...zzfxSound)];
|
|
78
74
|
this.sampleRate = zzfxR;
|
|
@@ -114,10 +110,11 @@ class Sound
|
|
|
114
110
|
// play the sound
|
|
115
111
|
const playbackRate = pitch + pitch * this.randomness*randomnessScale*rand(-1,1);
|
|
116
112
|
this.gainNode = audioContext.createGain();
|
|
117
|
-
|
|
113
|
+
this.source = playSamples(this.sampleChannels, volume, playbackRate, pan, loop, this.sampleRate, this.gainNode);
|
|
114
|
+
return this.source;
|
|
118
115
|
}
|
|
119
116
|
|
|
120
|
-
/** Set the sound volume
|
|
117
|
+
/** Set the sound volume of the most recently played instance of this sound
|
|
121
118
|
* @param {Number} [volume] - How much to scale volume by
|
|
122
119
|
*/
|
|
123
120
|
setVolume(volume=1)
|