littlejsengine 1.17.15 → 1.18.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/CLAUDE.md +1 -0
- package/README.md +13 -4
- package/dist/littlejs.d.ts +28 -9
- package/dist/littlejs.esm.js +111 -44
- package/dist/littlejs.esm.min.js +1 -1
- package/dist/littlejs.js +107 -43
- package/dist/littlejs.min.js +1 -1
- package/dist/littlejs.release.js +104 -40
- package/examples/box2d/game.js +2 -2
- package/examples/box2d/gameObjects.js +74 -0
- package/examples/box2d/scenes.js +7 -0
- package/examples/shorts/base.html +1 -1
- package/examples/shorts/music.js +1 -1
- package/examples/shorts/musicPlayer.js +3 -3
- package/examples/shorts/sequencer.js +1 -1
- package/examples/shorts/timers.js +1 -1
- package/examples/shorts/uiSystem.js +5 -5
- package/examples/starter/index.html +2 -2
- package/examples/stress/index.html +1 -1
- package/examples/uiSystem/game.js +6 -6
- package/package.json +1 -1
- package/plugins/box2d.js +18 -7
- package/plugins/pluginExport.js +1 -1
- package/plugins/uiSystem.js +15 -15
- package/src/engine.js +23 -6
- package/src/engineBuild.mjs +1 -1
- package/src/engineDebug.js +3 -3
- package/src/engineDraw.js +1 -0
- package/src/engineExport.js +3 -0
- package/src/engineInput.js +19 -8
- package/src/engineMath.js +1 -1
- package/src/engineObject.js +3 -3
- package/src/engineSettings.js +24 -0
package/plugins/box2d.js
CHANGED
|
@@ -119,7 +119,7 @@ class Box2dObject extends EngineObject
|
|
|
119
119
|
// draw non-edge fixtures
|
|
120
120
|
this.getFixtureList().forEach((fixture)=>
|
|
121
121
|
{
|
|
122
|
-
const shape = box2d.
|
|
122
|
+
const shape = box2d.castShapeObject(fixture.GetShape());
|
|
123
123
|
if (shape.GetType() !== box2d.instance.b2Shape.e_edge)
|
|
124
124
|
{
|
|
125
125
|
box2d.drawFixture(fixture, this.pos, this.angle, color, lineColor, lineWidth, useWebGL, context);
|
|
@@ -759,7 +759,7 @@ class Box2dJoint
|
|
|
759
759
|
constructor(jointDef)
|
|
760
760
|
{
|
|
761
761
|
/** @property {Object} - The Box2d joint */
|
|
762
|
-
this.box2dJoint = box2d.
|
|
762
|
+
this.box2dJoint = box2d.castJointObject(box2d.world.CreateJoint(jointDef));
|
|
763
763
|
}
|
|
764
764
|
|
|
765
765
|
/** Destroy this joint */
|
|
@@ -1044,7 +1044,7 @@ class Box2dRevoluteJoint extends Box2dJoint
|
|
|
1044
1044
|
|
|
1045
1045
|
/** Enable/disable the joint limit
|
|
1046
1046
|
* @param {boolean} [enable] */
|
|
1047
|
-
enableLimit(enable=true) { return this.box2dJoint.
|
|
1047
|
+
enableLimit(enable=true) { return this.box2dJoint.EnableLimit(enable); }
|
|
1048
1048
|
|
|
1049
1049
|
/** Get the lower joint limit
|
|
1050
1050
|
* @return {number} */
|
|
@@ -1202,7 +1202,7 @@ class Box2dPrismaticJoint extends Box2dJoint
|
|
|
1202
1202
|
|
|
1203
1203
|
/** Enable/disable the joint limit
|
|
1204
1204
|
* @param {boolean} [enable] */
|
|
1205
|
-
enableLimit(enable=true) { return this.box2dJoint.
|
|
1205
|
+
enableLimit(enable=true) { return this.box2dJoint.EnableLimit(enable); }
|
|
1206
1206
|
|
|
1207
1207
|
/** Get the lower joint limit
|
|
1208
1208
|
* @return {number} */
|
|
@@ -1816,7 +1816,7 @@ class Box2dPlugin
|
|
|
1816
1816
|
* @param {CanvasRenderingContext2D} [context] */
|
|
1817
1817
|
drawFixture(fixture, pos, angle, color=WHITE, lineColor=BLACK, lineWidth=.1, useWebgl, context)
|
|
1818
1818
|
{
|
|
1819
|
-
const shape = box2d.
|
|
1819
|
+
const shape = box2d.castShapeObject(fixture.GetShape());
|
|
1820
1820
|
switch (shape.GetType())
|
|
1821
1821
|
{
|
|
1822
1822
|
case box2d.instance.b2Shape.e_polygon:
|
|
@@ -1874,9 +1874,9 @@ class Box2dPlugin
|
|
|
1874
1874
|
* @param {Object} o */
|
|
1875
1875
|
isNull(o) { return !box2d.instance.getPointer(o); }
|
|
1876
1876
|
|
|
1877
|
-
/** casts a box2d object to
|
|
1877
|
+
/** casts a box2d object to a shape type
|
|
1878
1878
|
* @param {Object} o */
|
|
1879
|
-
|
|
1879
|
+
castShapeObject(o)
|
|
1880
1880
|
{
|
|
1881
1881
|
switch (o.GetType())
|
|
1882
1882
|
{
|
|
@@ -1888,6 +1888,17 @@ class Box2dPlugin
|
|
|
1888
1888
|
return box2d.instance.castObject(o, box2d.instance.b2PolygonShape);
|
|
1889
1889
|
case box2d.instance.b2Shape.e_chain:
|
|
1890
1890
|
return box2d.instance.castObject(o, box2d.instance.b2ChainShape);
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
ASSERT(false, 'Unknown box2d object type');
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
/** casts a box2d object to a joint type
|
|
1897
|
+
* @param {Object} o */
|
|
1898
|
+
castJointObject(o)
|
|
1899
|
+
{
|
|
1900
|
+
switch (o.GetType())
|
|
1901
|
+
{
|
|
1891
1902
|
case box2d.instance.e_revoluteJoint:
|
|
1892
1903
|
return box2d.instance.castObject(o, box2d.instance.b2RevoluteJoint);
|
|
1893
1904
|
case box2d.instance.e_prismaticJoint:
|
package/plugins/pluginExport.js
CHANGED
package/plugins/uiSystem.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - Buttons
|
|
8
8
|
* - Checkboxes
|
|
9
9
|
* - Images
|
|
10
|
-
* -
|
|
10
|
+
* - Sliders
|
|
11
11
|
* - Video
|
|
12
12
|
* @namespace UISystem
|
|
13
13
|
*/
|
|
@@ -1206,7 +1206,7 @@ class UICheckbox extends UIObject
|
|
|
1206
1206
|
ASSERT(isString(text), 'ui checkbox must be a string');
|
|
1207
1207
|
ASSERT(isColor(color), 'ui checkbox color must be a color');
|
|
1208
1208
|
|
|
1209
|
-
/** @property {boolean} - Current percentage value of this
|
|
1209
|
+
/** @property {boolean} - Current percentage value of this slider 0-1 */
|
|
1210
1210
|
this.checked = checked;
|
|
1211
1211
|
// set properties
|
|
1212
1212
|
this.text = text;
|
|
@@ -1241,13 +1241,13 @@ class UICheckbox extends UIObject
|
|
|
1241
1241
|
|
|
1242
1242
|
///////////////////////////////////////////////////////////////////////////////
|
|
1243
1243
|
/**
|
|
1244
|
-
*
|
|
1244
|
+
* UISlider - A UI object that acts as a slider or scrollbar
|
|
1245
1245
|
* @extends UIObject
|
|
1246
1246
|
* @memberof UISystem
|
|
1247
1247
|
*/
|
|
1248
|
-
class
|
|
1248
|
+
class UISlider extends UIObject
|
|
1249
1249
|
{
|
|
1250
|
-
/** Create a
|
|
1250
|
+
/** Create a UISlider object
|
|
1251
1251
|
* @param {Vector2} [pos]
|
|
1252
1252
|
* @param {Vector2} [size]
|
|
1253
1253
|
* @param {number} [value]
|
|
@@ -1259,14 +1259,14 @@ class UIScrollbar extends UIObject
|
|
|
1259
1259
|
{
|
|
1260
1260
|
super(pos, size);
|
|
1261
1261
|
|
|
1262
|
-
ASSERT(isNumber(value), 'ui
|
|
1263
|
-
ASSERT(isString(text), 'ui
|
|
1264
|
-
ASSERT(isColor(color), 'ui
|
|
1265
|
-
ASSERT(isColor(handleColor), 'ui
|
|
1262
|
+
ASSERT(isNumber(value), 'ui slider value must be a number');
|
|
1263
|
+
ASSERT(isString(text), 'ui slider must be a string');
|
|
1264
|
+
ASSERT(isColor(color), 'ui slider color must be a color');
|
|
1265
|
+
ASSERT(isColor(handleColor), 'ui slider handleColor must be a color');
|
|
1266
1266
|
|
|
1267
|
-
/** @property {number} - Current percentage value of this
|
|
1267
|
+
/** @property {number} - Current percentage value of this slider 0-1 */
|
|
1268
1268
|
this.value = value;
|
|
1269
|
-
/** @property {Color} - Color for the handle part of the
|
|
1269
|
+
/** @property {Color} - Color for the handle part of the slider */
|
|
1270
1270
|
this.handleColor = handleColor.copy();
|
|
1271
1271
|
/** @property {boolean} - Should it fill up like a progress bar? */
|
|
1272
1272
|
this.fillMode = false;
|
|
@@ -1285,7 +1285,7 @@ class UIScrollbar extends UIObject
|
|
|
1285
1285
|
const oldValue = this.value;
|
|
1286
1286
|
if (this.isActiveObject())
|
|
1287
1287
|
{
|
|
1288
|
-
// handle horizontal or vertical
|
|
1288
|
+
// handle horizontal or vertical slider
|
|
1289
1289
|
const isHorizontal = this.size.x > this.size.y;
|
|
1290
1290
|
const handleSize = isHorizontal ? this.size.y : this.size.x;
|
|
1291
1291
|
const barSize = isHorizontal ? this.size.x : this.size.y;
|
|
@@ -1313,7 +1313,7 @@ class UIScrollbar extends UIObject
|
|
|
1313
1313
|
{
|
|
1314
1314
|
super.render();
|
|
1315
1315
|
|
|
1316
|
-
// handle horizontal or vertical
|
|
1316
|
+
// handle horizontal or vertical slider
|
|
1317
1317
|
const isHorizontal = this.size.x > this.size.y;
|
|
1318
1318
|
const barWidth = isHorizontal ? this.size.x : this.size.y;
|
|
1319
1319
|
const handleWidth = isHorizontal ? this.size.y : this.size.x;
|
|
@@ -1331,7 +1331,7 @@ class UIScrollbar extends UIObject
|
|
|
1331
1331
|
}
|
|
1332
1332
|
else
|
|
1333
1333
|
{
|
|
1334
|
-
// draw the
|
|
1334
|
+
// draw the slider handle
|
|
1335
1335
|
const value = clamp(isHorizontal ? this.value : 1 - this.value);
|
|
1336
1336
|
const p = (barWidth - handleWidth) * (value - .5);
|
|
1337
1337
|
const pos = this.pos.add(isHorizontal ? vec2(p, 0) : vec2(0, p));
|
|
@@ -1340,7 +1340,7 @@ class UIScrollbar extends UIObject
|
|
|
1340
1340
|
uiSystem.drawRect(pos, drawSize, color, this.lineWidth, this.lineColor, this.cornerRadius, this.gradientColor);
|
|
1341
1341
|
}
|
|
1342
1342
|
|
|
1343
|
-
// draw the text scaled to fit on the
|
|
1343
|
+
// draw the text scaled to fit on the slider
|
|
1344
1344
|
const textSize = this.getTextSize();
|
|
1345
1345
|
uiSystem.drawText(this.text, this.pos, textSize,
|
|
1346
1346
|
this.textColor, this.textLineWidth, this.textLineColor, this.align, this.font, this.fontStyle, true, this.textShadow);
|
package/src/engine.js
CHANGED
|
@@ -32,7 +32,7 @@ const engineName = 'LittleJS';
|
|
|
32
32
|
* @type {string}
|
|
33
33
|
* @default
|
|
34
34
|
* @memberof Engine */
|
|
35
|
-
const engineVersion = '1.
|
|
35
|
+
const engineVersion = '1.18.1';
|
|
36
36
|
|
|
37
37
|
/** Frames per second to update
|
|
38
38
|
* @type {number}
|
|
@@ -315,12 +315,17 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
315
315
|
}
|
|
316
316
|
else
|
|
317
317
|
{
|
|
318
|
+
// apply device pixel ratio for crisp rendering
|
|
319
|
+
const dpr = canvasPixelRatio ?? (devicePixelRatio || 1);
|
|
320
|
+
const viewWidth = innerWidth * dpr | 0;
|
|
321
|
+
const viewHeight = innerHeight * dpr | 0;
|
|
322
|
+
|
|
318
323
|
// get main canvas size based on window size
|
|
319
|
-
mainCanvasSize.x = min(
|
|
320
|
-
mainCanvasSize.y = min(
|
|
324
|
+
mainCanvasSize.x = min(viewWidth, canvasMaxSize.x);
|
|
325
|
+
mainCanvasSize.y = min(viewHeight, canvasMaxSize.y);
|
|
321
326
|
|
|
322
327
|
// responsive aspect ratio with native resolution
|
|
323
|
-
const innerAspect =
|
|
328
|
+
const innerAspect = viewWidth / viewHeight;
|
|
324
329
|
ASSERT(canvasMinAspect <= canvasMaxAspect);
|
|
325
330
|
if (canvasMaxAspect && innerAspect > canvasMaxAspect)
|
|
326
331
|
{
|
|
@@ -334,6 +339,17 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
|
|
|
334
339
|
const h = mainCanvasSize.x / canvasMinAspect | 0;
|
|
335
340
|
mainCanvasSize.y = min(h, canvasMaxSize.y);
|
|
336
341
|
}
|
|
342
|
+
|
|
343
|
+
// set CSS display size so backing store renders at viewport size
|
|
344
|
+
const cssW = (mainCanvasSize.x / dpr | 0) + 'px';
|
|
345
|
+
const cssH = (mainCanvasSize.y / dpr | 0) + 'px';
|
|
346
|
+
mainCanvas.style.width = cssW;
|
|
347
|
+
mainCanvas.style.height = cssH;
|
|
348
|
+
if (glCanvas)
|
|
349
|
+
{
|
|
350
|
+
glCanvas.style.width = cssW;
|
|
351
|
+
glCanvas.style.height = cssH;
|
|
352
|
+
}
|
|
337
353
|
}
|
|
338
354
|
|
|
339
355
|
// clear main canvas and set size
|
|
@@ -553,8 +569,9 @@ function drawEngineLogo(t)
|
|
|
553
569
|
|
|
554
570
|
// LittleJS Logo and Splash Screen
|
|
555
571
|
const x = mainContext;
|
|
556
|
-
const
|
|
557
|
-
const
|
|
572
|
+
const dpr = canvasPixelRatio ?? (devicePixelRatio || 1);
|
|
573
|
+
const w = mainCanvas.width = innerWidth * dpr;
|
|
574
|
+
const h = mainCanvas.height = innerHeight * dpr;
|
|
558
575
|
{
|
|
559
576
|
// background
|
|
560
577
|
const p3 = percent(t, 1, .8);
|
package/src/engineBuild.mjs
CHANGED
|
@@ -61,7 +61,7 @@ const license = '// LittleJS Engine - MIT License - Copyright 2021 Frank Force\n
|
|
|
61
61
|
'// https://github.com/KilledByAPixel/LittleJS\n\n';
|
|
62
62
|
|
|
63
63
|
console.log(asciiArt);
|
|
64
|
-
console.log('
|
|
64
|
+
console.log('Choo Choo... Building LittleJS Engine!');
|
|
65
65
|
const startTime = Date.now();
|
|
66
66
|
|
|
67
67
|
try
|
package/src/engineDebug.js
CHANGED
|
@@ -266,6 +266,8 @@ function debugShowErrors()
|
|
|
266
266
|
|
|
267
267
|
function debugInit()
|
|
268
268
|
{
|
|
269
|
+
if (showEngineVersion)
|
|
270
|
+
console.warn("LittleJS DEBUG build loaded. Use the release build for production.");
|
|
269
271
|
}
|
|
270
272
|
|
|
271
273
|
function debugUpdate()
|
|
@@ -276,8 +278,6 @@ function debugUpdate()
|
|
|
276
278
|
debugOverlay = !debugOverlay;
|
|
277
279
|
if (debugOverlay)
|
|
278
280
|
{
|
|
279
|
-
if (keyWasPressed('Digit0'))
|
|
280
|
-
debugWatermark = !debugWatermark;
|
|
281
281
|
if (keyWasPressed('Digit1'))
|
|
282
282
|
debugPhysics = !debugPhysics, debugParticles = false;
|
|
283
283
|
if (keyWasPressed('Digit2'))
|
|
@@ -565,7 +565,7 @@ function debugRenderPost()
|
|
|
565
565
|
return;
|
|
566
566
|
}
|
|
567
567
|
|
|
568
|
-
if (!debugWatermark) return;
|
|
568
|
+
if (!debugWatermark && !debugOverlay) return;
|
|
569
569
|
|
|
570
570
|
// update fps display
|
|
571
571
|
mainContext.textAlign = 'right';
|
package/src/engineDraw.js
CHANGED
|
@@ -110,6 +110,7 @@ function tile(index=new Vector2, size=tileDefaultSize, texture=0, padding=tileDe
|
|
|
110
110
|
const textureInfo = typeof texture === 'number' ?
|
|
111
111
|
textureInfos[texture] : texture;
|
|
112
112
|
ASSERT(textureInfo instanceof TextureInfo, 'tile texture is not loaded');
|
|
113
|
+
ASSERT(textureInfo.size.x > 0, 'tile texture is not loaded');
|
|
113
114
|
|
|
114
115
|
// get the position of the tile
|
|
115
116
|
const sizePaddedX = size.x + padding*2;
|
package/src/engineExport.js
CHANGED
|
@@ -59,6 +59,7 @@ export
|
|
|
59
59
|
canvasFixedSize,
|
|
60
60
|
canvasPixelated,
|
|
61
61
|
tilesPixelated,
|
|
62
|
+
canvasPixelRatio,
|
|
62
63
|
fontDefault,
|
|
63
64
|
showSplashScreen,
|
|
64
65
|
headlessMode,
|
|
@@ -83,6 +84,7 @@ export
|
|
|
83
84
|
touchGamepadAnalog,
|
|
84
85
|
touchGamepadSize,
|
|
85
86
|
touchGamepadAlpha,
|
|
87
|
+
touchGamepadDisplayTime,
|
|
86
88
|
vibrateEnable,
|
|
87
89
|
soundEnable,
|
|
88
90
|
soundVolume,
|
|
@@ -104,6 +106,7 @@ export
|
|
|
104
106
|
setCanvasFixedSize,
|
|
105
107
|
setCanvasPixelated,
|
|
106
108
|
setTilesPixelated,
|
|
109
|
+
setCanvasPixelRatio,
|
|
107
110
|
setFontDefault,
|
|
108
111
|
setShowSplashScreen,
|
|
109
112
|
setHeadlessMode,
|
package/src/engineInput.js
CHANGED
|
@@ -321,7 +321,7 @@ function inputInit()
|
|
|
321
321
|
document.addEventListener('mouseup', onMouseUp);
|
|
322
322
|
document.addEventListener('mousemove', onMouseMove);
|
|
323
323
|
document.addEventListener('mouseleave', onMouseLeave);
|
|
324
|
-
document.addEventListener('wheel', onMouseWheel);
|
|
324
|
+
document.addEventListener('wheel', onMouseWheel, { passive: false });
|
|
325
325
|
document.addEventListener('contextmenu', onContextMenu);
|
|
326
326
|
document.addEventListener('blur', onBlur);
|
|
327
327
|
|
|
@@ -340,7 +340,7 @@ function inputInit()
|
|
|
340
340
|
}
|
|
341
341
|
|
|
342
342
|
// try to prevent default browser handling of input
|
|
343
|
-
if (!inputPreventDefault || !
|
|
343
|
+
if (!inputPreventDefault || !e.cancelable || !document.hasFocus()) return;
|
|
344
344
|
|
|
345
345
|
// don't break browser shortcuts
|
|
346
346
|
if (e.ctrlKey || e.metaKey || e.altKey) return;
|
|
@@ -399,7 +399,7 @@ function inputInit()
|
|
|
399
399
|
mousePosScreen = mouseEventToScreen(vec2(e.x,e.y));
|
|
400
400
|
mouseDeltaScreen = mouseDeltaScreen.add(mousePosScreen.subtract(mousePosScreenLast));
|
|
401
401
|
|
|
402
|
-
if (inputPreventDefault &&
|
|
402
|
+
if (inputPreventDefault && e.cancelable && document.hasFocus())
|
|
403
403
|
e.preventDefault();
|
|
404
404
|
}
|
|
405
405
|
function onMouseUp(e)
|
|
@@ -421,7 +421,12 @@ function inputInit()
|
|
|
421
421
|
mouseDeltaScreen = mouseDeltaScreen.add(movement);
|
|
422
422
|
}
|
|
423
423
|
function onMouseLeave() { mouseInWindow = false; } // mouse moved off window
|
|
424
|
-
function onMouseWheel(e)
|
|
424
|
+
function onMouseWheel(e)
|
|
425
|
+
{
|
|
426
|
+
mouseWheel = e.ctrlKey ? 0 : sign(e.deltaY);
|
|
427
|
+
if (inputPreventDefault && e.cancelable && document.hasFocus())
|
|
428
|
+
e.preventDefault(); // prevent page scrolling
|
|
429
|
+
}
|
|
425
430
|
function onContextMenu(e) { e.preventDefault(); } // prevent right click menu
|
|
426
431
|
function onBlur() { inputClear(); } // reset input when focus is lost
|
|
427
432
|
|
|
@@ -471,7 +476,7 @@ function inputInit()
|
|
|
471
476
|
wasTouching = touching;
|
|
472
477
|
|
|
473
478
|
// prevent default handling like copy, magnifier lens, and scrolling
|
|
474
|
-
if (inputPreventDefault &&
|
|
479
|
+
if (inputPreventDefault && e.cancelable && document.hasFocus())
|
|
475
480
|
e.preventDefault();
|
|
476
481
|
|
|
477
482
|
// must return true so the document will get focus
|
|
@@ -629,7 +634,13 @@ function inputUpdate()
|
|
|
629
634
|
}
|
|
630
635
|
|
|
631
636
|
// return if gamepads are disabled or not supported
|
|
632
|
-
|
|
637
|
+
try {
|
|
638
|
+
// protect against getGamepads disallowed security error
|
|
639
|
+
if (!gamepadsEnable || !navigator?.getGamepads)
|
|
640
|
+
return;
|
|
641
|
+
} catch(e) {
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
633
644
|
|
|
634
645
|
// only poll gamepads when focused or in debug mode
|
|
635
646
|
if (!debug && !document.hasFocus()) return;
|
|
@@ -727,10 +738,10 @@ function inputRender()
|
|
|
727
738
|
function touchGamepadRender()
|
|
728
739
|
{
|
|
729
740
|
if (!touchInputEnable || !isTouchDevice || headlessMode) return;
|
|
730
|
-
if (!touchGamepadEnable || !touchGamepadTimer.isSet()) return;
|
|
741
|
+
if (!touchGamepadEnable || !touchGamepadTimer.isSet() && touchGamepadDisplayTime) return;
|
|
731
742
|
|
|
732
743
|
// fade off when not touching or paused
|
|
733
|
-
const alpha = percent(touchGamepadTimer.get(),
|
|
744
|
+
const alpha = touchGamepadDisplayTime ? percent(touchGamepadTimer.get(), touchGamepadDisplayTime+1, touchGamepadDisplayTime) : 1;
|
|
734
745
|
if (!alpha || paused) return;
|
|
735
746
|
|
|
736
747
|
// setup the canvas
|
package/src/engineMath.js
CHANGED
|
@@ -327,7 +327,7 @@ function lineTest(posStart, posEnd, testFunction, normal)
|
|
|
327
327
|
// get ray direction and length
|
|
328
328
|
const dx = posEnd.x - posStart.x;
|
|
329
329
|
const dy = posEnd.y - posStart.y;
|
|
330
|
-
const totalLength =
|
|
330
|
+
const totalLength = (dx*dx + dy*dy)**.5;
|
|
331
331
|
if (!totalLength) return;
|
|
332
332
|
|
|
333
333
|
// current integer cell we are in
|
package/src/engineObject.js
CHANGED
|
@@ -212,10 +212,10 @@ class EngineObject
|
|
|
212
212
|
// if already was touching, try to push away
|
|
213
213
|
const deltaPos = oldPos.subtract(o.pos);
|
|
214
214
|
const length = deltaPos.length();
|
|
215
|
-
const pushAwayAccel = .001;
|
|
216
|
-
const velocity = length < .
|
|
215
|
+
const pushAwayAccel = .001;
|
|
216
|
+
const velocity = length < .001 ? vec2(0,1) : deltaPos.scale(pushAwayAccel/length);
|
|
217
217
|
this.velocity = this.velocity.add(velocity);
|
|
218
|
-
if (o.mass) // push away if not fixed
|
|
218
|
+
if (o.mass) // push away other object if not fixed
|
|
219
219
|
o.velocity = o.velocity.subtract(velocity);
|
|
220
220
|
|
|
221
221
|
debugPhysics && debugOverlap(this.pos, this.size, o.pos, o.size, '#f00');
|
package/src/engineSettings.js
CHANGED
|
@@ -82,6 +82,13 @@ let canvasPixelated = false;
|
|
|
82
82
|
* @memberof Settings */
|
|
83
83
|
let tilesPixelated = true;
|
|
84
84
|
|
|
85
|
+
/** Scale factor applied to the canvas backing store for native-resolution rendering.
|
|
86
|
+
* Pass 1 for no scaling, a number for an explicit ratio, or undefined to track devicePixelRatio each frame.
|
|
87
|
+
* @type {number|undefined}
|
|
88
|
+
* @default
|
|
89
|
+
* @memberof Settings */
|
|
90
|
+
let canvasPixelRatio = 1;
|
|
91
|
+
|
|
85
92
|
/** Default font used for text rendering
|
|
86
93
|
* @type {string}
|
|
87
94
|
* @default
|
|
@@ -260,6 +267,12 @@ let touchGamepadSize = 99;
|
|
|
260
267
|
* @memberof Settings */
|
|
261
268
|
let touchGamepadAlpha = .3;
|
|
262
269
|
|
|
270
|
+
/** How long to display the touch gamepad on screen in seconds, set to 0 to always display
|
|
271
|
+
* @type {number}
|
|
272
|
+
* @default
|
|
273
|
+
* @memberof Settings */
|
|
274
|
+
let touchGamepadDisplayTime = 3;
|
|
275
|
+
|
|
263
276
|
/** Allow vibration hardware if it exists
|
|
264
277
|
* @type {boolean}
|
|
265
278
|
* @default
|
|
@@ -388,6 +401,12 @@ function setCanvasPixelated(pixelated)
|
|
|
388
401
|
* @memberof Settings */
|
|
389
402
|
function setTilesPixelated(pixelated) { tilesPixelated = pixelated; }
|
|
390
403
|
|
|
404
|
+
/** Set the canvas pixel ratio.
|
|
405
|
+
* Pass a number for an explicit ratio, or call with no argument to track devicePixelRatio each frame.
|
|
406
|
+
* @param {number} [pixelRatio]
|
|
407
|
+
* @memberof Settings */
|
|
408
|
+
function setCanvasPixelRatio(pixelRatio) { canvasPixelRatio = pixelRatio; }
|
|
409
|
+
|
|
391
410
|
/** Set default font used for text rendering
|
|
392
411
|
* @param {string} font
|
|
393
412
|
* @memberof Settings */
|
|
@@ -534,6 +553,11 @@ function setTouchGamepadSize(size) { touchGamepadSize = size; }
|
|
|
534
553
|
* @memberof Settings */
|
|
535
554
|
function setTouchGamepadAlpha(alpha) { touchGamepadAlpha = alpha; }
|
|
536
555
|
|
|
556
|
+
/** Set how long to display the touch gamepad on screen in seconds, set to 0 to always display
|
|
557
|
+
* @param {number} time
|
|
558
|
+
* @memberof Settings */
|
|
559
|
+
function setTouchGamepadDisplayTime(time) { touchGamepadDisplayTime = time; }
|
|
560
|
+
|
|
537
561
|
/** Set to allow vibration hardware if it exists
|
|
538
562
|
* @param {boolean} enable
|
|
539
563
|
* @memberof Settings */
|