fix: spatial nearby

This commit is contained in:
cha0s 2024-06-11 02:10:08 -05:00
parent 02905ba1e2
commit 9cf77a1d2b
4 changed files with 28 additions and 12 deletions

View File

@ -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;
}
}

View File

@ -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))

View File

@ -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;

View File

@ -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,
},
},
});