summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLizzy Hunt <lizzy.hunt@usu.edu>2023-08-16 15:41:35 -0600
committerLizzy Hunt <lizzy.hunt@usu.edu>2023-08-16 15:41:35 -0600
commit1c28e10b860056d85cc07e5a834c4a54eac14563 (patch)
tree8057cbda0336474c3e27cc1de5ac35502e5daff7
parent732fe6f4811cc082bf938fed2d28c1f9c8bbd1f6 (diff)
downloadjumpstorm-1c28e10b860056d85cc07e5a834c4a54eac14563.tar.gz
jumpstorm-1c28e10b860056d85cc07e5a834c4a54eac14563.zip
refactor collision methods, rescaffold server
-rw-r--r--engine/structures/QuadTree.ts10
-rw-r--r--engine/systems/Collision.ts76
-rw-r--r--server/src/server.ts78
-rw-r--r--server/tsconfig.json2
4 files changed, 97 insertions, 69 deletions
diff --git a/engine/structures/QuadTree.ts b/engine/structures/QuadTree.ts
index 49afdad..e6e29fa 100644
--- a/engine/structures/QuadTree.ts
+++ b/engine/structures/QuadTree.ts
@@ -1,6 +1,6 @@
import type { Coord2D, Dimension2D } from "../interfaces";
-interface BoxedEntry {
+export interface BoxedEntry {
id: string;
dimension: Dimension2D;
center: Coord2D;
@@ -170,4 +170,12 @@ export class QuadTree {
private hasChildren() {
return this.children && this.children.size > 0;
}
+
+ public setTopLeft(topLeft: Coord2D) {
+ this.topLeft = topLeft;
+ }
+
+ public setDimension(dimension: Dimension2D) {
+ this.dimension = dimension;
+ }
}
diff --git a/engine/systems/Collision.ts b/engine/systems/Collision.ts
index 889f85e..e05aba0 100644
--- a/engine/systems/Collision.ts
+++ b/engine/systems/Collision.ts
@@ -10,8 +10,8 @@ import {
import { Game } from "../Game";
import { PhysicsConstants } from "../config";
import { Entity } from "../entities";
-import type { Dimension2D, Velocity2D } from "../interfaces";
-import { QuadTree } from "../structures";
+import type { Coord2D, Dimension2D, Velocity2D } from "../interfaces";
+import { QuadTree, BoxedEntry } from "../structures";
export class Collision extends System {
private static readonly COLLIDABLE_COMPONENT_NAMES = [
@@ -41,19 +41,26 @@ export class Collision extends System {
const entitiesToAddToQuadtree: Entity[] = [];
Collision.COLLIDABLE_COMPONENT_NAMES.map((componentName) =>
- game.componentEntities.get(componentName),
- ).forEach(
- (entityIds?: Set<number>) =>
- entityIds?.forEach((id) => {
- const entity = game.entities.get(id);
- if (!entity || !entity.hasComponent(ComponentNames.BoundingBox)) {
- return;
- }
- entitiesToAddToQuadtree.push(entity);
- }),
+ game.forEachEntityWithComponent(componentName, (entity) => {
+ if (!entity.hasComponent(ComponentNames.BoundingBox)) {
+ return;
+ }
+ entitiesToAddToQuadtree.push(entity);
+ }),
);
- entitiesToAddToQuadtree.forEach((entity) => {
+ this.insertEntitiesInQuadTreeAndUpdateBounds(entitiesToAddToQuadtree);
+
+ this.findCollidingEntitiesAndCollide(entitiesToAddToQuadtree, game);
+ }
+
+ private insertEntitiesInQuadTreeAndUpdateBounds(entities: Entity[]) {
+ const topLeft: Coord2D = { x: Infinity, y: Infinity };
+ const bottomRight: Coord2D = { x: -Infinity, y: -Infinity };
+
+ const quadTreeInsertions: BoxedEntry[] = [];
+
+ entities.forEach((entity) => {
const boundingBox = entity.getComponent<BoundingBox>(
ComponentNames.BoundingBox,
);
@@ -63,18 +70,45 @@ export class Collision extends System {
dimension = boundingBox.getOutscribedBoxDims();
}
- this.quadTree.insert({
+ const { center } = boundingBox;
+ const topLeftBoundingBox = {
+ x: center.x - dimension.width / 2,
+ y: center.y - dimension.height / 2,
+ };
+ const bottomRightBoundingBox = {
+ x: center.x + dimension.width / 2,
+ y: center.y + dimension.height / 2,
+ };
+
+ topLeft.x = Math.min(topLeftBoundingBox.x, topLeft.x);
+ topLeft.y = Math.min(topLeftBoundingBox.y, topLeft.y);
+ bottomRight.x = Math.max(bottomRightBoundingBox.x, bottomRight.x);
+ bottomRight.y = Math.min(bottomRightBoundingBox.y, bottomRight.y);
+
+ quadTreeInsertions.push({
id: entity.id,
dimension,
- center: boundingBox.center,
+ center,
});
});
- // find colliding entities and perform collisions
- const collidingEntities = this.getCollidingEntities(
- entitiesToAddToQuadtree,
- game,
+ // set bounds first
+ if (entities.length > 0) {
+ this.quadTree.setTopLeft(topLeft);
+ this.quadTree.setDimension({
+ width: bottomRight.x - topLeft.x,
+ height: bottomRight.y - topLeft.y,
+ });
+ }
+
+ // then, begin insertions
+ quadTreeInsertions.forEach((boxedEntry: BoxedEntry) =>
+ this.quadTree.insert(boxedEntry),
);
+ }
+
+ private findCollidingEntitiesAndCollide(entities: Entity[], game: Game) {
+ const collidingEntities = this.getCollidingEntities(entities, game);
collidingEntities.forEach(([entityAId, entityBId]) => {
const [entityA, entityB] = [entityAId, entityBId].map((id) =>
@@ -139,8 +173,8 @@ export class Collision extends System {
private getCollidingEntities(
collidableEntities: Entity[],
game: Game,
- ): [number, number][] {
- const collidingEntityIds: [number, number][] = [];
+ ): [string, string][] {
+ const collidingEntityIds: [string, string][] = [];
for (const entity of collidableEntities) {
const boundingBox = entity.getComponent<BoundingBox>(
diff --git a/server/src/server.ts b/server/src/server.ts
index 9a73f11..d169f7d 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -11,50 +11,38 @@ import { Miscellaneous } from "../../engine/config";
const TICK_RATE = 60 / 1000;
-class Server {
- private server: any;
- private game: Game;
-
- constructor() {
- this.game = new Game();
-
- [
- new Physics(),
- new Collision({
- width: Miscellaneous.WIDTH,
- height: Miscellaneous.HEIGHT,
- }),
- new WallBounds(Miscellaneous.WIDTH),
- ].forEach((system) => this.game.addSystem(system));
-
- [new Floor(160), new Player()].forEach((entity) =>
- this.game.addEntity(entity),
- );
-
- this.game.start();
- setInterval(() => {
- this.game.doGameLoop(performance.now());
- }, TICK_RATE);
-
- this.server = Bun.serve<any>({
- websocket: {
- open(ws) {
- ws.subscribe("the-group-chat");
- ws.publish("the-group-chat", msg);
- },
- message(ws, message) {
- // this is a group chat
- // so the server re-broadcasts incoming message to everyone
- ws.publish("the-group-chat", `${ws.data.username}: ${message}`);
- },
- close(ws) {
- const msg = `${ws.data.username} has left the chat`;
- ws.unsubscribe("the-group-chat");
- ws.publish("the-group-chat", msg);
- },
+const game = new Game();
+
+[new Physics(), new Collision(), new WallBounds(Miscellaneous.WIDTH)].forEach(
+ (system) => game.addSystem(system),
+);
+
+[new Floor(160), new Player()].forEach((entity) => game.addEntity(entity));
+
+game.start();
+
+setInterval(() => {
+ game.doGameLoop(performance.now());
+}, TICK_RATE);
+
+const server = Bun.serve({
+ port: 8080,
+ fetch(req, server) {
+ const sessionId = Math.floor(Math.random() * 1e10).toString();
+
+ server.upgrade(req, {
+ headers: {
+ "Set-Cookie": `SessionId=${sessionId}`,
},
});
- }
-}
-
-new Server();
+ },
+ websocket: {
+ open(ws) {},
+ message(ws, message) {
+ console.log(message);
+ },
+ close(ws) {},
+ },
+});
+
+console.log(`Listening on ${server.hostname}:${server.port}`);
diff --git a/server/tsconfig.json b/server/tsconfig.json
index 2567512..e39b364 100644
--- a/server/tsconfig.json
+++ b/server/tsconfig.json
@@ -13,8 +13,6 @@
"noEmit": true,
"allowImportingTsExtensions": true,
"moduleDetection": "force",
- // if TS 4.x or earlier
- "moduleResolution": "nodenext",
"jsx": "react-jsx", // support JSX
"allowJs": true, // allow importing `.js` from `.ts`