littlejsengine 1.11.6 → 1.11.8
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 +11 -16
- package/dist/littlejs.d.ts +14 -1
- package/dist/littlejs.esm.js +35 -21
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +32 -20
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +28 -19
- package/examples/box2d/game.js +2 -2
- package/examples/box2d/index.html +5 -5
- package/examples/breakout/game.js +6 -5
- package/examples/breakout/index.html +4 -4
- package/examples/breakoutTutorial/index.html +2 -2
- package/examples/htmlMenu/index.html +2 -2
- package/examples/index.html +300 -32
- package/examples/module/index.html +1 -1
- package/examples/particles/index.html +1 -1
- package/examples/platformer/gamePlayer.js +2 -7
- package/examples/platformer/index.html +8 -8
- package/examples/puzzle/index.html +2 -2
- package/examples/shorts/base.html +26 -0
- package/{shortExamples/code → examples/shorts}/blending.js +1 -1
- package/examples/shorts/platformer.js +42 -0
- package/{shortExamples/code → examples/shorts}/playSound.js +3 -0
- package/{shortExamples/code → examples/shorts}/pong.js +3 -3
- package/{shortExamples/code → examples/shorts}/shapes.js +2 -2
- package/examples/shorts/tiltedView.js +44 -0
- package/{shortExamples/code → examples/shorts}/timers.js +7 -3
- package/examples/shorts/topDown.js +44 -0
- package/examples/starter/index.html +13 -13
- package/examples/stress/index.html +2 -2
- package/examples/uiSystem/game.js +6 -1
- package/examples/uiSystem/index.html +3 -3
- package/package.json +1 -1
- package/plugins/Box2D_License.txt +17 -0
- package/plugins/uiSystem.js +2 -1
- package/reference.md +2 -1
- package/src/engine.js +1 -1
- package/src/engineDebug.js +5 -1
- package/src/engineDraw.js +5 -1
- package/src/engineExport.js +3 -1
- package/src/engineInput.js +19 -15
- package/src/engineRelease.js +1 -0
- package/src/engineTileLayer.js +2 -2
- package/.vscode/launch.json +0 -14
- package/shortExamples/base.html +0 -39
- package/shortExamples/index.html +0 -246
- /package/{shortExamples/code → examples/shorts}/animation.js +0 -0
- /package/{shortExamples/code → examples/shorts}/clock.js +0 -0
- /package/{shortExamples/code → examples/shorts}/colors.js +0 -0
- /package/{shortExamples/code → examples/shorts}/helloWorld.js +0 -0
- /package/{shortExamples/code → examples/shorts}/particles.js +0 -0
- /package/{shortExamples/code → examples/shorts}/spriteAtlas.js +0 -0
- /package/{shortExamples/code → examples/shorts}/systemFont.js +0 -0
- /package/{shortExamples/code → examples/shorts}/texture.js +0 -0
- /package/{shortExamples/code → examples/shorts}/tileLayer.js +0 -0
- /package/{shortExamples → examples/shorts}/tiles.png +0 -0
|
@@ -21,9 +21,10 @@ const sound_bounce = new Sound([,,1e3,,.03,.02,1,2,,,940,.03,,,,,.2,.6,,.06]);
|
|
|
21
21
|
///////////////////////////////////////////////////////////////////////////////
|
|
22
22
|
function gameInit()
|
|
23
23
|
{
|
|
24
|
-
canvasFixedSize = vec2(
|
|
24
|
+
canvasFixedSize = vec2(1920, 1080); // 1080p
|
|
25
25
|
levelSize = vec2(38, 20);
|
|
26
26
|
cameraPos = levelSize.scale(.5);
|
|
27
|
+
cameraScale = 48;
|
|
27
28
|
paddle = new Paddle(vec2(levelSize.x/2-12, 1));
|
|
28
29
|
score = brickCount = 0;
|
|
29
30
|
|
|
@@ -34,9 +35,9 @@ function gameInit()
|
|
|
34
35
|
new Brick(pos);
|
|
35
36
|
|
|
36
37
|
// create walls
|
|
37
|
-
new Wall(vec2(-.5,levelSize.y/2), vec2(1,100)) // top
|
|
38
|
-
new Wall(vec2(levelSize.x+.5,levelSize.y/2), vec2(1,100)) // left
|
|
39
|
-
new Wall(vec2(levelSize.x/2,levelSize.y+.5), vec2(100,1)) // right
|
|
38
|
+
new Wall(vec2(-.5,levelSize.y/2), vec2(1,100)); // top
|
|
39
|
+
new Wall(vec2(levelSize.x+.5,levelSize.y/2), vec2(1,100)); // left
|
|
40
|
+
new Wall(vec2(levelSize.x/2,levelSize.y+.5), vec2(100,1)); // right
|
|
40
41
|
|
|
41
42
|
setupPostProcess(); // set up a post processing shader
|
|
42
43
|
}
|
|
@@ -71,7 +72,7 @@ function gameRenderPost()
|
|
|
71
72
|
{
|
|
72
73
|
// use built in image font for text
|
|
73
74
|
const font = new FontImage;
|
|
74
|
-
font.drawText('Score: ' + score, cameraPos.add(vec2(0,9.
|
|
75
|
+
font.drawText('Score: ' + score, cameraPos.add(vec2(0,9.7)), .15, true);
|
|
75
76
|
if (!brickCount)
|
|
76
77
|
font.drawText('You Win!', cameraPos.add(vec2(0,-5)), .2, true);
|
|
77
78
|
else if (!ball)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<link rel=icon type=image/png href=../favicon.png>
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
|
-
<script src=../../dist/littlejs.js?
|
|
10
|
-
<script src=../../plugins/postProcess.js?
|
|
11
|
-
<script src=gameObjects.js?
|
|
12
|
-
<script src=game.js?
|
|
9
|
+
<script src=../../dist/littlejs.js?1117></script>
|
|
10
|
+
<script src=../../plugins/postProcess.js?1117></script>
|
|
11
|
+
<script src=gameObjects.js?1117></script>
|
|
12
|
+
<script src=game.js?1117></script>
|
package/examples/index.html
CHANGED
|
@@ -1,34 +1,302 @@
|
|
|
1
|
-
|
|
2
|
-
<title>LittleJS
|
|
1
|
+
<!DOCTYPE html><head>
|
|
2
|
+
<title>LittleJS Example Browser</title>
|
|
3
|
+
<link rel=icon type=image/png href=favicon.png>
|
|
4
|
+
<meta charset=utf-8>
|
|
3
5
|
<style>
|
|
4
|
-
|
|
6
|
+
html, body
|
|
7
|
+
{
|
|
8
|
+
height: 100%;
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
}
|
|
12
|
+
#container1
|
|
13
|
+
{
|
|
14
|
+
height: 100%;
|
|
15
|
+
display: flex;
|
|
16
|
+
}
|
|
17
|
+
#container2
|
|
18
|
+
{
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
}
|
|
22
|
+
#iframeContainer
|
|
23
|
+
{
|
|
24
|
+
border: 2px solid;
|
|
25
|
+
background: #000;
|
|
26
|
+
}
|
|
27
|
+
iframe
|
|
28
|
+
{
|
|
29
|
+
width: 100%;
|
|
30
|
+
height: 100%;
|
|
31
|
+
border: none;
|
|
32
|
+
}
|
|
33
|
+
#selectExample
|
|
34
|
+
{
|
|
35
|
+
flex-grow: 1;
|
|
36
|
+
}
|
|
37
|
+
#textareaCode
|
|
38
|
+
{
|
|
39
|
+
flex-grow: 1;
|
|
40
|
+
padding: 5px;
|
|
41
|
+
resize: none;
|
|
42
|
+
color: #fff;
|
|
43
|
+
background: #000;
|
|
44
|
+
}
|
|
45
|
+
#textareaError
|
|
46
|
+
{
|
|
47
|
+
flex-grow: .3;
|
|
48
|
+
padding: 5px;
|
|
49
|
+
resize: none;
|
|
50
|
+
display: none;
|
|
51
|
+
color:#f22;
|
|
52
|
+
background: #111;
|
|
53
|
+
}
|
|
54
|
+
#container3
|
|
55
|
+
{
|
|
56
|
+
width: 100%;
|
|
57
|
+
height: 100%;
|
|
58
|
+
display: flex;
|
|
59
|
+
flex-direction: column;
|
|
60
|
+
}
|
|
61
|
+
#titleInfo
|
|
62
|
+
{
|
|
63
|
+
margin: 5px;
|
|
64
|
+
text-align: center;
|
|
65
|
+
font-size: 50px;
|
|
66
|
+
}
|
|
67
|
+
#exampleLink
|
|
68
|
+
{
|
|
69
|
+
margin: 0px;
|
|
70
|
+
text-align: center;
|
|
71
|
+
font-size: 30px;
|
|
72
|
+
}
|
|
73
|
+
#exampleInfo
|
|
74
|
+
{
|
|
75
|
+
margin: 0px;
|
|
76
|
+
text-align: center;
|
|
77
|
+
font-size: 22px;
|
|
78
|
+
}
|
|
79
|
+
select
|
|
80
|
+
{
|
|
81
|
+
color:#fff;
|
|
82
|
+
background-color: #111;
|
|
83
|
+
width:100%;
|
|
84
|
+
}
|
|
5
85
|
</style>
|
|
6
|
-
|
|
7
|
-
<
|
|
8
|
-
<
|
|
9
|
-
<
|
|
10
|
-
<
|
|
11
|
-
<p>
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
</
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
86
|
+
</head><body>
|
|
87
|
+
<div id=container1>
|
|
88
|
+
<div id=container3>
|
|
89
|
+
<p id=titleInfo>LittleJS Example Browser</p>
|
|
90
|
+
<a id=exampleLink target="_blank">Example LINK</a>
|
|
91
|
+
<p id=exampleInfo>Example Info</p>
|
|
92
|
+
<textarea id=textareaCode oninput=codeInput() spellcheck=false></textarea>
|
|
93
|
+
<textarea id=textareaError readonly spellcheck=false></textarea>
|
|
94
|
+
<div><input type=checkbox id=checkboxLiveEdit checked>Live Edit
|
|
95
|
+
<button id=buttonScreenshot>Screenshot</button>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
<div id=container2>
|
|
99
|
+
<div id=iframeContainer></div>
|
|
100
|
+
<select id=selectExample autofocus onchange=setExample() size=2></select>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
<script>
|
|
104
|
+
'use strict';
|
|
105
|
+
|
|
106
|
+
class ExampleInfo
|
|
107
|
+
{
|
|
108
|
+
constructor(name, filename, description, fullExample=false)
|
|
109
|
+
{
|
|
110
|
+
if (filename && !fullExample)
|
|
111
|
+
filename = 'shorts/' + filename; // short examples folder
|
|
112
|
+
this.name = name;
|
|
113
|
+
this.filename = filename;
|
|
114
|
+
this.description = description;
|
|
115
|
+
this.fullExample = fullExample;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const exampleList =
|
|
120
|
+
[
|
|
121
|
+
new ExampleInfo('--- SHORT EXAMPLES ---'),
|
|
122
|
+
new ExampleInfo('Hello World', 'helloWorld.js', 'Simplest example'),
|
|
123
|
+
new ExampleInfo('Shapes', 'shapes.js', 'How to draw geometric shapes'),
|
|
124
|
+
new ExampleInfo('Colors', 'colors.js', 'How to use the color object'),
|
|
125
|
+
new ExampleInfo('Blending', 'blending.js', 'Shows different blending modes'),
|
|
126
|
+
new ExampleInfo('Timers', 'timers.js', 'How to use the timer object'),
|
|
127
|
+
new ExampleInfo('Texture', 'texture.js', 'How to display a full texture'),
|
|
128
|
+
new ExampleInfo('Particles', 'particles.js', 'How to use the particle system'),
|
|
129
|
+
new ExampleInfo('Play Sound', 'playSound.js', 'How to play sounds with zzfx'),
|
|
130
|
+
new ExampleInfo('System Font', 'systemFont.js', 'Demo of the included system font'),
|
|
131
|
+
new ExampleInfo('Sprite Atlas', 'spriteAtlas.js', 'How to set up a simple sprite atlas'),
|
|
132
|
+
new ExampleInfo('Animation', 'animation.js', 'How to animate sprites'),
|
|
133
|
+
new ExampleInfo('Clock', 'clock.js', 'A simple clock showing the time'),
|
|
134
|
+
new ExampleInfo('Tile Layer', 'tileLayer.js', 'How to use the tile layer object'),
|
|
135
|
+
new ExampleInfo('Platformer Game', 'platformer.js', 'A platformer jumping game'),
|
|
136
|
+
new ExampleInfo('Top Down Game', 'topDown.js', 'A top down adventure game'),
|
|
137
|
+
new ExampleInfo('Tilted View', 'tiltedView.js', 'Pseudo 3D view with tilted camera'),
|
|
138
|
+
new ExampleInfo('Pong Game', 'pong.js', 'A simple pong game'),
|
|
139
|
+
|
|
140
|
+
new ExampleInfo('--- FULL EXAMPLES ---'),
|
|
141
|
+
new ExampleInfo('Starter', 'starter', 'Clean starter project', true),
|
|
142
|
+
new ExampleInfo('Breakout Tutorial', 'breakoutTutorial', 'Tutorial Breakout example', true),
|
|
143
|
+
new ExampleInfo('Breakout Game', 'breakout', 'Block breaking game with post-processing effects', true),
|
|
144
|
+
new ExampleInfo('Platforming Game', 'platformer', 'Platformer/shooter with level data loading', true),
|
|
145
|
+
new ExampleInfo('Puzzle Game', 'puzzle', 'Match 3 puzzle game with HD rendering', true),
|
|
146
|
+
new ExampleInfo('Stress Test', 'stress', 'Max sprite/object test and music system demo', true),
|
|
147
|
+
new ExampleInfo('Box2D Plugin', 'box2d', 'Demo of the Box2D physics plugin', true),
|
|
148
|
+
new ExampleInfo('HTML Menus', 'htmlMenu', 'Shows how to combine HTML with LittleJS', true),
|
|
149
|
+
new ExampleInfo('UI System Plugin', 'uiSystem', 'Example of how to use LittleJS UI plugin', true),
|
|
150
|
+
// Add more examples here!
|
|
151
|
+
];
|
|
152
|
+
|
|
153
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
154
|
+
|
|
155
|
+
let iframeExample, inputTimeout;
|
|
156
|
+
|
|
157
|
+
// load the examples into the list
|
|
158
|
+
for (const example of exampleList)
|
|
159
|
+
{
|
|
160
|
+
const text = example.name + (example.description?' - ' + example.description : '');
|
|
161
|
+
const o = new Option(text);
|
|
162
|
+
o.disabled = !example.filename;
|
|
163
|
+
selectExample.add(o);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// select first option
|
|
167
|
+
selectExample.selectedIndex = 1;
|
|
168
|
+
setExample();
|
|
169
|
+
|
|
170
|
+
onresize = () =>
|
|
171
|
+
{
|
|
172
|
+
// resize iframe to fit half the window
|
|
173
|
+
const aspect = 1920 / 1080;
|
|
174
|
+
let w = innerWidth / 2 | 0;
|
|
175
|
+
let h = w / aspect | 0;
|
|
176
|
+
iframeContainer.style.width = w + 'px';
|
|
177
|
+
iframeContainer.style.height = h + 'px';
|
|
178
|
+
}
|
|
179
|
+
onresize();
|
|
180
|
+
|
|
181
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
182
|
+
|
|
183
|
+
function setExample()
|
|
184
|
+
{
|
|
185
|
+
const example = exampleList[selectExample.selectedIndex];
|
|
186
|
+
exampleInfo.innerText = example.name + (example.description ? ' - ' + example.description : '');
|
|
187
|
+
const filename = 'examples/' + example.filename;
|
|
188
|
+
exampleLink.href = 'https://github.com/KilledByAPixel/LittleJS/tree/main/' + filename;
|
|
189
|
+
exampleLink.innerText = filename;
|
|
190
|
+
loadFile(example.filename, example.fullExample);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function codeInput()
|
|
194
|
+
{
|
|
195
|
+
if (!checkboxLiveEdit.checked)
|
|
196
|
+
return;
|
|
197
|
+
|
|
198
|
+
// debounce input
|
|
199
|
+
clearTimeout(inputTimeout);
|
|
200
|
+
inputTimeout = setTimeout(() => setCode(textareaCode.value), 500);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function loadFile(filename, fullExample)
|
|
204
|
+
{
|
|
205
|
+
textareaCode.disabled = fullExample;
|
|
206
|
+
if (fullExample)
|
|
207
|
+
{
|
|
208
|
+
if (iframeExample)
|
|
209
|
+
iframeContainer.removeChild(iframeExample);
|
|
210
|
+
|
|
211
|
+
setErrorMessage();
|
|
212
|
+
iframeExample = document.createElement('iframe');
|
|
213
|
+
iframeContainer.appendChild(iframeExample);
|
|
214
|
+
iframeExample.onload = () =>
|
|
215
|
+
{
|
|
216
|
+
const iframeContent = iframeExample.contentWindow;
|
|
217
|
+
const iframeDocument = iframeContent.document;
|
|
218
|
+
//textareaCode.value = iframeDocument.body.innerHTML;
|
|
219
|
+
textareaCode.value = 'Editor code view not available for large examples.\n';
|
|
220
|
+
}
|
|
221
|
+
iframeExample.src = filename;
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
fetch(filename)
|
|
226
|
+
.then(response => {
|
|
227
|
+
if (!response.ok)
|
|
228
|
+
throw new Error('Could not load file: '+ filename);
|
|
229
|
+
return response.text();
|
|
230
|
+
})
|
|
231
|
+
.then(text => setCode(textareaCode.value = text, fullExample))
|
|
232
|
+
.catch(error => setErrorMessage(error.message));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function setCode(code, largeExample)
|
|
236
|
+
{
|
|
237
|
+
clearTimeout(inputTimeout);
|
|
238
|
+
if (iframeExample)
|
|
239
|
+
iframeContainer.removeChild(iframeExample);
|
|
240
|
+
|
|
241
|
+
setErrorMessage();
|
|
242
|
+
iframeExample = document.createElement('iframe');
|
|
243
|
+
iframeContainer.appendChild(iframeExample);
|
|
244
|
+
iframeExample.onload = () =>
|
|
245
|
+
{
|
|
246
|
+
const iframeContent = iframeExample.contentWindow;
|
|
247
|
+
const iframeDocument = iframeContent.document;
|
|
248
|
+
|
|
249
|
+
// create error event listeners
|
|
250
|
+
iframeContent.onerror = (message, source, lineno, colno, error) =>
|
|
251
|
+
{
|
|
252
|
+
let text = message;
|
|
253
|
+
if (lineno)
|
|
254
|
+
text += ` (Line:${lineno}, Column:${colno})`
|
|
255
|
+
if (error && error.stack)
|
|
256
|
+
text += `\n\n` + error.stack;
|
|
257
|
+
setErrorMessage(text);
|
|
258
|
+
}
|
|
259
|
+
iframeContent.onunhandledrejection = (event) =>
|
|
260
|
+
{
|
|
261
|
+
let text = event.reason;
|
|
262
|
+
if (event.reason.stack)
|
|
263
|
+
text += `\n\n` + event.reason.stack;
|
|
264
|
+
setErrorMessage(text);
|
|
265
|
+
};
|
|
266
|
+
const originalAssert = iframeContent.console.assert;
|
|
267
|
+
iframeContent.console.assert = function (condition, output)
|
|
268
|
+
{
|
|
269
|
+
if (!condition)
|
|
270
|
+
setErrorMessage('Assertion failed!\n' + (output || '') + '\n' + (new Error).stack);
|
|
271
|
+
originalAssert.apply(this, arguments);
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
// create a script element that overrides the default functions
|
|
275
|
+
const overrideScript = iframeDocument.createElement('script');
|
|
276
|
+
iframeDocument.body.appendChild(overrideScript);
|
|
277
|
+
overrideScript.text = code;
|
|
278
|
+
|
|
279
|
+
if (textareaError.style.display == 'block')
|
|
280
|
+
return; // stop if script error
|
|
281
|
+
|
|
282
|
+
// start LittleJS engine
|
|
283
|
+
iframeContent.engineInit(iframeContent.gameInit, iframeContent.gameUpdate, iframeContent.gameUpdatePost, iframeContent.gameRender, iframeContent.gameRenderPost, ['tiles.png?1']);
|
|
284
|
+
|
|
285
|
+
buttonScreenshot.onclick = () =>
|
|
286
|
+
{
|
|
287
|
+
if (iframeContent.debugScreenshot)
|
|
288
|
+
iframeContent.debugScreenshot();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
iframeExample.src = 'shorts/base.html';
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function setErrorMessage(message='')
|
|
295
|
+
{
|
|
296
|
+
textareaError.value = message
|
|
297
|
+
textareaError.style.display = message ? 'block' : 'none';
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
</script>
|
|
301
|
+
</body>
|
|
302
|
+
</html>
|
|
@@ -13,17 +13,12 @@ class Player extends Character
|
|
|
13
13
|
{
|
|
14
14
|
update()
|
|
15
15
|
{
|
|
16
|
-
//
|
|
16
|
+
// movement control
|
|
17
|
+
this.moveInput = isUsingGamepad ? gamepadStick(0) : keyDirection();
|
|
17
18
|
this.holdingJump = keyIsDown('ArrowUp') || gamepadIsDown(0);
|
|
18
19
|
this.holdingShoot = !isUsingGamepad && mouseIsDown(0) || keyIsDown('KeyZ') || gamepadIsDown(2);
|
|
19
20
|
this.pressingThrow = keyIsDown('KeyC') || mouseIsDown(1) || gamepadIsDown(1);
|
|
20
21
|
this.pressedDodge = keyIsDown('KeyX') || mouseIsDown(2) || gamepadIsDown(3);
|
|
21
|
-
|
|
22
|
-
// movement control
|
|
23
|
-
this.moveInput = isUsingGamepad ? gamepadStick(0) :
|
|
24
|
-
vec2(keyIsDown('ArrowRight') - keyIsDown('ArrowLeft'),
|
|
25
|
-
keyIsDown('ArrowUp') - keyIsDown('ArrowDown'));
|
|
26
|
-
|
|
27
22
|
super.update();
|
|
28
23
|
}
|
|
29
24
|
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
<link rel=icon type=image/png href=../favicon.png>
|
|
8
8
|
</head><body>
|
|
9
9
|
|
|
10
|
-
<script src=../../dist/littlejs.js?
|
|
11
|
-
<script src=gameObjects.js?
|
|
12
|
-
<script src=gameCharacter.js?
|
|
13
|
-
<script src=gamePlayer.js?
|
|
14
|
-
<script src=gameEffects.js?
|
|
15
|
-
<script src=gameLevel.js?
|
|
16
|
-
<script src=gameLevelData.js?
|
|
17
|
-
<script src=game.js?
|
|
10
|
+
<script src=../../dist/littlejs.js?1117></script>
|
|
11
|
+
<script src=gameObjects.js?1117></script>
|
|
12
|
+
<script src=gameCharacter.js?1117></script>
|
|
13
|
+
<script src=gamePlayer.js?1117></script>
|
|
14
|
+
<script src=gameEffects.js?1117></script>
|
|
15
|
+
<script src=gameLevel.js?1117></script>
|
|
16
|
+
<script src=gameLevelData.js?1117></script>
|
|
17
|
+
<script src=game.js?1117></script>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<!DOCTYPE html><meta charset=utf-8><body>
|
|
2
|
+
<script src=../../dist/littlejs.js?1117></script>
|
|
3
|
+
<script>
|
|
4
|
+
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
// use fixed size canvas for examples
|
|
8
|
+
canvasFixedSize = vec2(960, 540);
|
|
9
|
+
|
|
10
|
+
// fix bleeding from neighboring pixels
|
|
11
|
+
tileFixBleedScale = .5;
|
|
12
|
+
|
|
13
|
+
// allow improved scaling
|
|
14
|
+
canvasPixelated = false;
|
|
15
|
+
|
|
16
|
+
// disable watermark
|
|
17
|
+
showWatermark = false;
|
|
18
|
+
|
|
19
|
+
// these functions can be overridden for each example
|
|
20
|
+
function gameInit() {}
|
|
21
|
+
function gameUpdate() {}
|
|
22
|
+
function gameUpdatePost() {}
|
|
23
|
+
function gameRender() {}
|
|
24
|
+
function gameRenderPost() {}
|
|
25
|
+
|
|
26
|
+
</script>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
class PhysicsObject extends EngineObject
|
|
2
|
+
{
|
|
3
|
+
constructor(pos, size, color)
|
|
4
|
+
{
|
|
5
|
+
super(pos, size, 0, 0, color);
|
|
6
|
+
this.setCollision(); // make object collide
|
|
7
|
+
this.mass = 0; // make object have static physics
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
class Player extends PhysicsObject
|
|
12
|
+
{
|
|
13
|
+
constructor(pos)
|
|
14
|
+
{
|
|
15
|
+
super(pos, vec2(2,4), RED);
|
|
16
|
+
this.mass = 1; // make object have dynamic physics
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
update()
|
|
20
|
+
{
|
|
21
|
+
// apply movement controls
|
|
22
|
+
const moveInput = keyDirection();
|
|
23
|
+
this.velocity.x += moveInput.x * (this.groundObject ? .1: .01);
|
|
24
|
+
if (this.groundObject && moveInput.y > 0)
|
|
25
|
+
this.velocity.y = .9; // jump
|
|
26
|
+
|
|
27
|
+
super.update(); // call parent update function
|
|
28
|
+
cameraPos = vec2(this.pos.x, 9); // move camera with player
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function gameInit()
|
|
33
|
+
{
|
|
34
|
+
// setup level
|
|
35
|
+
gravity = -.05;
|
|
36
|
+
new Player(vec2(0,4));
|
|
37
|
+
|
|
38
|
+
// create random objects
|
|
39
|
+
new PhysicsObject(vec2(), vec2(1e3,4), GRAY); // ground
|
|
40
|
+
for (let i = 1; i < 500; ++i)
|
|
41
|
+
new PhysicsObject(vec2(i*10+randInt(4), 0), vec2(2+randInt(20),4+randInt(8)), GREEN);
|
|
42
|
+
}
|
|
@@ -9,12 +9,14 @@ class SoundButton extends EngineObject
|
|
|
9
9
|
|
|
10
10
|
update()
|
|
11
11
|
{
|
|
12
|
+
// play sound when clicked
|
|
12
13
|
if (mouseWasPressed(0) && isOverlapping(this.pos, this.size, mousePos))
|
|
13
14
|
this.sound.play(this.pos);
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
render()
|
|
17
18
|
{
|
|
19
|
+
// draw the button and icon
|
|
18
20
|
drawRect(this.pos, this.size, hsl(0,0,.8));
|
|
19
21
|
drawTextOverlay(this.icon, this.pos, 3);
|
|
20
22
|
}
|
|
@@ -22,6 +24,7 @@ class SoundButton extends EngineObject
|
|
|
22
24
|
|
|
23
25
|
function gameInit()
|
|
24
26
|
{
|
|
27
|
+
// create a grid of buttons with different sounds
|
|
25
28
|
new SoundButton(vec2(-6, 5),'💰', new Sound([,,1675,,.06,.24,1,1.82,,,837,.06]));
|
|
26
29
|
new SoundButton(vec2( 0, 5),'🥊', new Sound([,,925,.04,.3,.6,1,.3,,6.27,-184,.09,.17]));
|
|
27
30
|
new SoundButton(vec2( 6, 5),'✨', new Sound([,,539,0,.04,.29,1,1.92,,,567,.02,.02,,,,.04]));
|
|
@@ -20,9 +20,9 @@ function gameInit()
|
|
|
20
20
|
|
|
21
21
|
// create objects
|
|
22
22
|
paddle = new PhysicsObject(vec2(0,1), vec2(6,1)); // create player's paddle
|
|
23
|
-
new PhysicsObject(vec2(-.5,levelSize.y/2), vec2(1,100)) //
|
|
24
|
-
new PhysicsObject(vec2(levelSize.x+.5,levelSize.y/2), vec2(1,100)) //
|
|
25
|
-
new PhysicsObject(vec2(levelSize.x/2,levelSize.y+.5), vec2(100,1)) //
|
|
23
|
+
new PhysicsObject(vec2(-.5,levelSize.y/2), vec2(1,100)); // left wall
|
|
24
|
+
new PhysicsObject(vec2(levelSize.x+.5,levelSize.y/2), vec2(1,100)); // right wall
|
|
25
|
+
new PhysicsObject(vec2(levelSize.x/2,levelSize.y+.5), vec2(100,1)); // top wall
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function gameUpdate()
|
|
@@ -13,9 +13,9 @@ function gameRender()
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
// circles and ellipses
|
|
16
|
-
drawCircle(vec2(0,5), 1,
|
|
16
|
+
drawCircle(vec2(0,5), 1, hsl(.15,1,.5));
|
|
17
17
|
drawEllipse(vec2(-5,5), 2, 1, 0, hsl(0,1,.5));
|
|
18
|
-
drawEllipse(vec2(5,5),
|
|
18
|
+
drawEllipse(vec2(5,5), .5, 2, .5, hsl(.55,1,.5));
|
|
19
19
|
|
|
20
20
|
// rects and lines
|
|
21
21
|
drawRect(vec2(0,-5), vec2(13,2), hsl(.6,1,.5));
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
class GameObject extends EngineObject
|
|
2
|
+
{
|
|
3
|
+
update()
|
|
4
|
+
{
|
|
5
|
+
this.renderOrder = -this.pos.y; // sort by y position
|
|
6
|
+
super.update();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
render()
|
|
10
|
+
{
|
|
11
|
+
// adjust draw postion to be at the bottom of the object
|
|
12
|
+
const pos = this.pos.add(vec2(0,this.size.y/2).rotate(this.angle));
|
|
13
|
+
drawTile(pos, this.size, this.tileInfo, this.color, this.angle);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class Player extends GameObject
|
|
18
|
+
{
|
|
19
|
+
update()
|
|
20
|
+
{
|
|
21
|
+
// apply movement controls
|
|
22
|
+
const moveInput = keyDirection().clampLength(1).scale(.2); // clamp and scale input
|
|
23
|
+
this.velocity = this.velocity.add(moveInput); // apply movement
|
|
24
|
+
|
|
25
|
+
super.update(); // call parent update function
|
|
26
|
+
cameraPos = this.pos.add(vec2(0,2)); // move camera with player
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
function gameInit()
|
|
32
|
+
{
|
|
33
|
+
// setup level
|
|
34
|
+
objectDefaultDamping = .7;
|
|
35
|
+
new Player(vec2(), vec2(3), tile(5), 0, RED);
|
|
36
|
+
|
|
37
|
+
// create background objects
|
|
38
|
+
for (let i = 1; i < 300; ++i)
|
|
39
|
+
new EngineObject(randInCircle(90), vec2(rand(59),rand(59)), 0, 0, hsl(.4,.3,rand(.1,.2),.8), -1e5);
|
|
40
|
+
|
|
41
|
+
// create world objects
|
|
42
|
+
for (let i = 1; i < 1e3; ++i)
|
|
43
|
+
new GameObject(randInCircle(7+i,7), vec2(rand(1,2),rand(4,9)), 0, 0, hsl(.1,.5,rand(.2,.3)));
|
|
44
|
+
}
|