diff --git a/src/engine/components/Colliding.ts b/src/engine/components/Colliding.ts new file mode 100644 index 0000000..fe782df --- /dev/null +++ b/src/engine/components/Colliding.ts @@ -0,0 +1,13 @@ +import { Component, ComponentNames } from "."; +import { Game } from ".."; +import { Entity } from "../entities"; + +export class Colliding extends Component { + public onCollision?: (game: Game, entity: Entity) => void; + + constructor(onCollision?: (game: Game, entity: Entity) => void) { + super(ComponentNames.Colliding); + + this.onCollision = onCollision; + } +} diff --git a/src/engine/components/ComponentNames.ts b/src/engine/components/ComponentNames.ts index fdf1a18..aec14c5 100644 --- a/src/engine/components/ComponentNames.ts +++ b/src/engine/components/ComponentNames.ts @@ -7,6 +7,7 @@ export namespace ComponentNames { export const Highlight = "Highlight"; export const Interactable = "Interactable"; export const Pushable = "Pushable"; + export const Colliding = "Colliding"; export const RadialObserve = "RadialObserve"; export const GridSpawn = "GridSpawn"; export const Text = "Text"; diff --git a/src/engine/components/RadialObserver.ts b/src/engine/components/RadialObserver.ts new file mode 100644 index 0000000..627c4ff --- /dev/null +++ b/src/engine/components/RadialObserver.ts @@ -0,0 +1,13 @@ +import { Component, ComponentNames } from "."; +import { Game } from ".."; +import { Entity } from "../entities"; + +export class Colliding extends Component { + public onCollision?: (game: Game, entity: Entity) => void; + + constructor(onCollision?: (game: Game, entity: Entity) => void) { + super(ComponentNames.RadialObserve); + + this.onCollision = onCollision; + } +} diff --git a/src/engine/components/index.ts b/src/engine/components/index.ts index d3b2fd0..0e5f85c 100644 --- a/src/engine/components/index.ts +++ b/src/engine/components/index.ts @@ -8,6 +8,7 @@ export * from "./Control"; export * from "./Highlight"; export * from "./Interactable"; export * from "./Pushable"; +export * from "./RadialObserve"; export * from "./Colliding"; export * from "./GridSpawn"; export * from "./Text"; diff --git a/src/engine/interfaces/Vec2.ts b/src/engine/interfaces/Vec2.ts index 04be4be..cdb150e 100644 --- a/src/engine/interfaces/Vec2.ts +++ b/src/engine/interfaces/Vec2.ts @@ -2,6 +2,8 @@ export interface Coord2D { x: number; y: number; } +export const cartesianDistance = (a: Coord2D, b: Coord2D) => + Math.sqrt((b.y - a.y) ** 2 + (b.x - a.x) ** 2); export interface Dimension2D { width: number; @@ -15,11 +17,3 @@ export interface Velocity2D { }; dTheta: number; } - -export interface Force2D { - fCartesian: { - fx: number; - fy: number; - }; - torque: number; -} diff --git a/src/engine/systems/RadialObserve.ts b/src/engine/systems/RadialObserve.ts new file mode 100644 index 0000000..8d418df --- /dev/null +++ b/src/engine/systems/RadialObserve.ts @@ -0,0 +1,61 @@ +import { System, SystemNames } from "."; +import { ComponentNames, Grid, RadialObserve } from "../components"; +import { Entity, EntityNames } from "../entities"; +import { Game } from "../Game"; +import { cartesianDistance } from "../interfaces"; + +const radialObservations: Record> = { + TODO: new Set([]), +}; + +export class RadialObserver extends System { + constructor() { + super(SystemNames.RadialObserver); + } + + public update(_dt: number, game: Game) { + game.forEachEntityWithComponent(ComponentNames.RadialObserve, (entity) => { + if (!(entity.name in radialObservations)) { + return; + } + const observable = radialObservations[entity.name]; + + const entityObserve = entity.getComponent( + ComponentNames.RadialObserve, + ); + if (!entityObserve.onObservation) { + return; + } + + const entityPosition = entity.getComponent( + ComponentNames.Grid, + ).gridPosition; + + const observations: Entity[] = []; + game.forEachEntityWithComponent(ComponentNames.RadialObserve, (other) => { + if (entity === other) { + return; + } + if (!observable.has(other.name)) { + return; + } + + const otherPosition = other.getComponent( + ComponentNames.Grid, + ).gridPosition; + if ( + cartesianDistance(entityPosition, otherPosition) > + entityObserve.radius + ) { + return; + } + + observations.push(other); + }); + + for (const observation of observations) { + entityObserve.onObservation!(game, observation); + } + }); + } +}