Skip to content

Commit 49ca521

Browse files
1.18.9
1 parent 39697e8 commit 49ca521

10 files changed

Lines changed: 99 additions & 25 deletions

File tree

dist/littlejs.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5308,6 +5308,14 @@ declare module "littlejsengine" {
53085308
* @param {PathFinderNode[]} path
53095309
* @private */
53105310
private smoothPathStringPull;
5311+
/** Drop any middle node that lies exactly on the line through its two
5312+
* neighbors. Backstop for the smoothing passes — the corners pass
5313+
* intentionally keeps truly-straight runs, and the string-pulling pass
5314+
* checks collinearity against the original path, not the in-progress
5315+
* result, so it can leave 3+ collinear nodes in some edge cases.
5316+
* @param {PathFinderNode[]} path
5317+
* @private */
5318+
private dropCollinearNodes;
53115319
/** Lookup helper: true when the node at tile coords (x, y) is in-bounds
53125320
* and clear (walkable, zero-cost). Used by isLineClear's hot path.
53135321
* @param {number} x

dist/littlejs.esm.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
207207
const combinedScale = timeScale * debugScale;
208208
frameTimeDeltaMS *= combinedScale;
209209
frameTimeBufferMS += paused ? 0 : frameTimeDeltaMS;
210-
if (debugScale <= 1)
210+
if (combinedScale <= 1)
211211
frameTimeBufferMS = min(frameTimeBufferMS, 50); // clamp min framerate
212212

213213
let wasUpdated = false;
@@ -14117,10 +14117,10 @@ class PathFinder
1411714117

1411814118
// Tunables (public, freely re-assignable).
1411914119
this.heuristicWeight = 1;
14120-
this.maxLoop = 500;
14120+
this.maxLoop = 1e3;
1412114121
this.smoothPath = true;
1412214122
this.debug = false;
14123-
this.debugTime = 2;
14123+
this.debugTime = 1;
1412414124

1412514125
// Pre-allocate the node array — one node per tile, reused across calls.
1412614126
this.nodes = new Array(this.size.x * this.size.y);
@@ -14296,9 +14296,12 @@ class PathFinder
1429614296
// Best path so far through neighbor — record it.
1429714297
neighbor.parent = current;
1429814298
neighbor.g = tentativeG;
14299-
const gdx = endNode.pos.x - neighbor.pos.x;
14300-
const gdy = endNode.pos.y - neighbor.pos.y;
14301-
neighbor.f = neighbor.g + (gdx * gdx + gdy * gdy) * this.heuristicWeight;
14299+
// Octile heuristic — tightest admissible distance for an
14300+
// 8-connected grid with cardinal cost 1 and diagonal cost √2.
14301+
const adx = abs(endNode.pos.x - neighbor.pos.x);
14302+
const ady = abs(endNode.pos.y - neighbor.pos.y);
14303+
const h = max(adx, ady) + (Math.SQRT2 - 1) * min(adx, ady);
14304+
neighbor.f = neighbor.g + h * this.heuristicWeight;
1430214305
}
1430314306
}
1430414307

@@ -14580,6 +14583,24 @@ class PathFinder
1458014583
path.push(original[original.length - 1]);
1458114584
}
1458214585

14586+
/** Drop any middle node that lies exactly on the line through its two
14587+
* neighbors. Backstop for the smoothing passes — the corners pass
14588+
* intentionally keeps truly-straight runs, and the string-pulling pass
14589+
* checks collinearity against the original path, not the in-progress
14590+
* result, so it can leave 3+ collinear nodes in some edge cases.
14591+
* @param {PathFinderNode[]} path
14592+
* @private */
14593+
dropCollinearNodes(path)
14594+
{
14595+
for (let i = path.length - 2; i >= 1; --i)
14596+
{
14597+
const a = path[i - 1], b = path[i], c = path[i + 1];
14598+
if ((b.pos.x - a.pos.x) * (c.pos.y - a.pos.y) ===
14599+
(b.pos.y - a.pos.y) * (c.pos.x - a.pos.x))
14600+
path.splice(i, 1);
14601+
}
14602+
}
14603+
1458314604
/** Lookup helper: true when the node at tile coords (x, y) is in-bounds
1458414605
* and clear (walkable, zero-cost). Used by isLineClear's hot path.
1458514606
* @param {number} x
@@ -14747,6 +14768,7 @@ class PathFinder
1474714768
{
1474814769
this.smoothPathCorners(nodePath);
1474914770
this.smoothPathStringPull(nodePath);
14771+
this.dropCollinearNodes(nodePath);
1475014772
}
1475114773

1475214774
// Convert to world-space Vector2 path. Return copies, not live node

dist/littlejs.esm.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/littlejs.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
207207
const combinedScale = timeScale * debugScale;
208208
frameTimeDeltaMS *= combinedScale;
209209
frameTimeBufferMS += paused ? 0 : frameTimeDeltaMS;
210-
if (debugScale <= 1)
210+
if (combinedScale <= 1)
211211
frameTimeBufferMS = min(frameTimeBufferMS, 50); // clamp min framerate
212212

213213
let wasUpdated = false;
@@ -14117,10 +14117,10 @@ class PathFinder
1411714117

1411814118
// Tunables (public, freely re-assignable).
1411914119
this.heuristicWeight = 1;
14120-
this.maxLoop = 500;
14120+
this.maxLoop = 1e3;
1412114121
this.smoothPath = true;
1412214122
this.debug = false;
14123-
this.debugTime = 2;
14123+
this.debugTime = 1;
1412414124

1412514125
// Pre-allocate the node array — one node per tile, reused across calls.
1412614126
this.nodes = new Array(this.size.x * this.size.y);
@@ -14296,9 +14296,12 @@ class PathFinder
1429614296
// Best path so far through neighbor — record it.
1429714297
neighbor.parent = current;
1429814298
neighbor.g = tentativeG;
14299-
const gdx = endNode.pos.x - neighbor.pos.x;
14300-
const gdy = endNode.pos.y - neighbor.pos.y;
14301-
neighbor.f = neighbor.g + (gdx * gdx + gdy * gdy) * this.heuristicWeight;
14299+
// Octile heuristic — tightest admissible distance for an
14300+
// 8-connected grid with cardinal cost 1 and diagonal cost √2.
14301+
const adx = abs(endNode.pos.x - neighbor.pos.x);
14302+
const ady = abs(endNode.pos.y - neighbor.pos.y);
14303+
const h = max(adx, ady) + (Math.SQRT2 - 1) * min(adx, ady);
14304+
neighbor.f = neighbor.g + h * this.heuristicWeight;
1430214305
}
1430314306
}
1430414307

@@ -14580,6 +14583,24 @@ class PathFinder
1458014583
path.push(original[original.length - 1]);
1458114584
}
1458214585

14586+
/** Drop any middle node that lies exactly on the line through its two
14587+
* neighbors. Backstop for the smoothing passes — the corners pass
14588+
* intentionally keeps truly-straight runs, and the string-pulling pass
14589+
* checks collinearity against the original path, not the in-progress
14590+
* result, so it can leave 3+ collinear nodes in some edge cases.
14591+
* @param {PathFinderNode[]} path
14592+
* @private */
14593+
dropCollinearNodes(path)
14594+
{
14595+
for (let i = path.length - 2; i >= 1; --i)
14596+
{
14597+
const a = path[i - 1], b = path[i], c = path[i + 1];
14598+
if ((b.pos.x - a.pos.x) * (c.pos.y - a.pos.y) ===
14599+
(b.pos.y - a.pos.y) * (c.pos.x - a.pos.x))
14600+
path.splice(i, 1);
14601+
}
14602+
}
14603+
1458314604
/** Lookup helper: true when the node at tile coords (x, y) is in-bounds
1458414605
* and clear (walkable, zero-cost). Used by isLineClear's hot path.
1458514606
* @param {number} x
@@ -14747,6 +14768,7 @@ class PathFinder
1474714768
{
1474814769
this.smoothPathCorners(nodePath);
1474914770
this.smoothPathStringPull(nodePath);
14771+
this.dropCollinearNodes(nodePath);
1475014772
}
1475114773

1475214774
// Convert to world-space Vector2 path. Return copies, not live node

dist/littlejs.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/littlejs.release.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ async function engineInit(gameInit, gameUpdate, gameUpdatePost, gameRender, game
207207
const combinedScale = timeScale * debugScale;
208208
frameTimeDeltaMS *= combinedScale;
209209
frameTimeBufferMS += paused ? 0 : frameTimeDeltaMS;
210-
if (debugScale <= 1)
210+
if (combinedScale <= 1)
211211
frameTimeBufferMS = min(frameTimeBufferMS, 50); // clamp min framerate
212212

213213
let wasUpdated = false;
@@ -13437,10 +13437,10 @@ class PathFinder
1343713437

1343813438
// Tunables (public, freely re-assignable).
1343913439
this.heuristicWeight = 1;
13440-
this.maxLoop = 500;
13440+
this.maxLoop = 1e3;
1344113441
this.smoothPath = true;
1344213442
this.debug = false;
13443-
this.debugTime = 2;
13443+
this.debugTime = 1;
1344413444

1344513445
// Pre-allocate the node array — one node per tile, reused across calls.
1344613446
this.nodes = new Array(this.size.x * this.size.y);
@@ -13616,9 +13616,12 @@ class PathFinder
1361613616
// Best path so far through neighbor — record it.
1361713617
neighbor.parent = current;
1361813618
neighbor.g = tentativeG;
13619-
const gdx = endNode.pos.x - neighbor.pos.x;
13620-
const gdy = endNode.pos.y - neighbor.pos.y;
13621-
neighbor.f = neighbor.g + (gdx * gdx + gdy * gdy) * this.heuristicWeight;
13619+
// Octile heuristic — tightest admissible distance for an
13620+
// 8-connected grid with cardinal cost 1 and diagonal cost √2.
13621+
const adx = abs(endNode.pos.x - neighbor.pos.x);
13622+
const ady = abs(endNode.pos.y - neighbor.pos.y);
13623+
const h = max(adx, ady) + (Math.SQRT2 - 1) * min(adx, ady);
13624+
neighbor.f = neighbor.g + h * this.heuristicWeight;
1362213625
}
1362313626
}
1362413627

@@ -13900,6 +13903,24 @@ class PathFinder
1390013903
path.push(original[original.length - 1]);
1390113904
}
1390213905

13906+
/** Drop any middle node that lies exactly on the line through its two
13907+
* neighbors. Backstop for the smoothing passes — the corners pass
13908+
* intentionally keeps truly-straight runs, and the string-pulling pass
13909+
* checks collinearity against the original path, not the in-progress
13910+
* result, so it can leave 3+ collinear nodes in some edge cases.
13911+
* @param {PathFinderNode[]} path
13912+
* @private */
13913+
dropCollinearNodes(path)
13914+
{
13915+
for (let i = path.length - 2; i >= 1; --i)
13916+
{
13917+
const a = path[i - 1], b = path[i], c = path[i + 1];
13918+
if ((b.pos.x - a.pos.x) * (c.pos.y - a.pos.y) ===
13919+
(b.pos.y - a.pos.y) * (c.pos.x - a.pos.x))
13920+
path.splice(i, 1);
13921+
}
13922+
}
13923+
1390313924
/** Lookup helper: true when the node at tile coords (x, y) is in-bounds
1390413925
* and clear (walkable, zero-cost). Used by isLineClear's hot path.
1390513926
* @param {number} x
@@ -14067,6 +14088,7 @@ class PathFinder
1406714088
{
1406814089
this.smoothPathCorners(nodePath);
1406914090
this.smoothPathStringPull(nodePath);
14091+
this.dropCollinearNodes(nodePath);
1407014092
}
1407114093

1407214094
// Convert to world-space Vector2 path. Return copies, not live node

examples/shorts/base.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!DOCTYPE html><meta charset=utf-8><body>
2-
<script src=../../dist/littlejs.js?1.18.8></script>
2+
<script src=../../dist/littlejs.js?1.18.9></script>
33
<script src=../../dist/box2d.wasm.js></script>
44

55
<!-- LittleJS Engine Source

examples/starter/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
</head><body>
88

99
<!-- LittleJS Engine -->
10-
<script src=../../dist/littlejs.js?1.18.8></script>
10+
<script src=../../dist/littlejs.js?1.18.9></script>
1111

1212
<!-- LittleJS Engine Source
1313
<script src=../../src/engine.js></script>
@@ -34,4 +34,4 @@
3434
-->
3535

3636
<!-- Add your game scripts here -->
37-
<script src=game.js?1.18.8></script>
37+
<script src=game.js?1.18.9></script>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "littlejsengine",
3-
"version": "1.18.8",
3+
"version": "1.18.9",
44
"description": "LittleJS - Tiny and Fast HTML5 Game Engine",
55
"main": "dist/littlejs.esm.js",
66
"types": "dist/littlejs.d.ts",

src/engine.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const engineName = 'LittleJS';
3232
* @type {string}
3333
* @default
3434
* @memberof Engine */
35-
const engineVersion = '1.18.8';
35+
const engineVersion = '1.18.9';
3636

3737
/** Frames per second to update
3838
* @type {number}

0 commit comments

Comments
 (0)