From cbb88091bdf69cc8752ef1cc3662dc0b99e3ead6 Mon Sep 17 00:00:00 2001 From: Elizabeth Hunt Date: Sat, 2 Mar 2024 05:30:17 -0700 Subject: key lock / player curry collisions --- src/engine/systems/Collision.ts | 103 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 src/engine/systems/Collision.ts (limited to 'src/engine/systems/Collision.ts') diff --git a/src/engine/systems/Collision.ts b/src/engine/systems/Collision.ts new file mode 100644 index 0000000..7b1b963 --- /dev/null +++ b/src/engine/systems/Collision.ts @@ -0,0 +1,103 @@ +import { System, SystemNames } from "."; +import { Game } from ".."; +import { Entity, EntityNames } from "../entities"; +import { BoundingBox, Colliding, ComponentNames, Grid } from "../components"; + +const collisionMap: Record> = { + [EntityNames.Key]: new Set([EntityNames.LockedDoor]), + [EntityNames.Curry]: new Set([EntityNames.Player]), +}; + +export class Collision extends System { + static canCollide(entityName: string, otherEntityName: string) { + if (collisionMap[entityName]) { + return collisionMap[entityName].has(otherEntityName); + } + return collisionMap[otherEntityName]?.has(entityName) ?? false; + } + + constructor() { + super(SystemNames.Collision); + } + + public update(_dt: number, game: Game) { + game.forEachEntityWithComponent(ComponentNames.Colliding, (entity) => { + if (!entity.hasComponent(ComponentNames.BoundingBox)) { + return; + } + const collidingBox = entity.getComponent( + ComponentNames.BoundingBox, + ); + let collidingGrid = entity.hasComponent(ComponentNames.Grid) + ? entity.getComponent(ComponentNames.Grid) + : null; + + const collidingWith: Entity[] = []; + game.forEachEntityWithComponent( + ComponentNames.BoundingBox, + (otherEntity) => { + const otherBoundingBox = otherEntity.getComponent( + ComponentNames.BoundingBox, + ); + let otherGrid = otherEntity.hasComponent(ComponentNames.Grid) + ? otherEntity.getComponent(ComponentNames.Grid) + : null; + + if (collidingGrid && otherGrid) { + if ( + collidingGrid.gridPosition.x === otherGrid.gridPosition.x && + collidingGrid.gridPosition.y === otherGrid.gridPosition.y + ) { + collidingWith.push(otherEntity); + } + return; + } + + if (collidingBox.isCollidingWith(otherBoundingBox)) { + collidingWith.push(otherEntity); + } + }, + ); + + for (const collision of collidingWith) { + this.handleCollision(entity, collision, game); + } + }); + } + + private handleCollision(entity: Entity, otherEntity: Entity, game: Game) { + if (!Collision.canCollide(entity.name, otherEntity.name)) { + return; + } + + const keyDoorPair = [EntityNames.Key, EntityNames.LockedDoor].map((x) => + [entity, otherEntity].find((y) => y.name === x), + ); + const [key, door] = keyDoorPair; + if (key && door) { + this.handleKeyDoorCollision(key, door, game); + } + + const curryPlayerPair = [EntityNames.Curry, EntityNames.Player].map((x) => + [entity, otherEntity].find((y) => y.name === x), + ); + const [curry, player] = curryPlayerPair; + if (curry && player) { + this.handleCurryPlayerCollision(curry, player, game); + } + } + + private handleKeyDoorCollision(key: Entity, door: Entity, game: Game) { + game.removeEntity(key.id); + game.removeEntity(door.id); + } + + private handleCurryPlayerCollision( + curry: Entity, + _player: Entity, + game: Game, + ) { + game.removeEntity(curry.id); + game.stop(); + } +} -- cgit v1.2.3-70-g09d2