littlejsengine 1.17.1 → 1.17.10
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/LICENSE +10 -10
- package/dist/littlejs.d.ts +254 -171
- package/dist/littlejs.esm.js +892 -628
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +889 -626
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +885 -622
- package/examples/box2d/gameObjects.js +3 -3
- package/examples/electron/index.html +2 -2
- package/examples/index.html +10 -9
- package/examples/logo.png +0 -0
- package/examples/logo2.png +0 -0
- package/examples/module/build.bat +7 -0
- package/examples/module/build.js +121 -0
- package/examples/particles/index.html +1 -1
- package/examples/platformer/game.js +1 -1
- package/examples/platformer/gameEffects.js +5 -10
- package/examples/platformer/gameLevel.js +3 -3
- package/examples/puzzle/game.js +2 -2
- package/examples/shorts/base.html +4 -1
- package/examples/shorts/box2dPool.js +2 -2
- package/examples/shorts/box2dTileLayer.js +48 -0
- package/examples/shorts/colors.js +1 -1
- package/examples/shorts/fps.js +1 -1
- package/examples/shorts/music.js +5 -4
- package/examples/shorts/musicPlayer.js +4 -3
- package/examples/shorts/parallax.js +2 -2
- package/examples/shorts/tiltedView.js +1 -1
- package/examples/starter/index.html +2 -2
- package/package.json +5 -5
- package/plugins/box2d.js +166 -63
- package/plugins/pluginExport.js +1 -1
- package/plugins/postProcess.js +1 -1
- package/plugins/uiSystem.js +33 -20
- package/plugins/zzfxm.js +2 -2
- package/reference.md +9 -8
- package/src/engine.js +111 -134
- package/src/engineAudio.js +44 -58
- package/src/engineDebug.js +4 -4
- package/src/engineDraw.js +7 -4
- package/src/engineExport.js +2 -1
- package/src/engineInput.js +5 -5
- package/src/engineMath.js +9 -9
- package/src/engineObject.js +25 -25
- package/src/engineParticles.js +241 -118
- package/src/engineTileLayer.js +117 -88
- package/src/engineUtilities.js +105 -78
- package/src/engineWebGL.js +2 -2
- package/plugins/Box2D_License.txt +0 -17
|
@@ -126,7 +126,7 @@ export class CarObject extends LJS.Box2dObject
|
|
|
126
126
|
const maxTorque = 35;
|
|
127
127
|
const sprite = Game.spriteAtlas.wheel;
|
|
128
128
|
this.wheels = [];
|
|
129
|
-
const makeWheel = (pos, isMotor)
|
|
129
|
+
const makeWheel = (pos, isMotor)=>
|
|
130
130
|
{
|
|
131
131
|
const wheel = new LJS.Box2dObject(pos, vec2(diameter), sprite);
|
|
132
132
|
const joint = new LJS.Box2dWheelJoint(this, wheel);
|
|
@@ -284,7 +284,7 @@ export class SoftBodyObject extends LJS.Box2dObject
|
|
|
284
284
|
for (let x=sizeCount.x; x--;)
|
|
285
285
|
{
|
|
286
286
|
const o = this.getNode(x, y);
|
|
287
|
-
const tryAddJoint = (xo, yo)
|
|
287
|
+
const tryAddJoint = (xo, yo)=>
|
|
288
288
|
{
|
|
289
289
|
const o2 = this.getNode(x+xo, y+yo);
|
|
290
290
|
const joint = o2 ? new LJS.Box2dWeldJoint(o, o2) : 0;
|
|
@@ -360,7 +360,7 @@ export class ClothObject extends LJS.Box2dStaticObject
|
|
|
360
360
|
const d = y%2 ? 1 : -1;
|
|
361
361
|
const x2 = d>1 ? x : sizeCount.x-1-x;
|
|
362
362
|
const o = this.getNode(x2, y);
|
|
363
|
-
const tryAddJoint = (xo, yo)
|
|
363
|
+
const tryAddJoint = (xo, yo)=>
|
|
364
364
|
{
|
|
365
365
|
const o2 = this.getNode(x2+xo, y+yo);
|
|
366
366
|
const joint = o2 ? new LJS.Box2dRopeJoint(o, o2) : 0;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../dist/littlejs.js?1.17.
|
|
10
|
+
<script src=../../dist/littlejs.js?1.17.10></script>
|
|
11
11
|
|
|
12
12
|
<!-- Add your game scripts here -->
|
|
13
|
-
<script src=game.js?1.17.
|
|
13
|
+
<script src=game.js?1.17.10></script>
|
package/examples/index.html
CHANGED
|
@@ -103,7 +103,7 @@ const exampleList =
|
|
|
103
103
|
new ExampleInfo('Font Image', 'fontImage.js', 'Bitmap font system with built-in system font', false, 'text, characters'),
|
|
104
104
|
new ExampleInfo('Medals', 'medals.js', 'Achievement system', false, 'unlock, progress, newgrounds'),
|
|
105
105
|
new ExampleInfo('Tile Raycast', 'tileRaycast.js', 'Example of the tile layer raycast collision', false, 'level, map, grid'),
|
|
106
|
-
new ExampleInfo('Camera Mouse Drag', 'cameraDrag.js', 'Example of how to control camera with
|
|
106
|
+
new ExampleInfo('Camera Mouse Drag', 'cameraDrag.js', 'Example of how to control camera with mouse', false, 'ui, input, control'),
|
|
107
107
|
new ExampleInfo('Debug Drawing', 'debugDraw.js', 'Debug drawing system', false, 'debug, circle, line, rectangle'),
|
|
108
108
|
new ExampleInfo('--- ADVANCED ---'),
|
|
109
109
|
new ExampleInfo('Clock', 'clock.js', 'Animated analog clock', false, 'time, rotation, lines, rectangle'),
|
|
@@ -113,7 +113,7 @@ const exampleList =
|
|
|
113
113
|
new ExampleInfo('Piano', 'piano.js', 'Interactive piano keyboard', false, 'music, sound, audio, notes, ui, instrument'),
|
|
114
114
|
new ExampleInfo('Step Sequencer', 'sequencer.js', 'Simple music loop creation tool', false, 'music, sound, audio, notes, ui, instrument'),
|
|
115
115
|
new ExampleInfo('Music Player', 'musicPlayer.js', 'Music player with audio seeking and drag and drop', false, 'sound, loading, audio, ui'),
|
|
116
|
-
new ExampleInfo('---
|
|
116
|
+
new ExampleInfo('--- GAMES ---'),
|
|
117
117
|
new ExampleInfo('Pong Game', 'pongGame.js', 'Classic paddle ball bouncing', false, 'objects, collision'),
|
|
118
118
|
new ExampleInfo('Platformer Game', 'platformer.js', 'Jump and run side view', false, 'objects, gravity, level, tiles, camera'),
|
|
119
119
|
new ExampleInfo('Top Down Game', 'topDown.js', 'Top-down style camera', false, 'objects, movement, exploration'),
|
|
@@ -127,7 +127,8 @@ const exampleList =
|
|
|
127
127
|
new ExampleInfo('--- PLUGINS ---'),
|
|
128
128
|
new ExampleInfo('Box2d Demo', 'box2d.js', 'Box2D physics plugin', false, 'objects, mouse'),
|
|
129
129
|
new ExampleInfo('Box2d Car', 'box2dCar.js', 'Drivable car with Box2D physics', false, 'objects, vehicle, suspension, wheels'),
|
|
130
|
-
new ExampleInfo('Box2d Pool', 'box2dPool.js', 'Billiard table pool game with physics', false, 'objects, game'),
|
|
130
|
+
new ExampleInfo('Box2d Pool', 'box2dPool.js', 'Billiard table pool game with Box2d physics', false, 'objects, game'),
|
|
131
|
+
new ExampleInfo('Box2d Tile Layer', 'box2dTileLayer.js', 'Tile layer with Box2d physics', false, 'objects, level, map, grid'),
|
|
131
132
|
new ExampleInfo('WebGL Shader', 'shader.js', 'Full canvas webgl shader', false, 'webgl, visual, effect'),
|
|
132
133
|
new ExampleInfo('Post Processing', 'postProcess.js', 'Shader effects and filters', false, 'webgl, visual, effect'),
|
|
133
134
|
new ExampleInfo('UI System', 'uiSystem.js', 'Buttons, sliders, and checkboxes', false, 'objects, widgets, interactive'),
|
|
@@ -159,7 +160,7 @@ function initExampleBrowser()
|
|
|
159
160
|
// set the selected example from the URL parameters
|
|
160
161
|
const urlParams = new URLSearchParams(window.location.search);
|
|
161
162
|
const selectedExample = urlParams.get('example') || '';
|
|
162
|
-
let exampleIndex = exampleList.findIndex((example)
|
|
163
|
+
let exampleIndex = exampleList.findIndex((example)=> example.name === selectedExample);
|
|
163
164
|
if (exampleIndex < 0)
|
|
164
165
|
exampleIndex = 1;
|
|
165
166
|
selectExample.selectedIndex = exampleIndex;
|
|
@@ -398,7 +399,7 @@ function codeInput()
|
|
|
398
399
|
// debounce input - get content from code mirror if available, otherwise from textarea
|
|
399
400
|
clearTimeout(inputTimeout);
|
|
400
401
|
const code = codeMirror ? codeMirror.getValue() : textareaCode.value;
|
|
401
|
-
inputTimeout = setTimeout(()
|
|
402
|
+
inputTimeout = setTimeout(()=> setCode(code), 500);
|
|
402
403
|
}
|
|
403
404
|
|
|
404
405
|
function restartCode()
|
|
@@ -453,7 +454,7 @@ function setCode(code, filename)
|
|
|
453
454
|
const anonymousMatch = stack?.match(/(<anonymous>|injectedScript):(\d+)/);
|
|
454
455
|
return anonymousMatch ? parseInt(anonymousMatch[2]) : -1;
|
|
455
456
|
}
|
|
456
|
-
iframeContent.onerror = (message, source, lineno, colno, error)
|
|
457
|
+
iframeContent.onerror = (message, source, lineno, colno, error)=>
|
|
457
458
|
{
|
|
458
459
|
let text = message;
|
|
459
460
|
if (lineno)
|
|
@@ -463,7 +464,7 @@ function setCode(code, filename)
|
|
|
463
464
|
setErrorMessage(text);
|
|
464
465
|
setErrorLine(lineno);
|
|
465
466
|
}
|
|
466
|
-
iframeContent.onunhandledrejection = (event)
|
|
467
|
+
iframeContent.onunhandledrejection = (event)=>
|
|
467
468
|
{
|
|
468
469
|
let text = event.reason;
|
|
469
470
|
setErrorMessage(text);
|
|
@@ -510,14 +511,14 @@ function setCode(code, filename)
|
|
|
510
511
|
|
|
511
512
|
{
|
|
512
513
|
// hook up buttons
|
|
513
|
-
buttonScreenshot.onclick = ()
|
|
514
|
+
buttonScreenshot.onclick = ()=>
|
|
514
515
|
{
|
|
515
516
|
if (iframeContent.debugScreenshot)
|
|
516
517
|
iframeContent.debugScreenshot();
|
|
517
518
|
}
|
|
518
519
|
|
|
519
520
|
// pause/resume functionality
|
|
520
|
-
buttonPause.onclick = ()
|
|
521
|
+
buttonPause.onclick = ()=>
|
|
521
522
|
{
|
|
522
523
|
if (!iframeContent.getPaused || !iframeContent.setPaused)
|
|
523
524
|
return;
|
package/examples/logo.png
CHANGED
|
Binary file
|
package/examples/logo2.png
CHANGED
|
Binary file
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* LittleJS Build System
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const PROGRAM_TITLE = 'Little JS Starter Project';
|
|
10
|
+
const PROGRAM_NAME = 'game';
|
|
11
|
+
const BUILD_FOLDER = 'build';
|
|
12
|
+
const sourceFiles =
|
|
13
|
+
[
|
|
14
|
+
'game.js',
|
|
15
|
+
// add your game's source files here
|
|
16
|
+
];
|
|
17
|
+
const engineFile = '../../dist/littlejs.esm.min.js'; // Use the minified ES module
|
|
18
|
+
const dataFiles =
|
|
19
|
+
[
|
|
20
|
+
'tiles.png',
|
|
21
|
+
// add your game's data files here
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
console.log(`Building ${PROGRAM_NAME}...`);
|
|
25
|
+
const startTime = Date.now();
|
|
26
|
+
const fs = require('node:fs');
|
|
27
|
+
const child_process = require('node:child_process');
|
|
28
|
+
|
|
29
|
+
// rebuild engine
|
|
30
|
+
//child_process.execSync(`npm run build`, { stdio: 'inherit' });
|
|
31
|
+
|
|
32
|
+
// remove old files and setup build folder
|
|
33
|
+
fs.rmSync(BUILD_FOLDER, { recursive: true, force: true });
|
|
34
|
+
fs.rmSync(`${PROGRAM_NAME}.zip`, { force: true });
|
|
35
|
+
fs.mkdirSync(BUILD_FOLDER);
|
|
36
|
+
|
|
37
|
+
// copy data files
|
|
38
|
+
for (const file of dataFiles)
|
|
39
|
+
fs.copyFileSync(file, `${BUILD_FOLDER}/${file}`);
|
|
40
|
+
|
|
41
|
+
// copy engine module
|
|
42
|
+
fs.copyFileSync(engineFile, `${BUILD_FOLDER}/littlejs.esm.min.js`);
|
|
43
|
+
|
|
44
|
+
Build
|
|
45
|
+
(
|
|
46
|
+
sourceFiles,
|
|
47
|
+
[htmlBuildStep, zipBuildStep]
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
console.log('');
|
|
51
|
+
console.log(`Build Completed in ${((Date.now() - startTime)/1e3).toFixed(2)} seconds!`);
|
|
52
|
+
|
|
53
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
54
|
+
|
|
55
|
+
// A single build with its own source files, build steps, and output file
|
|
56
|
+
// - each build step is a callback that accepts a single filename
|
|
57
|
+
function Build(files=[], buildSteps=[])
|
|
58
|
+
{
|
|
59
|
+
// process each source file separately (don't concatenate modules!)
|
|
60
|
+
for (const file of files)
|
|
61
|
+
{
|
|
62
|
+
const outputFile = `${BUILD_FOLDER}/${file}`;
|
|
63
|
+
fs.copyFileSync(file, outputFile);
|
|
64
|
+
moduleFixStep(outputFile);
|
|
65
|
+
uglifyBuildStep(outputFile);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// execute build steps in order
|
|
69
|
+
for (const buildStep of buildSteps)
|
|
70
|
+
buildStep();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function moduleFixStep(filename)
|
|
74
|
+
{
|
|
75
|
+
console.log(`Fixing module imports in ${filename}...`);
|
|
76
|
+
|
|
77
|
+
let code = fs.readFileSync(filename, 'utf8');
|
|
78
|
+
|
|
79
|
+
// update the import path to use the local minified version
|
|
80
|
+
code = code.replace(/import \* as LJS from ['"].*littlejs\.esm(?:\.min)?\.js['"];?/g,
|
|
81
|
+
"import * as LJS from './littlejs.esm.min.js';");
|
|
82
|
+
|
|
83
|
+
// also fix relative imports to other game modules
|
|
84
|
+
code = code.replace(/from ['"]\.\.\//g, "from './");
|
|
85
|
+
|
|
86
|
+
fs.writeFileSync(filename, code);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function uglifyBuildStep(filename)
|
|
90
|
+
{
|
|
91
|
+
console.log('Running uglify...');
|
|
92
|
+
child_process.execSync(`npx uglifyjs ${filename} -c -m -o ${filename}`, {stdio: 'inherit'});
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
function htmlBuildStep()
|
|
96
|
+
{
|
|
97
|
+
console.log('Building html...');
|
|
98
|
+
|
|
99
|
+
// create html file with module script tag pointing to main game file
|
|
100
|
+
let buffer = ''
|
|
101
|
+
buffer += '<!DOCTYPE html>';
|
|
102
|
+
buffer += '<head>';
|
|
103
|
+
buffer += `<title>${PROGRAM_TITLE}</title>`;
|
|
104
|
+
buffer += '<meta charset=utf-8>';
|
|
105
|
+
buffer += '</head>';
|
|
106
|
+
buffer += '<body>';
|
|
107
|
+
buffer += '<script src="game.js" type="module"></script>';
|
|
108
|
+
buffer += '</body>';
|
|
109
|
+
|
|
110
|
+
// output html file
|
|
111
|
+
fs.writeFileSync(`${BUILD_FOLDER}/index.html`, buffer, {flag: 'w+'});
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
function zipBuildStep()
|
|
115
|
+
{
|
|
116
|
+
console.log('Zipping...');
|
|
117
|
+
const sources = ['index.html', 'littlejs.esm.min.js', ...sourceFiles, ...dataFiles];
|
|
118
|
+
const sourceList = sources.join(' ');
|
|
119
|
+
child_process.execSync(`npx bestzip ../${PROGRAM_NAME}.zip ${sourceList}`, {cwd:BUILD_FOLDER, stdio: 'inherit'});
|
|
120
|
+
console.log(`Size of ${PROGRAM_NAME}.zip: ${fs.statSync(`${PROGRAM_NAME}.zip`).size} bytes`);
|
|
121
|
+
};
|
|
@@ -72,7 +72,7 @@ addSetting('gravityScale', '', -1e9, 1e9, .1, 'How much does gravity effect
|
|
|
72
72
|
addSetting('particleConeAngle','', 0, 1e9, .1, 'Cone for start particle angle');
|
|
73
73
|
addSetting('fadeRate', '', 0, 1, .01,'How quickly particles fade in percent of life');
|
|
74
74
|
addSetting('randomness', '', 0, 1, .01,'Apply extra randomness percent');
|
|
75
|
-
addSetting('additive', 'checkbox',0,0,0, 'Should particles use
|
|
75
|
+
addSetting('additive', 'checkbox',0,0,0, 'Should particles use additive blend?');
|
|
76
76
|
addSetting('randomColorLinear','checkbox',0,0,0, 'Should color be randomized linearly?');
|
|
77
77
|
|
|
78
78
|
function makeEmitter()
|
|
@@ -127,7 +127,7 @@ function gameRender()
|
|
|
127
127
|
function gameRenderPost()
|
|
128
128
|
{
|
|
129
129
|
// draw to main canvas for hud rendering
|
|
130
|
-
const drawText = (text, x, y, size=40)
|
|
130
|
+
const drawText = (text, x, y, size=40)=>
|
|
131
131
|
{
|
|
132
132
|
const context = LJS.mainContext;
|
|
133
133
|
context.textAlign = 'center';
|
|
@@ -15,9 +15,6 @@ import * as LJS from '../../dist/littlejs.esm.js';
|
|
|
15
15
|
import * as GameLevel from './gameLevel.js';
|
|
16
16
|
const {vec2, hsl, rgb} = LJS;
|
|
17
17
|
|
|
18
|
-
// use low graphics mode on mobile devices
|
|
19
|
-
const lowGraphicsMode = LJS.isTouchDevice;
|
|
20
|
-
|
|
21
18
|
///////////////////////////////////////////////////////////////////////////////
|
|
22
19
|
// sound effects
|
|
23
20
|
|
|
@@ -36,8 +33,6 @@ export const sound_score = new LJS.Sound([,,783,,.03,.02,1,2,,,940,.03,,,
|
|
|
36
33
|
|
|
37
34
|
export const persistentParticleDestroyCallback = (particle)=>
|
|
38
35
|
{
|
|
39
|
-
if (lowGraphicsMode) return;
|
|
40
|
-
|
|
41
36
|
// draw particle to tile layer on death
|
|
42
37
|
LJS.ASSERT(!particle.tileInfo, 'quick draw to tile layer uses canvas 2d so must be untextured');
|
|
43
38
|
if (particle.groundObject)
|
|
@@ -51,7 +46,7 @@ export function makeDebris(pos, color = hsl(), amount = 50, size=.2, restitution
|
|
|
51
46
|
{
|
|
52
47
|
const color2 = color.lerp(hsl(), .5);
|
|
53
48
|
const emitter = new LJS.ParticleEmitter(
|
|
54
|
-
pos, 0,
|
|
49
|
+
pos, 0, .5, .1, amount/.1, 3.14, // pos, angle, size, time, rate, cone
|
|
55
50
|
0, // tileInfo
|
|
56
51
|
color, color2, // colorStartA, colorStartB
|
|
57
52
|
color, color2, // colorEndA, colorEndB
|
|
@@ -158,7 +153,7 @@ export function destroyTile(pos, makeSound = 1, cleanup = 1)
|
|
|
158
153
|
makeSound && sound_destroyObject.play(centerPos);
|
|
159
154
|
|
|
160
155
|
// set and clear tile
|
|
161
|
-
layer.
|
|
156
|
+
layer.clearData(pos, true);
|
|
162
157
|
layer.setCollisionData(pos, GameLevel.tileType_empty);
|
|
163
158
|
|
|
164
159
|
// cleanup neighbors and rebuild WebGL
|
|
@@ -199,7 +194,7 @@ export class Sky extends LJS.EngineObject
|
|
|
199
194
|
// draw stars
|
|
200
195
|
LJS.setBlendMode(true);
|
|
201
196
|
const random = new LJS.RandomGenerator(this.seed);
|
|
202
|
-
for (let i=
|
|
197
|
+
for (let i = 1e3; i--;)
|
|
203
198
|
{
|
|
204
199
|
const size = random.float(.5,2)**2;
|
|
205
200
|
const speed = random.float() < .9 ? random.float(5) : random.float(9,99);
|
|
@@ -274,9 +269,9 @@ export class ParallaxLayer extends LJS.CanvasLayer
|
|
|
274
269
|
const cameraDeltaFromCenter = LJS.cameraPos.subtract(levelCenter)
|
|
275
270
|
.divide(levelCenter.scale(-1).divide(parallax));
|
|
276
271
|
const scale = distance/LJS.cameraScale;
|
|
277
|
-
const
|
|
272
|
+
const positionOffset = vec2(0, 2-depth);
|
|
278
273
|
const cameraOffset = cameraDeltaFromCenter.scale(1/LJS.cameraScale);
|
|
279
|
-
this.pos = LJS.cameraPos.add(
|
|
274
|
+
this.pos = LJS.cameraPos.add(positionOffset).add(cameraOffset);
|
|
280
275
|
this.size = canvasSize.scale(scale);
|
|
281
276
|
super.render();
|
|
282
277
|
}
|
|
@@ -96,8 +96,8 @@ function loadLevelData()
|
|
|
96
96
|
new GameObjects.Coin(objectPos);
|
|
97
97
|
|
|
98
98
|
// replace with empty tile and empty collision
|
|
99
|
-
tileLayer.
|
|
100
|
-
tileLayer.
|
|
99
|
+
tileLayer.clearData(pos);
|
|
100
|
+
tileLayer.clearCollisionData(pos);
|
|
101
101
|
continue;
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -151,7 +151,7 @@ export function decorateTile(pos, tileLayer)
|
|
|
151
151
|
if (tileType <= 0)
|
|
152
152
|
{
|
|
153
153
|
// force it to clear if it is empty
|
|
154
|
-
tileType || tileLayer.
|
|
154
|
+
tileType || tileLayer.clearData(pos, true);
|
|
155
155
|
return;
|
|
156
156
|
}
|
|
157
157
|
if (tileType == tileType_breakable)
|
package/examples/puzzle/game.js
CHANGED
|
@@ -44,8 +44,8 @@ const tileColors =
|
|
|
44
44
|
];
|
|
45
45
|
const tileTypeCount = tileColors.length;
|
|
46
46
|
|
|
47
|
-
const getTile = (pos)
|
|
48
|
-
const setTile = (pos, data)
|
|
47
|
+
const getTile = (pos)=> level[pos.x + pos.y * levelSize.x];
|
|
48
|
+
const setTile = (pos, data)=> level[pos.x + pos.y * levelSize.x] = data;
|
|
49
49
|
|
|
50
50
|
///////////////////////////////////////////////////////////////////////////////
|
|
51
51
|
function gameReset()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!DOCTYPE html><meta charset=utf-8><body>
|
|
2
|
-
<script src=../../dist/littlejs.js?1.17.
|
|
2
|
+
<script src=../../dist/littlejs.js?1.17.10></script>
|
|
3
3
|
<script src=../../dist/box2d.wasm.js></script>
|
|
4
4
|
|
|
5
5
|
<!-- LittleJS Engine Source
|
|
@@ -38,6 +38,9 @@ canvasPixelated = false;
|
|
|
38
38
|
// disable watermark
|
|
39
39
|
debugWatermark = false;
|
|
40
40
|
|
|
41
|
+
// disable showing the engine version in console
|
|
42
|
+
showEngineVersion = false;
|
|
43
|
+
|
|
41
44
|
// these functions can be overridden for each example
|
|
42
45
|
function gameInit() {}
|
|
43
46
|
function gameUpdate() {}
|
|
@@ -3,10 +3,10 @@ const maxHitDistance = 6;
|
|
|
3
3
|
|
|
4
4
|
class Ball extends Box2dObject
|
|
5
5
|
{
|
|
6
|
-
constructor(
|
|
6
|
+
constructor(pos, number=0)
|
|
7
7
|
{
|
|
8
8
|
const color = hsl(number/9, 1, number? .5 : 1);
|
|
9
|
-
super(
|
|
9
|
+
super(pos, vec2(), 0, 0, color);
|
|
10
10
|
this.number = number;
|
|
11
11
|
|
|
12
12
|
// setup pool ball physics
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
let box2DTileLayer;
|
|
2
|
+
|
|
3
|
+
async function gameInit()
|
|
4
|
+
{
|
|
5
|
+
// setup box2d
|
|
6
|
+
await box2dInit();
|
|
7
|
+
cameraPos = vec2(16); // setup camera
|
|
8
|
+
gravity.y = -30; // enable gravity
|
|
9
|
+
canvasClearColor = hsl(0,0,.2); // background color
|
|
10
|
+
|
|
11
|
+
// create tile layer
|
|
12
|
+
const pos = vec2();
|
|
13
|
+
const tileLayer = new TileCollisionLayer(pos, vec2(32));
|
|
14
|
+
for (pos.x = tileLayer.size.x; pos.x--;)
|
|
15
|
+
for (pos.y = tileLayer.size.y; pos.y--;)
|
|
16
|
+
{
|
|
17
|
+
// check if tile should be solid
|
|
18
|
+
if (randBool(.7))
|
|
19
|
+
continue;
|
|
20
|
+
|
|
21
|
+
// set tile data
|
|
22
|
+
const tileIndex = 11;
|
|
23
|
+
const direction = randInt(4)
|
|
24
|
+
const mirror = randBool();
|
|
25
|
+
const color = randColor(WHITE, hsl(0,0,.2));
|
|
26
|
+
const data = new TileLayerData(tileIndex, direction, mirror, color);
|
|
27
|
+
tileLayer.setData(pos, data);
|
|
28
|
+
tileLayer.setCollisionData(pos);
|
|
29
|
+
}
|
|
30
|
+
tileLayer.redraw(); // redraw tile layer with new data
|
|
31
|
+
box2DTileLayer = new Box2dTileLayer(tileLayer);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function gameUpdate()
|
|
35
|
+
{
|
|
36
|
+
if (mouseWasPressed(0))
|
|
37
|
+
{
|
|
38
|
+
// clear tile that was clicked
|
|
39
|
+
box2DTileLayer.tileLayer.clearData(mousePos, true);
|
|
40
|
+
box2DTileLayer.tileLayer.clearCollisionData(mousePos);
|
|
41
|
+
box2DTileLayer.buildCollision();
|
|
42
|
+
|
|
43
|
+
// spawn box2d object at mouse position
|
|
44
|
+
const o = new Box2dObject(mousePos, vec2(), 0, 0, randColor());
|
|
45
|
+
const friction = .2, restitution = .5;
|
|
46
|
+
o.addCircle(rand(.5,1), vec2(), 1, friction, restitution);
|
|
47
|
+
}
|
|
48
|
+
}
|
package/examples/shorts/fps.js
CHANGED
|
@@ -33,7 +33,7 @@ function gameUpdate()
|
|
|
33
33
|
function gameRender()
|
|
34
34
|
{
|
|
35
35
|
{
|
|
36
|
-
// draw horizontal
|
|
36
|
+
// draw horizontal slices to create floor and ceiling
|
|
37
37
|
const h = 9;
|
|
38
38
|
let pos = vec2(), size = vec2(39, .15), color = rgb();
|
|
39
39
|
for (let y=-h; y<h; y+=.1)
|
package/examples/shorts/music.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const musicSound = new
|
|
2
|
-
let musicVolume =
|
|
1
|
+
const musicSound = new Sound('song.mp3');
|
|
2
|
+
let musicVolume = .8, musicInstance;
|
|
3
3
|
|
|
4
4
|
function gameInit()
|
|
5
5
|
{
|
|
@@ -15,15 +15,16 @@ function gameInit()
|
|
|
15
15
|
const center = mainCanvasSize.scale(.5);
|
|
16
16
|
musicPlayer = new UIObject(center, vec2(500, 220));
|
|
17
17
|
|
|
18
|
-
//
|
|
18
|
+
// information text
|
|
19
19
|
infoText = new UIText(vec2(0, -70), vec2(400, 50));
|
|
20
20
|
musicPlayer.addChild(infoText);
|
|
21
21
|
|
|
22
22
|
// volume slider
|
|
23
23
|
const volumeSlider = new UIScrollbar(vec2(0, -20), vec2(400, 30),
|
|
24
24
|
musicVolume, 'Music Volume');
|
|
25
|
+
volumeSlider.fillMode = true;
|
|
25
26
|
musicPlayer.addChild(volumeSlider);
|
|
26
|
-
volumeSlider.onChange = ()
|
|
27
|
+
volumeSlider.onChange = ()=>
|
|
27
28
|
{
|
|
28
29
|
musicVolume = volumeSlider.value;
|
|
29
30
|
musicInstance?.setVolume(musicVolume);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
let musicVolume =
|
|
2
|
+
let musicVolume = .8, musicSound, musicInstance;
|
|
3
3
|
|
|
4
4
|
function gameInit()
|
|
5
5
|
{
|
|
@@ -28,8 +28,9 @@ function gameInit()
|
|
|
28
28
|
// volume slider
|
|
29
29
|
const volumeSlider = new UIScrollbar(vec2(0, -20), vec2(400, 30),
|
|
30
30
|
musicVolume, 'Music Volume');
|
|
31
|
+
volumeSlider.fillMode = true;
|
|
31
32
|
musicPlayer.addChild(volumeSlider);
|
|
32
|
-
volumeSlider.onChange = ()
|
|
33
|
+
volumeSlider.onChange = ()=>
|
|
33
34
|
{
|
|
34
35
|
musicVolume = volumeSlider.value;
|
|
35
36
|
musicInstance?.setVolume(musicVolume);
|
|
@@ -89,7 +90,7 @@ function gameInit()
|
|
|
89
90
|
|
|
90
91
|
// create new sound from dropped file
|
|
91
92
|
const fileURL = URL.createObjectURL(file);
|
|
92
|
-
musicSound = new
|
|
93
|
+
musicSound = new Sound(fileURL, musicVolume);
|
|
93
94
|
dropZoneText.text = file.name;
|
|
94
95
|
|
|
95
96
|
// reset UI
|
|
@@ -64,8 +64,8 @@ class ParallaxLayer extends CanvasLayer
|
|
|
64
64
|
const distance = 3 + depth;
|
|
65
65
|
const parallax = vec2(.2, .05).scale(depth**2+1);
|
|
66
66
|
const cameraDeltaFromCenter = viewerPos.multiply(parallax);
|
|
67
|
-
const
|
|
68
|
-
this.pos = cameraDeltaFromCenter.add(
|
|
67
|
+
const positionOffset = vec2(0, 4-depth*3);
|
|
68
|
+
this.pos = cameraDeltaFromCenter.add(positionOffset)
|
|
69
69
|
this.size = canvasSize.scale(distance/cameraScale);
|
|
70
70
|
super.render();
|
|
71
71
|
}
|
|
@@ -7,7 +7,7 @@ class GameObject extends EngineObject
|
|
|
7
7
|
|
|
8
8
|
render()
|
|
9
9
|
{
|
|
10
|
-
// adjust draw
|
|
10
|
+
// adjust draw position to be at the bottom of the object
|
|
11
11
|
const drawSize = this.drawSize || this.size;
|
|
12
12
|
const offset = this.getUp(drawSize.y/2);
|
|
13
13
|
const pos = this.pos.add(offset);
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
</head><body>
|
|
8
8
|
|
|
9
9
|
<!-- LittleJS Engine -->
|
|
10
|
-
<script src=../../dist/littlejs.js?1.17.
|
|
10
|
+
<script src=../../dist/littlejs.js?1.17.9></script>
|
|
11
11
|
|
|
12
12
|
<!-- LittleJS Engine Source
|
|
13
13
|
<script src=../../src/engine.js></script>
|
|
@@ -32,4 +32,4 @@
|
|
|
32
32
|
-->
|
|
33
33
|
|
|
34
34
|
<!-- Add your game scripts here -->
|
|
35
|
-
<script src=game.js?1.17.
|
|
35
|
+
<script src=game.js?1.17.10></script>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "littlejsengine",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.10",
|
|
4
4
|
"description": "LittleJS - Tiny and Fast HTML5 Game Engine",
|
|
5
5
|
"main": "dist/littlejs.esm.js",
|
|
6
6
|
"types": "dist/littlejs.d.ts",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"bestzip": "^2.2.1",
|
|
37
|
+
"electron": "^38.2.0",
|
|
38
|
+
"electron-packager": "^17.1.2",
|
|
37
39
|
"google-closure-compiler": "~20230502.0.0",
|
|
38
40
|
"roadroller": "~2.1.0",
|
|
39
41
|
"typescript": "~5.1.6",
|
|
40
|
-
"uglify-js": "~3.17.4"
|
|
41
|
-
"electron": "^38.2.0",
|
|
42
|
-
"electron-packager": "^17.1.2"
|
|
42
|
+
"uglify-js": "~3.17.4"
|
|
43
43
|
}
|
|
44
|
-
}
|
|
44
|
+
}
|