From 9cf77a1d2bc33b65937035b63fe5bfe10f73d96c Mon Sep 17 00:00:00 2001 From: cha0s Date: Tue, 11 Jun 2024 02:10:08 -0500 Subject: [PATCH] fix: spatial nearby --- app/ecs-systems/update-spatial-hash.js | 20 ++++++++++++++++++++ app/ecs/ecs.test.js | 2 ++ app/engine/engine.js | 8 +------- app/engine/engine.test.js | 10 +++++----- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/app/ecs-systems/update-spatial-hash.js b/app/ecs-systems/update-spatial-hash.js index b23134e..98467e7 100644 --- a/app/ecs-systems/update-spatial-hash.js +++ b/app/ecs-systems/update-spatial-hash.js @@ -95,4 +95,24 @@ export default class UpdateSpatialHash extends System { } } + nearby(entity) { + const [cx0, cy0] = this.hash.chunkIndex( + entity.Position.x - RESOLUTION[0] * 0.75, + entity.Position.y - RESOLUTION[0] * 0.75, + ); + const [cx1, cy1] = this.hash.chunkIndex( + entity.Position.x + RESOLUTION[0] * 0.75, + entity.Position.y + RESOLUTION[0] * 0.75, + ); + const nearby = new Set(); + for (let cy = cy0; cy <= cy1; ++cy) { + for (let cx = cx0; cx <= cx1; ++cx) { + this.hash.chunks[cx][cy].forEach((id) => { + nearby.add(this.ecs.get(id)); + }); + } + } + return nearby; + } + } diff --git a/app/ecs/ecs.test.js b/app/ecs/ecs.test.js index ab17b8a..a78c0f2 100644 --- a/app/ecs/ecs.test.js +++ b/app/ecs/ecs.test.js @@ -439,6 +439,8 @@ test('serializes and deserializes', () => { expect(deserialized.get(16).constructor.types) .to.deep.equal(['Name', 'Position']); // Entity values. + expect(JSON.stringify(deserialized.get(1))) + .to.equal(JSON.stringify({Empty: {}, Position: {x: 64}})) expect(JSON.stringify(deserialized.get(1).Position)) .to.equal(JSON.stringify({x: 64})); expect(JSON.stringify(deserialized.get(16).Position)) diff --git a/app/engine/engine.js b/app/engine/engine.js index 6edfb67..0d07f8c 100644 --- a/app/engine/engine.js +++ b/app/engine/engine.js @@ -139,13 +139,7 @@ export default class Engine { const {entity, memory} = this.connectedPlayers.get(connection); const mainEntityId = entity.id; const ecs = this.ecses[entity.World.world]; - const {hash} = ecs.system(UpdateSpatialHash); - const nearby = new Set(); - for (const [cx, cy] of hash.data[entity.id]) { - hash.chunks[cx][cy].forEach((id) => { - nearby.add(ecs.get(id)); - }); - } + const nearby = ecs.system(UpdateSpatialHash).nearby(entity); const lastMemory = new Set(memory.values()); for (const entity of nearby) { const {id} = entity; diff --git a/app/engine/engine.test.js b/app/engine/engine.test.js index 276c98c..ba445ab 100644 --- a/app/engine/engine.test.js +++ b/app/engine/engine.test.js @@ -10,7 +10,7 @@ test('visibility-based updates', async () => { // Create an entity. const entity = ecs.get(ecs.create({ Momentum: {x: 1, y: 0}, - Position: {x: (RESOLUTION[0] / 2) + 32 - 3, y: 20}, + Position: {x: RESOLUTION[0] + 32 - 3, y: 20}, VisibleAabb: {}, })); // Connect an entity. @@ -18,16 +18,16 @@ test('visibility-based updates', async () => { // Tick and get update. Should be a full update. engine.tick(1); expect(engine.updateFor(undefined)) - .to.deep.equal({2: ecs.get(2).toJSON(), 3: ecs.get(3).toJSON()}); + .to.deep.equal({2: ecs.get(2).toJSON(), 3: {MainEntity: {}, ...ecs.get(3).toJSON()}}); // Tick and get update. Should be a partial update. engine.tick(1); expect(engine.updateFor(undefined)) .to.deep.equal({ 2: { - Position: {x: (RESOLUTION[0] / 2) + 32 - 1}, + Position: {x: RESOLUTION[0] + 32 - 1}, VisibleAabb: { - x0: 399, - x1: 463, + x0: 799, + x1: 863, }, }, });