import {System} from '@/ecs/index.js'; import {distance, normalizeVector} from '@/util/math.js'; export default class Attract extends System { static queries() { return { default: ['Magnet'], }; } tick(elapsed) { for (const entity of this.select('default')) { const {Magnet, Position} = entity; const aabb = { x0: Position.x - Magnet.strength / 2, x1: Position.x + (Magnet.strength / 2) - 1, y0: Position.y - Magnet.strength / 2, y1: Position.y + (Magnet.strength / 2) - 1, }; let s = Magnet.strength; s = s * s; for (const other of this.ecs.system('MaintainColliderHash').within(aabb)) { if (other === entity || !other.Magnetic) { continue; } const difference = { x: entity.Position.x - other.Position.x, y: entity.Position.y - other.Position.y, }; const toward = normalizeVector(difference); let d = distance(entity.Position, other.Position); if (d > 0) { const inv = s * (1 / (d * d)); let impulse = { x: toward.x * inv, y: toward.y * inv, }; if (Math.sign(entity.Position.x - (impulse.x * elapsed + other.Position.x)) !== Math.sign(difference.x)) { impulse.x = difference.x / elapsed; } if (Math.sign(entity.Position.y - (impulse.y * elapsed + other.Position.y)) !== Math.sign(difference.y)) { impulse.y = difference.y / elapsed; } other.Forces.applyImpulse(impulse); } } } } }