implement a radial observation system

This commit is contained in:
Elizabeth Hunt 2025-03-02 17:06:49 -07:00
parent d8511f4ad3
commit 491a1d05a5
6 changed files with 91 additions and 8 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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<string, Set<string>> = {
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<RadialObserve>(
ComponentNames.RadialObserve,
);
if (!entityObserve.onObservation) {
return;
}
const entityPosition = entity.getComponent<Grid>(
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<Grid>(
ComponentNames.Grid,
).gridPosition;
if (
cartesianDistance(entityPosition, otherPosition) >
entityObserve.radius
) {
return;
}
observations.push(other);
});
for (const observation of observations) {
entityObserve.onObservation!(game, observation);
}
});
}
}