summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/lib/Game.ts70
-rw-r--r--client/lib/components/BoundingBox.ts97
-rw-r--r--client/lib/components/Collide.ts7
-rw-r--r--client/lib/components/Component.ts7
-rw-r--r--client/lib/components/Control.ts7
-rw-r--r--client/lib/components/FacingDirection.ts13
-rw-r--r--client/lib/components/Forces.ts17
-rw-r--r--client/lib/components/Gravity.ts13
-rw-r--r--client/lib/components/Jump.ts10
-rw-r--r--client/lib/components/Mass.ts10
-rw-r--r--client/lib/components/Moment.ts10
-rw-r--r--client/lib/components/Sprite.ts92
-rw-r--r--client/lib/components/TopCollidable.ts7
-rw-r--r--client/lib/components/Velocity.ts15
-rw-r--r--client/lib/components/WallBounded.ts7
-rw-r--r--client/lib/components/index.ts15
-rw-r--r--client/lib/components/names.ts15
-rw-r--r--client/lib/config/assets.ts40
-rw-r--r--client/lib/config/constants.ts34
-rw-r--r--client/lib/config/index.ts3
-rw-r--r--client/lib/config/sprites.ts49
-rw-r--r--client/lib/entities/Entity.ts33
-rw-r--r--client/lib/entities/Floor.ts31
-rw-r--r--client/lib/entities/Player.ts68
-rw-r--r--client/lib/entities/index.ts3
-rw-r--r--client/lib/interfaces/Action.ts5
-rw-r--r--client/lib/interfaces/Direction.ts6
-rw-r--r--client/lib/interfaces/Draw.ts9
-rw-r--r--client/lib/interfaces/LeaderBoardEntry.ts5
-rw-r--r--client/lib/interfaces/Vec2.ts22
-rw-r--r--client/lib/interfaces/index.ts5
-rw-r--r--client/lib/structures/QuadTree.ts154
-rw-r--r--client/lib/structures/index.ts1
-rw-r--r--client/lib/systems/Collision.ts214
-rw-r--r--client/lib/systems/FacingDirection.ts39
-rw-r--r--client/lib/systems/Input.ts86
-rw-r--r--client/lib/systems/Physics.ts94
-rw-r--r--client/lib/systems/Render.ts41
-rw-r--r--client/lib/systems/System.ts15
-rw-r--r--client/lib/systems/WallBounds.ts35
-rw-r--r--client/lib/systems/index.ts8
-rw-r--r--client/lib/systems/names.ts8
-rw-r--r--client/lib/utils/dotProduct.ts4
-rw-r--r--client/lib/utils/index.ts3
-rw-r--r--client/lib/utils/normalizeVector.ts8
-rw-r--r--client/lib/utils/rotateVector.ts15
-rw-r--r--client/package-lock.json8
-rw-r--r--client/package.json3
-rw-r--r--client/src/JumpStorm.ts (renamed from client/lib/JumpStorm.ts)6
-rw-r--r--client/src/components/GameCanvas.svelte9
-rw-r--r--client/src/components/LeaderBoard.svelte2
-rw-r--r--client/src/components/LeaderBoardCard.svelte2
-rw-r--r--client/tsconfig.json3
-rw-r--r--client/vite.config.ts12
54 files changed, 31 insertions, 1464 deletions
diff --git a/client/lib/Game.ts b/client/lib/Game.ts
deleted file mode 100644
index d6ffb47..0000000
--- a/client/lib/Game.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { Entity } from "./entities";
-import { System } from "./systems";
-
-export class Game {
- private entities: Map<number, Entity>;
- private systems: Map<string, System>;
- private systemOrder: string[];
-
- private running: boolean;
- private lastTimeStamp: number;
-
- constructor() {
- this.running = false;
- this.systemOrder = [];
- this.systems = new Map();
- this.entities = new Map();
- }
-
- public start() {
- this.lastTimeStamp = performance.now();
- this.running = true;
- }
-
- public addEntity(entity: Entity) {
- this.entities.set(entity.id, entity);
- }
-
- public getEntity(id: number): Entity {
- return this.entities.get(id);
- }
-
- public removeEntity(id: number) {
- this.entities.delete(id);
- }
-
- public addSystem(system: System) {
- if (!this.systemOrder.includes(system.name)) {
- this.systemOrder.push(system.name);
- }
- this.systems.set(system.name, system);
- }
-
- public getSystem(name: string): System {
- return this.systems.get(name);
- }
-
- public doGameLoop = (timeStamp: number) => {
- if (!this.running) {
- return;
- }
-
- const dt = timeStamp - this.lastTimeStamp;
- this.lastTimeStamp = timeStamp;
-
- const componentEntities = new Map<string, Set<number>>();
- this.entities.forEach((entity) =>
- entity.getComponents().forEach((component) => {
- if (!componentEntities.has(component.name)) {
- componentEntities.set(component.name, new Set<number>([entity.id]));
- return;
- }
- componentEntities.get(component.name).add(entity.id);
- })
- );
-
- this.systemOrder.forEach((systemName) => {
- this.systems.get(systemName).update(dt, this.entities, componentEntities);
- });
- };
-}
diff --git a/client/lib/components/BoundingBox.ts b/client/lib/components/BoundingBox.ts
deleted file mode 100644
index 2b1d648..0000000
--- a/client/lib/components/BoundingBox.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-import { Component, ComponentNames } from ".";
-import type { Coord2D, Dimension2D } from "../interfaces";
-import { dotProduct, rotateVector, normalizeVector } from "../utils";
-
-export class BoundingBox extends Component {
- public center: Coord2D;
- public dimension: Dimension2D;
- public rotation: number;
-
- constructor(center: Coord2D, dimension: Dimension2D, rotation?: number) {
- super(ComponentNames.BoundingBox);
-
- this.center = center;
- this.dimension = dimension;
- this.rotation = rotation ?? 0;
- }
-
- public isCollidingWith(box: BoundingBox): boolean {
- const boxes = [this.getVertices(), box.getVertices()];
- for (const poly of boxes) {
- for (let i = 0; i < poly.length; ++i) {
- const [A, B] = [poly[i], poly[(i + 1) % poly.length]];
- const normal: Coord2D = { x: B.y - A.y, y: A.x - B.x };
-
- const [[minThis, maxThis], [minBox, maxBox]] = boxes.map((box) =>
- box.reduce(
- ([min, max], vertex) => {
- const projection = dotProduct(normal, vertex);
- return [Math.min(min, projection), Math.max(max, projection)];
- },
- [Infinity, -Infinity]
- )
- );
-
- if (maxThis < minBox || maxBox < minThis) return false;
- }
- }
-
- return true;
- }
-
- public getVertices(): Coord2D[] {
- return [
- { x: -this.dimension.width / 2, y: -this.dimension.height / 2 },
- { x: -this.dimension.width / 2, y: this.dimension.height / 2 },
- { x: this.dimension.width / 2, y: this.dimension.height / 2 },
- { x: this.dimension.width / 2, y: -this.dimension.height / 2 },
- ]
- .map((vertex) => rotateVector(vertex, this.rotation))
- .map((vertex) => {
- return {
- x: vertex.x + this.center.x,
- y: vertex.y + this.center.y,
- };
- });
- }
-
- private getAxes() {
- const corners: Coord2D[] = this.getVerticesRelativeToCenter();
- const axes: Coord2D[] = [];
-
- for (let i = 0; i < corners.length; ++i) {
- const [cornerA, cornerB] = [
- corners[i],
- corners[(i + 1) % corners.length],
- ].map((corner) => rotateVector(corner, this.rotation));
-
- axes.push(
- normalizeVector({
- x: cornerB.y - cornerA.y,
- y: -(cornerB.x - cornerA.x),
- })
- );
- }
-
- return axes;
- }
-
- private project(axis: Coord2D): [number, number] {
- const corners = this.getCornersRelativeToCenter();
- let [min, max] = [Infinity, -Infinity];
-
- for (const corner of corners) {
- const rotated = rotateVector(corner, this.rotation);
- const translated = {
- x: rotated.x + this.center.x,
- y: rotated.y + this.center.y,
- };
- const projection = dotProduct(translated, axis);
-
- min = Math.min(projection, min);
- max = Math.max(projection, max);
- }
-
- return [min, max];
- }
-}
diff --git a/client/lib/components/Collide.ts b/client/lib/components/Collide.ts
deleted file mode 100644
index 889ecf8..0000000
--- a/client/lib/components/Collide.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Component, ComponentNames } from ".";
-
-export class Collide extends Component {
- constructor() {
- super(ComponentNames.Collide);
- }
-}
diff --git a/client/lib/components/Component.ts b/client/lib/components/Component.ts
deleted file mode 100644
index 7331982..0000000
--- a/client/lib/components/Component.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-export abstract class Component {
- public readonly name: string;
-
- constructor(name: string) {
- this.name = name;
- }
-}
diff --git a/client/lib/components/Control.ts b/client/lib/components/Control.ts
deleted file mode 100644
index 094ef1c..0000000
--- a/client/lib/components/Control.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Component, ComponentNames } from ".";
-
-export class Control extends Component {
- constructor() {
- super(ComponentNames.Control);
- }
-}
diff --git a/client/lib/components/FacingDirection.ts b/client/lib/components/FacingDirection.ts
deleted file mode 100644
index 1c701a3..0000000
--- a/client/lib/components/FacingDirection.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Component, ComponentNames, Sprite } from ".";
-
-export class FacingDirection extends Component {
- public readonly facingLeftSprite: Sprite;
- public readonly facingRightSprite: Sprite;
-
- constructor(facingLeftSprite: Sprite, facingRightSprite: Sprite) {
- super(ComponentNames.FacingDirection);
-
- this.facingLeftSprite = facingLeftSprite;
- this.facingRightSprite = facingRightSprite;
- }
-}
diff --git a/client/lib/components/Forces.ts b/client/lib/components/Forces.ts
deleted file mode 100644
index bf540a1..0000000
--- a/client/lib/components/Forces.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import type { Accel2D, Force2D } from "../interfaces";
-import { Component } from "./Component";
-import { ComponentNames } from ".";
-
-/**
- * A list of forces and torque, (in newtons, and newton-meters respectively)
- * to apply on one Physics system update (after which, they are cleared).
- */
-export class Forces extends Component {
- public forces: Force2D[];
-
- constructor(forces?: Force2D[]) {
- super(ComponentNames.Forces);
-
- this.forces = forces ?? [];
- }
-}
diff --git a/client/lib/components/Gravity.ts b/client/lib/components/Gravity.ts
deleted file mode 100644
index 89fcb67..0000000
--- a/client/lib/components/Gravity.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { ComponentNames, Component } from ".";
-
-export class Gravity extends Component {
- private static DEFAULT_TERMINAL_VELOCITY = 5;
-
- public terminalVelocity: number;
-
- constructor(terminalVelocity?: number) {
- super(ComponentNames.Gravity);
- this.terminalVelocity =
- terminalVelocity ?? Gravity.DEFAULT_TERMINAL_VELOCITY;
- }
-}
diff --git a/client/lib/components/Jump.ts b/client/lib/components/Jump.ts
deleted file mode 100644
index 0b40767..0000000
--- a/client/lib/components/Jump.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { Component, ComponentNames } from ".";
-
-export class Jump extends Component {
- public canJump: boolean;
-
- constructor() {
- super(ComponentNames.Jump);
- this.canJump = false;
- }
-}
diff --git a/client/lib/components/Mass.ts b/client/lib/components/Mass.ts
deleted file mode 100644
index daa2d71..0000000
--- a/client/lib/components/Mass.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { Component, ComponentNames } from ".";
-
-export class Mass extends Component {
- public mass: number;
-
- constructor(mass: number) {
- super(ComponentNames.Mass);
- this.mass = mass;
- }
-}
diff --git a/client/lib/components/Moment.ts b/client/lib/components/Moment.ts
deleted file mode 100644
index 3d0dd2f..0000000
--- a/client/lib/components/Moment.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { Component, ComponentNames } from ".";
-
-export class Moment extends Component {
- public inertia: number;
-
- constructor(inertia: number) {
- super(ComponentNames.Moment);
- this.inertia = inertia;
- }
-}
diff --git a/client/lib/components/Sprite.ts b/client/lib/components/Sprite.ts
deleted file mode 100644
index 90e1389..0000000
--- a/client/lib/components/Sprite.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import { Component, ComponentNames } from ".";
-import type { Dimension2D, DrawArgs, Coord2D } from "../interfaces";
-
-export class Sprite extends Component {
- private sheet: HTMLImageElement;
-
- private spriteImgPos: Coord2D;
- private spriteImgDimensions: Dimension2D;
-
- private msPerFrame: number;
- private msSinceLastFrame: number;
- private currentFrame: number;
- private numFrames: number;
-
- constructor(
- sheet: HTMLImageElement,
- spriteImgPos: Coord2D,
- spriteImgDimensions: Dimension2D,
- msPerFrame: number,
- numFrames: number
- ) {
- super(ComponentNames.Sprite);
-
- this.sheet = sheet;
- this.spriteImgPos = spriteImgPos;
- this.spriteImgDimensions = spriteImgDimensions;
- this.msPerFrame = msPerFrame;
- this.numFrames = numFrames;
-
- this.msSinceLastFrame = 0;
- this.currentFrame = 0;
- }
-
- public update(dt: number) {
- this.msSinceLastFrame += dt;
- if (this.msSinceLastFrame >= this.msPerFrame) {
- this.currentFrame = (this.currentFrame + 1) % this.numFrames;
- this.msSinceLastFrame = 0;
- }
- }
-
- public draw(ctx: CanvasRenderingContext2D, drawArgs: DrawArgs) {
- const { center, rotation, tint, opacity } = drawArgs;
-
- ctx.save();
- ctx.translate(center.x, center.y);
- if (rotation != 0) {
- ctx.rotate(rotation * (Math.PI / 180));
- }
- ctx.translate(-center.x, -center.y);
-
- if (opacity) {
- ctx.globalAlpha = opacity;
- }
-
- ctx.drawImage(
- this.sheet,
- ...this.getSpriteArgs(),
- ...this.getDrawArgs(drawArgs)
- );
-
- if (tint) {
- ctx.globalAlpha = 0.5;
- ctx.globalCompositeOperation = "source-atop";
- ctx.fillStyle = tint;
- ctx.fillRect(...this.getDrawArgs(drawArgs));
- }
-
- ctx.restore();
- }
-
- private getSpriteArgs(): [sx: number, sy: number, sw: number, sh: number] {
- return [
- this.spriteImgPos.x + this.currentFrame * this.spriteImgDimensions.width,
- this.spriteImgPos.y,
- this.spriteImgDimensions.width,
- this.spriteImgDimensions.height,
- ];
- }
-
- private getDrawArgs({
- center,
- dimension,
- }: DrawArgs): [dx: number, dy: number, dw: number, dh: number] {
- return [
- center.x - dimension.width / 2,
- center.y - dimension.height / 2,
- dimension.width,
- dimension.height,
- ];
- }
-}
diff --git a/client/lib/components/TopCollidable.ts b/client/lib/components/TopCollidable.ts
deleted file mode 100644
index 7fb147d..0000000
--- a/client/lib/components/TopCollidable.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Component, ComponentNames } from ".";
-
-export class TopCollidable extends Component {
- constructor() {
- super(ComponentNames.TopCollidable);
- }
-}
diff --git a/client/lib/components/Velocity.ts b/client/lib/components/Velocity.ts
deleted file mode 100644
index 119427d..0000000
--- a/client/lib/components/Velocity.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import type { Velocity2D } from "../interfaces";
-import { Component } from "./Component";
-import { ComponentNames } from ".";
-
-export class Velocity extends Component {
- public dCartesian: Velocity2D;
- public dTheta: number;
-
- constructor(dCartesian: Velocity2D, dTheta: number) {
- super(ComponentNames.Velocity);
-
- this.dCartesian = dCartesian;
- this.dTheta = dTheta;
- }
-}
diff --git a/client/lib/components/WallBounded.ts b/client/lib/components/WallBounded.ts
deleted file mode 100644
index 5f787e1..0000000
--- a/client/lib/components/WallBounded.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Component, ComponentNames } from ".";
-
-export class WallBounded extends Component {
- constructor() {
- super(ComponentNames.WallBounded);
- }
-}
diff --git a/client/lib/components/index.ts b/client/lib/components/index.ts
deleted file mode 100644
index 67f1259..0000000
--- a/client/lib/components/index.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export * from "./Component";
-export * from "./BoundingBox";
-export * from "./Velocity";
-export * from "./Forces";
-export * from "./Sprite";
-export * from "./FacingDirection";
-export * from "./Jump";
-export * from "./TopCollidable";
-export * from "./Collide";
-export * from "./Control";
-export * from "./WallBounded";
-export * from "./Gravity";
-export * from "./Mass";
-export * from "./Moment";
-export * from "./names";
diff --git a/client/lib/components/names.ts b/client/lib/components/names.ts
deleted file mode 100644
index e2ee3d3..0000000
--- a/client/lib/components/names.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-export namespace ComponentNames {
- export const Sprite = "Sprite";
- export const BoundingBox = "BoundingBox";
- export const Velocity = "Velocity";
- export const FacingDirection = "FacingDirection";
- export const Control = "Control";
- export const Jump = "Jump";
- export const TopCollidable = "TopCollidable";
- export const Collide = "Collide";
- export const WallBounded = "WallBounded";
- export const Gravity = "Gravity";
- export const Forces = "Forces";
- export const Mass = "Mass";
- export const Moment = "Moment";
-}
diff --git a/client/lib/config/assets.ts b/client/lib/config/assets.ts
deleted file mode 100644
index 51a5303..0000000
--- a/client/lib/config/assets.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import type { SpriteSpec } from "./sprites";
-import { SPRITE_SPECS } from "./sprites";
-
-export const IMAGES = new Map<string, HTMLImageElement>();
-
-export const loadSpritesIntoImageElements = (
- spriteSpecs: Partial<SpriteSpec>[]
-): Promise<void>[] => {
- const spritePromises: Promise<void>[] = [];
-
- for (const spriteSpec of spriteSpecs) {
- if (spriteSpec.sheet) {
- const img = new Image();
- img.src = spriteSpec.sheet;
- IMAGES.set(spriteSpec.sheet, img);
-
- spritePromises.push(
- new Promise((resolve) => {
- img.onload = () => resolve();
- })
- );
- }
-
- if (spriteSpec.states) {
- spritePromises.push(
- ...loadSpritesIntoImageElements(Object.values(spriteSpec.states))
- );
- }
- }
-
- return spritePromises;
-};
-
-export const loadAssets = () =>
- Promise.all([
- ...loadSpritesIntoImageElements(
- Array.from(SPRITE_SPECS.keys()).map((key) => SPRITE_SPECS.get(key))
- ),
- // TODO: Sound
- ]);
diff --git a/client/lib/config/constants.ts b/client/lib/config/constants.ts
deleted file mode 100644
index 27c8160..0000000
--- a/client/lib/config/constants.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Action } from "../interfaces";
-
-export namespace KeyConstants {
- export const KeyActions: Record<string, Action> = {
- a: Action.MOVE_LEFT,
- ArrowLeft: Action.MOVE_LEFT,
- d: Action.MOVE_RIGHT,
- ArrowRight: Action.MOVE_RIGHT,
- w: Action.JUMP,
- ArrowUp: Action.JUMP,
- };
-
- export const ActionKeys: Map<Action, string[]> = Object.keys(
- KeyActions
- ).reduce((acc: Map<Action, string[]>, key) => {
- const action = KeyActions[key];
-
- if (acc.has(action)) {
- acc.get(action).push(key);
- return acc;
- }
-
- acc.set(action, [key]);
- return acc;
- }, new Map<Action, string[]>());
-}
-
-export namespace PhysicsConstants {
- export const MAX_JUMP_TIME_MS = 150;
- export const GRAVITY = 0.0075;
- export const PLAYER_MOVE_VEL = 1;
- export const PLAYER_JUMP_ACC = -0.01;
- export const PLAYER_JUMP_INITIAL_VEL = -0.9;
-}
diff --git a/client/lib/config/index.ts b/client/lib/config/index.ts
deleted file mode 100644
index 7a1052a..0000000
--- a/client/lib/config/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from "./constants";
-export * from "./assets.ts";
-export * from "./sprites.ts";
diff --git a/client/lib/config/sprites.ts b/client/lib/config/sprites.ts
deleted file mode 100644
index 18bec73..0000000
--- a/client/lib/config/sprites.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-export enum Sprites {
- FLOOR,
- TRAMPOLINE,
- COFFEE,
-}
-
-export interface SpriteSpec {
- sheet: string;
- width: number;
- height: number;
- frames: number;
- msPerFrame: number;
- states?: Record<string | number, Partial<SpriteSpec>>;
-}
-
-export const SPRITE_SPECS: Map<Sprites, Partial<SpriteSpec>> = new Map<
- Sprites,
- SpriteSpec
->();
-
-const floorSpriteSpec = {
- height: 40,
- frames: 3,
- msPerFrame: 125,
- states: {},
-};
-floorSpriteSpec.states = [40, 80, 120, 160].reduce((acc, cur) => {
- acc[cur] = {
- width: cur,
- sheet: `/assets/floor_tile_${cur}.png`,
- };
- return acc;
-}, {});
-SPRITE_SPECS.set(Sprites.FLOOR, floorSpriteSpec);
-
-SPRITE_SPECS.set(Sprites.COFFEE, {
- msPerFrame: 100,
- width: 60,
- height: 45,
- frames: 3,
- states: {
- LEFT: {
- sheet: "/assets/coffee_left.png",
- },
- RIGHT: {
- sheet: "/assets/coffee_right.png",
- },
- },
-});
diff --git a/client/lib/entities/Entity.ts b/client/lib/entities/Entity.ts
deleted file mode 100644
index e57ccde..0000000
--- a/client/lib/entities/Entity.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { Component } from "../components";
-import { ComponentNotFoundError } from "../exceptions";
-
-export abstract class Entity {
- private static ID = 0;
-
- public readonly id: number;
- public readonly components: Map<string, Component>;
-
- constructor() {
- this.id = Entity.ID++;
- this.components = new Map();
- }
-
- public addComponent(component: Component) {
- this.components.set(component.name, component);
- }
-
- public getComponent<T extends Component>(name: string): T {
- if (!this.hasComponent(name)) {
- throw new Error("Entity does not have component " + name);
- }
- return this.components.get(name) as T;
- }
-
- public getComponents(): Component[] {
- return Array.from(this.components.values());
- }
-
- public hasComponent(name: string): boolean {
- return this.components.has(name);
- }
-}
diff --git a/client/lib/entities/Floor.ts b/client/lib/entities/Floor.ts
deleted file mode 100644
index d51badc..0000000
--- a/client/lib/entities/Floor.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { IMAGES, SPRITE_SPECS, Sprites, type SpriteSpec } from "../config";
-import { BoundingBox, Sprite } from "../components";
-import { TopCollidable } from "../components/TopCollidable";
-import { Entity } from "../entities";
-
-export class Floor extends Entity {
- private static spriteSpec: SpriteSpec = SPRITE_SPECS.get(Sprites.FLOOR);
-
- constructor(width: number) {
- super();
-
- this.addComponent(
- new Sprite(
- IMAGES.get(Floor.spriteSpec.states[width].sheet),
- { x: 0, y: 0 },
- { width, height: Floor.spriteSpec.height },
- Floor.spriteSpec.msPerFrame,
- Floor.spriteSpec.frames
- )
- );
-
- this.addComponent(
- new BoundingBox(
- { x: 300, y: 300 },
- { width, height: Floor.spriteSpec.height }
- )
- );
-
- this.addComponent(new TopCollidable());
- }
-}
diff --git a/client/lib/entities/Player.ts b/client/lib/entities/Player.ts
deleted file mode 100644
index 0ba5a41..0000000
--- a/client/lib/entities/Player.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-import { Entity } from ".";
-import { IMAGES, SPRITE_SPECS, Sprites, type SpriteSpec } from "../config";
-import {
- Jump,
- FacingDirection,
- BoundingBox,
- Sprite,
- Velocity,
- Gravity,
- WallBounded,
- Forces,
- Collide,
- Control,
- Mass,
- Moment,
-} from "../components";
-import { PhysicsConstants } from "../config";
-import { Direction } from "../interfaces";
-
-export class Player extends Entity {
- private static MASS: number = 10;
- private static MOI: number = 1000;
-
- private static spriteSpec: SpriteSpec = SPRITE_SPECS.get(Sprites.COFFEE);
-
- constructor() {
- super();
-
- this.addComponent(
- new BoundingBox(
- { x: 300, y: 100 },
- { width: Player.spriteSpec.width, height: Player.spriteSpec.height },
- 0
- )
- );
-
- this.addComponent(new Velocity({ dx: 0, dy: 0 }, 0));
-
- this.addComponent(new Mass(Player.MASS));
- this.addComponent(new Moment(Player.MOI));
- this.addComponent(new Forces());
- this.addComponent(new Gravity());
-
- this.addComponent(new Jump());
- this.addComponent(new Control());
-
- this.addComponent(new Collide());
- this.addComponent(new WallBounded());
-
- this.addFacingDirectionComponents();
- }
-
- private addFacingDirectionComponents() {
- const [leftSprite, rightSprite] = [Direction.LEFT, Direction.RIGHT].map(
- (direction) =>
- new Sprite(
- IMAGES.get(Player.spriteSpec.states[direction].sheet),
- { x: 0, y: 0 },
- { width: Player.spriteSpec.width, height: Player.spriteSpec.height },
- Player.spriteSpec.msPerFrame,
- Player.spriteSpec.frames
- )
- );
-
- this.addComponent(new FacingDirection(leftSprite, rightSprite));
- this.addComponent(leftSprite); // face Left by default
- }
-}
diff --git a/client/lib/entities/index.ts b/client/lib/entities/index.ts
deleted file mode 100644
index a921512..0000000
--- a/client/lib/entities/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from "./Entity";
-export * from "./Floor";
-export * from "./Player";
diff --git a/client/lib/interfaces/Action.ts b/client/lib/interfaces/Action.ts
deleted file mode 100644
index 61c89e1..0000000
--- a/client/lib/interfaces/Action.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export enum Action {
- MOVE_LEFT,
- MOVE_RIGHT,
- JUMP,
-}
diff --git a/client/lib/interfaces/Direction.ts b/client/lib/interfaces/Direction.ts
deleted file mode 100644
index 0bc6ef3..0000000
--- a/client/lib/interfaces/Direction.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export enum Direction {
- UP = "UP",
- DOWN = "DOWN",
- LEFT = "LEFT",
- RIGHT = "RIGHT",
-}
diff --git a/client/lib/interfaces/Draw.ts b/client/lib/interfaces/Draw.ts
deleted file mode 100644
index 6561a01..0000000
--- a/client/lib/interfaces/Draw.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import type { Coord2D, Dimension2D } from "./";
-
-export interface DrawArgs {
- center: Coord2D;
- dimension: Dimension2D;
- tint?: string;
- opacity?: number;
- rotation?: number;
-}
diff --git a/client/lib/interfaces/LeaderBoardEntry.ts b/client/lib/interfaces/LeaderBoardEntry.ts
deleted file mode 100644
index 1b1e7b3..0000000
--- a/client/lib/interfaces/LeaderBoardEntry.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export interface LeaderBoardEntry {
- name: string;
- score: number;
- avatar: string;
-}
diff --git a/client/lib/interfaces/Vec2.ts b/client/lib/interfaces/Vec2.ts
deleted file mode 100644
index b2bae37..0000000
--- a/client/lib/interfaces/Vec2.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-export interface Coord2D {
- x: number;
- y: number;
-}
-
-export interface Dimension2D {
- width: number;
- height: number;
-}
-
-export interface Velocity2D {
- dx: number;
- dy: number;
-}
-
-export interface Force2D {
- fCartesian: {
- fx: number;
- fy: number;
- };
- torque: number;
-}
diff --git a/client/lib/interfaces/index.ts b/client/lib/interfaces/index.ts
deleted file mode 100644
index 0398abd..0000000
--- a/client/lib/interfaces/index.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export * from "./LeaderBoardEntry";
-export * from "./Vec2";
-export * from "./Draw";
-export * from "./Direction";
-export * from "./Action";
diff --git a/client/lib/structures/QuadTree.ts b/client/lib/structures/QuadTree.ts
deleted file mode 100644
index 7913e59..0000000
--- a/client/lib/structures/QuadTree.ts
+++ /dev/null
@@ -1,154 +0,0 @@
-import type { Coord2D, Dimension2D } from "../interfaces";
-import { ComponentNames, BoundingBox } from "../components";
-import { Entity } from "../entities";
-
-interface BoxedEntry {
- id: number;
- dimension: Dimension2D;
- center: Coord2D;
-}
-
-enum Quadrant {
- I,
- II,
- III,
- IV,
-}
-
-export class QuadTree {
- private maxLevels: number;
- private splitThreshold: number;
- private level: number;
- private topLeft: Coord2D;
- private dimension: Dimension2D;
-
- private children: Map<Quadrant, QuadTree>;
- private objects: BoxedEntry[];
-
- constructor(
- topLeft: Coord2D,
- dimension: Dimension2D,
- maxLevels: number,
- splitThreshold: number,
- level?: number
- ) {
- this.children = [];
- this.objects = [];
-
- this.maxLevels = maxLevels;
- this.splitThreshold = splitThreshold;
- this.level = level ?? 0;
- }
-
- public insert(id: number, dimension: Dimension2D, center: Coord2D): void {
- if (this.hasChildren()) {
- this.getIndices(boundingBox).forEach((i) =>
- this.children[i].insert(id, dimension, center)
- );
- return;
- }
-
- this.objects.push({ id, dimension, center });
-
- if (
- this.objects.length > this.splitThreshold &&
- this.level < this.maxLevels
- ) {
- if (!this.hasChildren()) {
- this.performSplit();
- }
- this.realignObjects();
- }
- }
-
- public clear(): void {
- this.objects = [];
- if (this.hasChildren()) {
- this.children.forEach((child) => child.clear());
- this.children.clear();
- }
- }
-
- public getNeighborIds(boxedEntry: BoxedEntry): number[] {
- const neighbors: number[] = this.objects.map(({ id }) => id);
-
- if (this.hasChildren()) {
- this.getQuadrants(boxedEntry).forEach((quadrant) => {
- this.children
- .get(quadrant)
- .getNeighborIds(boxedEntry)
- .forEach((id) => neighbors.push(id));
- });
- }
-
- return neighbors;
- }
-
- private performSplit(): void {
- const halfWidth = this.dimension.width / 2;
- const halfHeight = this.dimension.height / 2;
-
- [
- [Quadrant.I, { x: this.topLeft.x + halfWidth, y: this.topLeft.y }],
- [Quadrant.II, { ...this.topLeft }],
- [Quadrant.III, { x: this.topLeft.x, y: this.topLeft.y + halfHeight }],
- [
- Quadrant.IV,
- { x: this.topLeft.x + halfWidth, y: this.topLeft.y + halfHeight },
- ],
- ].forEach(([quadrant, pos]) => {
- this.children.set(
- quadrant,
- new QuadTree(
- pos,
- { width: halfWidth, height: halfHeight },
- this.maxLevels,
- this.splitThreshold,
- this.level + 1
- )
- );
- });
- }
-
- private getQuandrants(boxedEntry: BoxedEntry): Quadrant[] {
- const treeCenter: Coord2D = {
- x: this.topLeft.x + this.dimension.width / 2,
- y: this.topLeft.y + this.dimension.height / 2,
- };
-
- return [
- [Quadrant.I, (x, y) => x >= treeCenter.x && y < treeCenter.y],
- [Quadrant.II, (x, y) => x < treeCenter.x && y < treeCenter.y],
- [Quadrant.III, (x, y) => x < treeCenter.x && y >= treeCenter.y],
- [Quadrant.IV, (x, y) => x >= treeCenter.x && y >= treeCenter.y],
- ]
- .filter(
- ([_quadrant, condition]) =>
- condition(
- boxedEntry.center.x + boxedEntry.dimension.width / 2,
- boxedEntry.center.y + boxedEntry.dimension.height / 2
- ) ||
- condition(
- boxedEntry.center.x - boxedEntry.dimension.width / 2,
- boxedEntry.center.y - boxedEntry.dimension.height / 2
- )
- )
- .map(([quadrant]) => quadrant);
- }
-
- private realignObjects(): void {
- this.objects.forEach((boxedEntry) => {
- this.getQuadrants(boxedEntry).forEach((direction) => {
- this.children
- .get(direction)
- .insert(boxedEntry.id, boxedEntry.dimension, boxedEntry.center);
- });
- });
-
- this.objects = [];
- }
-
- private hasChildren() {
- return this.children && this.children.length > 0;
- }
-}
diff --git a/client/lib/structures/index.ts b/client/lib/structures/index.ts
deleted file mode 100644
index 605a82a..0000000
--- a/client/lib/structures/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "./QuadTree";
diff --git a/client/lib/systems/Collision.ts b/client/lib/systems/Collision.ts
deleted file mode 100644
index 16ad8c6..0000000
--- a/client/lib/systems/Collision.ts
+++ /dev/null
@@ -1,214 +0,0 @@
-import { SystemNames, System } from ".";
-import {
- Mass,
- BoundingBox,
- ComponentNames,
- Jump,
- Velocity,
- Moment,
-} from "../components";
-import { PhysicsConstants } from "../config";
-import { Entity } from "../entities";
-import type { Dimension2D } from "../interfaces";
-import { QuadTree } from "../structures";
-
-export class Collision extends System {
- private static readonly COLLIDABLE_COMPONENTS = [
- ComponentNames.Collide,
- ComponentNames.TopCollidable,
- ];
- private static readonly QUADTREE_MAX_LEVELS = 10;
- private static readonly QUADTREE_SPLIT_THRESHOLD = 10;
-
- private quadTree: QuadTree;
-
- constructor(screenDimensions: Dimension2D) {
- super(SystemNames.Collision);
-
- this.quadTree = new QuadTree(
- { x: 0, y: 0 },
- screenDimensions,
- Collision.QUADTREE_MAX_LEVELS,
- Collision.QUADTREE_SPLIT_THRESHOLD
- );
- }
-
- public update(
- dt: number,
- entityMap: Map<number, Entity>,
- entityComponents: Map<string, Set<number>>
- ) {
- this.quadTree.clear();
-
- const entitiesToAddToQuadtree: Entity[] = [];
- Collision.COLLIDABLE_COMPONENTS.map((componentName) =>
- entityComponents.get(componentName)
- ).forEach((entityIds: Set<number>) =>
- entityIds.forEach((id) => {
- const entity = entityMap.get(id);
- if (!entity.hasComponent(ComponentNames.BoundingBox)) {
- return;
- }
- entitiesToAddToQuadtree.push(entity);
- })
- );
-
- entitiesToAddToQuadtree.forEach((entity) => {
- const boundingBox = entity.getComponent<BoundingBox>(
- ComponentNames.BoundingBox
- );
-
- this.quadTree.insert(
- entity.id,
- boundingBox.dimension,
- boundingBox.center
- );
- });
-
- const collidingEntities = this.getCollidingEntities(
- entitiesToAddToQuadtree,
- entityMap
- );
- collidingEntities.forEach(([entityAId, entityBId]) => {
- const [entityA, entityB] = [entityAId, entityBId].map((id) =>
- entityMap.get(id)
- );
- this.performCollision(entityA, entityB);
- });
- }
-
- private performCollision(entityA: Entity, entityB: Entity) {
- const [entityABoundingBox, entityBBoundingBox] = [entityA, entityB].map(
- (entity) => entity.getComponent<BoundingBox>(ComponentNames.BoundingBox)
- );
-
- let velocity: Velocity;
- if (entityA.hasComponent(ComponentNames.Velocity)) {
- velocity = entityA.getComponent<Velocity>(ComponentNames.Velocity);
- }
-
- if (
- entityA.hasComponent(ComponentNames.Collide) &&
- entityB.hasComponent(ComponentNames.TopCollidable) &&
- entityABoundingBox.center.y <= entityBBoundingBox.center.y &&
- velocity &&
- velocity.dCartesian.dy >= 0 // don't apply floor logic when coming through the bottom
- ) {
- if (entityBBoundingBox.rotation != 0) {
- throw new Error(
- `entity with id ${entityB.id} has TopCollidable component and a non-zero rotation. that is not (yet) supported.`
- );
- }
-
- // remove previous velocity in the y axis
- velocity.dCartesian.dy = 0;
-
- // apply normal force
- if (entityA.hasComponent(ComponentNames.Gravity)) {
- const mass = entityA.getComponent<Mass>(ComponentNames.Mass).mass;
- const F_n = -mass * PhysicsConstants.GRAVITY;
-
- entityA.getComponent<Forces>(ComponentNames.Forces).forces.push({
- fCartesian: { fy: F_n },
- });
- }
-
- // reset the entities' jump
- if (entityA.hasComponent(ComponentNames.Jump)) {
- entityA.getComponent<Jump>(ComponentNames.Jump).canJump = true;
- }
-
- entityABoundingBox.center.y =
- entityBBoundingBox.center.y -
- entityBBoundingBox.dimension.height / 2 -
- this.getDyToPushOutOfFloor(entityABoundingBox, entityBBoundingBox);
- }
- }
-
- private getCollidingEntities(
- collidableEntities: Entity[],
- entityMap: Map<number, Entity>
- ): [number, number][] {
- const collidingEntityIds: [number, number] = [];
-
- for (const entity of collidableEntities) {
- const boundingBox = entity.getComponent<BoundingBox>(
- ComponentNames.BoundingBox
- );
-
- this.quadTree
- .getNeighborIds({
- id: entity.id,
- dimension: boundingBox.dimension,
- center: boundingBox.center,
- })
- .filter((neighborId) => neighborId != entity.id)
- .forEach((neighborId) => {
- const neighborBoundingBox = entityMap
- .get(neighborId)
- .getComponent<BoundingBox>(ComponentNames.BoundingBox);
-
- if (boundingBox.isCollidingWith(neighborBoundingBox)) {
- collidingEntityIds.push([entity.id, neighborId]);
- }
- });
- }
-
- return collidingEntityIds;
- }
-
- private getDyToPushOutOfFloor(
- entityBoundingBox: BoundingBox,
- floorBoundingBox: BoundingBox
- ): number {
- // ramblings: https://excalidraw.com/#json=z-xD86Za4a3duZuV2Oky0,KaGe-5iHJu1Si8inEo4GLQ
- const {
- rotation,
- center: { x, y },
- dimension: { width, height },
- } = entityBoundingBox;
-
- let rads = rotation * (Math.PI / 180);
- if (rads >= Math.PI) {
- rads -= Math.PI; // we have symmetry so we can skip two cases
- }
-
- let boundedCollisionX = 0; // bounded x on the surface from width
- let clippedX = 0; // x coordinate of the vertex below the surface
- let outScribedRectangleHeight, dy, dx;
-
- if (rads <= Math.PI / 2) {
- dx = (width * Math.cos(rads) - height * Math.sin(rads)) / 2;
- outScribedRectangleHeight =
- width * Math.sin(rads) + height * Math.cos(rads);
- } else if (rads <= Math.PI) {
- rads -= Math.PI / 2;
- dx = (height * Math.cos(rads) - width * Math.sin(rads)) / 2;
- outScribedRectangleHeight =
- width * Math.cos(rads) + height * Math.sin(rads);
- }
-
- if (x >= floorBoundingBox.center.x) {
- clippedX = x + dx;
- boundedCollisionX = Math.min(
- floorBoundingBox.center.x + floorBoundingBox.dimension.width / 2,
- clippedX
- );
- return (
- outScribedRectangleHeight / 2 -
- Math.max((clippedX - boundedCollisionX) * Math.tan(rads), 0)
- );
- }
-
- clippedX = x - dx;
- boundedCollisionX = Math.max(
- floorBoundingBox.center.x - floorBoundingBox.dimension.width / 2,
- clippedX
- );
-
- return (
- outScribedRectangleHeight / 2 -
- Math.max((boundedCollisionX - clippedX) * Math.tan(rads), 0)
- );
- }
-}
diff --git a/client/lib/systems/FacingDirection.ts b/client/lib/systems/FacingDirection.ts
deleted file mode 100644
index fbb4c7c..0000000
--- a/client/lib/systems/FacingDirection.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import {
- ComponentNames,
- Velocity,
- FacingDirection as FacingDirectionComponent,
-} from "../components";
-import type { Entity } from "../entities";
-import { System, SystemNames } from "./";
-
-export class FacingDirection extends System {
- constructor() {
- super(SystemNames.FacingDirection);
- }
-
- public update(
- _dt: number,
- entityMap: Map<number, Entity>,
- componentEntities: Map<string, Set<number>>
- ) {
- componentEntities
- .get(ComponentNames.FacingDirection)
- ?.forEach((entityId) => {
- const entity = entityMap.get(entityId);
- if (!entity.hasComponent(ComponentNames.Velocity)) {
- return;
- }
-
- const velocity = entity.getComponent<Velocity>(ComponentNames.Velocity);
- const facingDirection = entity.getComponent<FacingDirectionComponent>(
- ComponentNames.FacingDirection
- );
-
- if (velocity.dCartesian.dx > 0) {
- entity.addComponent(facingDirection.facingRightSprite);
- } else if (velocity.dCartesian.dx < 0) {
- entity.addComponent(facingDirection.facingLeftSprite);
- }
- });
- }
-}
diff --git a/client/lib/systems/Input.ts b/client/lib/systems/Input.ts
deleted file mode 100644
index 92932dd..0000000
--- a/client/lib/systems/Input.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import {
- Jump,
- Forces,
- Acceleration,
- ComponentNames,
- Velocity,
- Mass,
-} from "../components";
-import { KeyConstants, PhysicsConstants } from "../config";
-import type { Entity } from "../entities";
-import { Action } from "../interfaces";
-import { System, SystemNames } from "./";
-
-export class Input extends System {
- private keys: Set<string>;
- private actionTimeStamps: Map<Action, number>;
-
- constructor() {
- super(SystemNames.Input);
-
- this.keys = new Set<number>();
- this.actionTimeStamps = new Map<Action, number>();
- }
-
- public keyPressed(key: string) {
- this.keys.add(key);
- }
-
- public keyReleased(key: string) {
- this.keys.delete(key);
- }
-
- private hasSomeKey(keys: string[]): boolean {
- return keys.some((key) => this.keys.has(key));
- }
-
- public update(
- dt: number,
- entityMap: Map<number, Entity>,
- componentEntities: Map<string, Set<number>>
- ) {
- componentEntities.get(ComponentNames.Control)?.forEach((entityId) => {
- const entity = entityMap.get(entityId);
- if (!entity.hasComponent(ComponentNames.Velocity)) {
- return;
- }
-
- const velocity = entity.getComponent<Velocity>(ComponentNames.Velocity);
-
- if (this.hasSomeKey(KeyConstants.ActionKeys.get(Action.MOVE_RIGHT))) {
- velocity.dCartesian.dx = PhysicsConstants.PLAYER_MOVE_VEL;
- } else if (
- this.hasSomeKey(KeyConstants.ActionKeys.get(Action.MOVE_LEFT))
- ) {
- velocity.dCartesian.dx = -PhysicsConstants.PLAYER_MOVE_VEL;
- } else {
- velocity.dCartesian.dx = 0;
- }
- });
-
- componentEntities.get(ComponentNames.Jump)?.forEach((entityId) => {
- const entity = entityMap.get(entityId);
- const jump = entity.getComponent<Jump>(ComponentNames.Jump);
- const velocity = entity.getComponent<Velocity>(ComponentNames.Velocity);
-
- if (this.hasSomeKey(KeyConstants.ActionKeys.get(Action.JUMP))) {
- if (jump.canJump) {
- this.actionTimeStamps.set(Action.JUMP, performance.now());
-
- velocity.dCartesian.dy = PhysicsConstants.PLAYER_JUMP_INITIAL_VEL;
- jump.canJump = false;
- }
-
- if (
- performance.now() - this.actionTimeStamps.get(Action.JUMP) <
- PhysicsConstants.MAX_JUMP_TIME_MS
- ) {
- const mass = entity.getComponent<Mass>(ComponentNames.Mass).mass;
- entity.getComponent<Forces>(ComponentNames.Forces)?.forces.push({
- fCartesian: { fy: mass * PhysicsConstants.PLAYER_JUMP_ACC },
- });
- }
- }
- });
- }
-}
diff --git a/client/lib/systems/Physics.ts b/client/lib/systems/Physics.ts
deleted file mode 100644
index 319ae29..0000000
--- a/client/lib/systems/Physics.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { System, SystemNames } from ".";
-import {
- Acceleration,
- BoundingBox,
- ComponentNames,
- Forces,
- Gravity,
- Velocity,
- Mass,
- Jump,
-} from "../components";
-import { PhysicsConstants } from "../config";
-import type { Entity } from "../entities";
-import type { Force2D } from "../interfaces";
-
-export class Physics extends System {
- constructor() {
- super(SystemNames.Physics);
- }
-
- public update(
- dt: number,
- entityMap: Map<number, Entity>,
- componentEntities: Map<string, Set<number>>
- ): void {
- componentEntities.get(ComponentNames.Forces)?.forEach((entityId) => {
- const entity = entityMap.get(entityId);
-
- const mass = entity.getComponent<Mass>(ComponentNames.Mass).mass;
- const forces = entity.getComponent<Forces>(ComponentNames.Forces).forces;
- const velocity = entity.getComponent<Velocity>(ComponentNames.Velocity);
- const inertia = entity.getComponent<Moment>(
- ComponentNames.Moment
- ).inertia;
-
- // F_g = mg, applied only until terminal velocity is reached
- if (entity.hasComponent(ComponentNames.Gravity)) {
- const gravity = entity.getComponent<Gravity>(ComponentNames.Gravity);
- if (velocity.dCartesian.dy <= gravity.terminalVelocity) {
- forces.push({
- fCartesian: {
- fy: mass * PhysicsConstants.GRAVITY,
- },
- });
- }
- }
-
- // ma = Σ(F), Iα = Σ(T)
- const sumOfForces = forces.reduce(
- (accum: Force2D, { fCartesian, torque }: Force2D) => ({
- fCartesian: {
- fx: accum.fCartesian.fx + (fCartesian?.fx ?? 0),
- fy: accum.fCartesian.fy + (fCartesian?.fy ?? 0),
- },
- torque: accum.torque + (torque ?? 0),
- }),
- { fCartesian: { fx: 0, fy: 0 }, torque: 0 }
- );
-
- // integrate accelerations
- const [ddy, ddx] = [
- sumOfForces.fCartesian.fy,
- sumOfForces.fCartesian.fx,
- ].map((x) => x / mass);
- velocity.dCartesian.dx += ddx * dt;
- velocity.dCartesian.dy += ddy * dt;
- velocity.dTheta += (sumOfForces.torque * dt) / inertia;
- // clear the forces
- entity.getComponent<Forces>(ComponentNames.Forces).forces = [];
-
- // maybe we fell off the floor
- if (ddy > 0 && entity.hasComponent(ComponentNames.Jump)) {
- entity.getComponent<Jump>(ComponentNames.Jump).canJump = false;
- }
- });
-
- componentEntities.get(ComponentNames.Velocity)?.forEach((entityId) => {
- const entity = entityMap.get(entityId);
- const velocity = entity.getComponent<Velocity>(ComponentNames.Velocity);
- const boundingBox = entity.getComponent<BoundingBox>(
- ComponentNames.BoundingBox
- );
-
- // integrate velocity
- boundingBox.center.x += velocity.dCartesian.dx * dt;
- boundingBox.center.y += velocity.dCartesian.dy * dt;
- boundingBox.rotation += velocity.dTheta * dt;
- boundingBox.rotation =
- (boundingBox.rotation < 0
- ? 360 + boundingBox.rotation
- : boundingBox.rotation) % 360;
- });
- }
-}
diff --git a/client/lib/systems/Render.ts b/client/lib/systems/Render.ts
deleted file mode 100644
index 0c76b00..0000000
--- a/client/lib/systems/Render.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { System, SystemNames } from ".";
-import { BoundingBox, ComponentNames, Sprite } from "../components";
-import type { Entity } from "../entities";
-import type { DrawArgs } from "../interfaces";
-
-export class Render extends System {
- private ctx: CanvasRenderingContext2D;
-
- constructor(ctx: CanvasRenderingContext2D) {
- super(SystemNames.Render);
- this.ctx = ctx;
- }
-
- public update(
- dt: number,
- entityMap: Map<number, Entity>,
- componentEntities: Map<string, Set<number>>
- ) {
- this.ctx.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
-
- componentEntities.get(ComponentNames.Sprite)?.forEach((entityId) => {
- const entity = entityMap.get(entityId);
- const sprite = entity.getComponent<Sprite>(ComponentNames.Sprite);
- sprite.update(dt);
-
- let drawArgs: DrawArgs;
- if (entity.hasComponent(ComponentNames.BoundingBox)) {
- const boundingBox = entity.getComponent<BoundingBox>(
- ComponentNames.BoundingBox
- );
-
- drawArgs = {
- center: boundingBox.center,
- dimension: boundingBox.dimension,
- rotation: boundingBox.rotation,
- };
- }
- sprite.draw(this.ctx, drawArgs);
- });
- }
-}
diff --git a/client/lib/systems/System.ts b/client/lib/systems/System.ts
deleted file mode 100644
index 2accc97..0000000
--- a/client/lib/systems/System.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Entity } from "../entities";
-
-export abstract class System {
- public readonly name: string;
-
- constructor(name: string) {
- this.name = name;
- }
-
- abstract update(
- dt: number,
- entityMap: Map<number, Entity>,
- componentEntities: Map<string, Set<number>>
- ): void;
-}
diff --git a/client/lib/systems/WallBounds.ts b/client/lib/systems/WallBounds.ts
deleted file mode 100644
index 3fd5dc4..0000000
--- a/client/lib/systems/WallBounds.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { System, SystemNames } from ".";
-import { BoundingBox, ComponentNames } from "../components";
-import type { Entity } from "../entities";
-
-export class WallBounds extends System {
- private screenWidth: number;
-
- constructor(screenWidth: number) {
- super(SystemNames.WallBounds);
-
- this.screenWidth = screenWidth;
- }
-
- public update(
- _dt: number,
- entityMap: Map<number, Entity>,
- componentEntities: Map<string, Set<number>>
- ) {
- componentEntities.get(ComponentNames.WallBounded)?.forEach((entityId) => {
- const entity = entityMap.get(entityId);
- if (!entity.hasComponent(ComponentNames.BoundingBox)) {
- return;
- }
-
- const boundingBox = entity.getComponent<BoundingBox>(
- ComponentNames.BoundingBox
- );
-
- boundingBox.center.x = Math.min(
- this.screenWidth - boundingBox.dimension.width / 2,
- Math.max(boundingBox.dimension.width / 2, boundingBox.center.x)
- );
- });
- }
-}
diff --git a/client/lib/systems/index.ts b/client/lib/systems/index.ts
deleted file mode 100644
index 6cb6f35..0000000
--- a/client/lib/systems/index.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export * from "./names";
-export * from "./System";
-export * from "./Render";
-export * from "./Physics";
-export * from "./Input";
-export * from "./FacingDirection";
-export * from "./Collision";
-export * from "./WallBounds";
diff --git a/client/lib/systems/names.ts b/client/lib/systems/names.ts
deleted file mode 100644
index 23f31fc..0000000
--- a/client/lib/systems/names.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export namespace SystemNames {
- export const Render = "Render";
- export const Physics = "Physics";
- export const FacingDirection = "FacingDirection";
- export const Input = "Input";
- export const Collision = "Collision";
- export const WallBounds = "WallBounds";
-}
diff --git a/client/lib/utils/dotProduct.ts b/client/lib/utils/dotProduct.ts
deleted file mode 100644
index 59f8857..0000000
--- a/client/lib/utils/dotProduct.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-import type { Coord2D } from "../interfaces";
-
-export const dotProduct = (vector1: Coord2D, vector2: Coord2D): number =>
- vector1.x * vector2.x + vector1.y * vector2.y;
diff --git a/client/lib/utils/index.ts b/client/lib/utils/index.ts
deleted file mode 100644
index 1f8e2f0..0000000
--- a/client/lib/utils/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from "./rotateVector";
-export * from "./normalizeVector";
-export * from "./dotProduct";
diff --git a/client/lib/utils/normalizeVector.ts b/client/lib/utils/normalizeVector.ts
deleted file mode 100644
index e6dfd7f..0000000
--- a/client/lib/utils/normalizeVector.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import type { Coord2D } from "../interfaces";
-
-export const normalizeVector = (vector: Coord2D): Coord2D => {
- const { x, y } = vector;
- const length = Math.sqrt(x * x + y * y);
-
- return { x: x / length, y: y / length };
-};
diff --git a/client/lib/utils/rotateVector.ts b/client/lib/utils/rotateVector.ts
deleted file mode 100644
index 82bb54d..0000000
--- a/client/lib/utils/rotateVector.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import type { Coord2D } from "../interfaces";
-
-/**
- * ([[cos(θ), -sin(θ),]) ([x,)
- * ([sin(θ), cos(θ)] ]) ( y])
- */
-export const rotateVector = (vector: Coord2D, theta: number): Coord2D => {
- const rads = (theta * Math.PI) / 180;
- const [cos, sin] = [Math.cos(rads), Math.sin(rads)];
-
- return {
- x: vector.x * cos - vector.y * sin,
- y: vector.x * sin + vector.y * cos,
- };
-};
diff --git a/client/package-lock.json b/client/package-lock.json
index 641f566..bf627d9 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -7,6 +7,9 @@
"": {
"name": "client",
"version": "0.0.0",
+ "dependencies": {
+ "module-alias": "^2.2.3"
+ },
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^2.0.4",
"@tsconfig/svelte": "^4.0.1",
@@ -1585,6 +1588,11 @@
"mkdirp": "bin/cmd.js"
}
},
+ "node_modules/module-alias": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.3.tgz",
+ "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q=="
+ },
"node_modules/mri": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
diff --git a/client/package.json b/client/package.json
index 1ddd2b8..43c1b66 100644
--- a/client/package.json
+++ b/client/package.json
@@ -20,5 +20,8 @@
"tslib": "^2.5.0",
"typescript": "^5.0.2",
"vite": "^4.3.9"
+ },
+ "dependencies": {
+ "module-alias": "^2.2.3"
}
}
diff --git a/client/lib/JumpStorm.ts b/client/src/JumpStorm.ts
index c76d9bc..45ea163 100644
--- a/client/lib/JumpStorm.ts
+++ b/client/src/JumpStorm.ts
@@ -1,5 +1,5 @@
-import { Floor, Player } from "./entities";
-import { Game } from "./Game";
+import { Floor, Player } from "@engine/entities";
+import { Game } from "@engine/Game";
import {
WallBounds,
FacingDirection,
@@ -7,7 +7,7 @@ import {
Physics,
Input,
Collision,
-} from "./systems";
+} from "@engine/systems";
export class JumpStorm {
private game: Game;
diff --git a/client/src/components/GameCanvas.svelte b/client/src/components/GameCanvas.svelte
index 766a08a..d7abecf 100644
--- a/client/src/components/GameCanvas.svelte
+++ b/client/src/components/GameCanvas.svelte
@@ -1,11 +1,8 @@
<script lang="ts">
import { onMount } from "svelte";
- import { Game } from "../../lib/Game";
- import { Render } from "../../lib/systems";
- import { Floor } from "../../lib/entities";
- import { loadAssets } from "../../lib/config";
- import { JumpStorm } from "../../lib/JumpStorm";
-
+ import { loadAssets } from "@engine/config";
+ import { JumpStorm} from "../Jumpstorm";
+
let canvas: HTMLCanvasElement;
let ctx: CanvasRenderingContext2D;
diff --git a/client/src/components/LeaderBoard.svelte b/client/src/components/LeaderBoard.svelte
index d6e4ce3..880e64a 100644
--- a/client/src/components/LeaderBoard.svelte
+++ b/client/src/components/LeaderBoard.svelte
@@ -1,5 +1,5 @@
<script lang="ts">
- import { type LeaderBoardEntry } from "../../lib/interfaces";
+ import { type LeaderBoardEntry } from "@engine/interfaces";
import LeaderBoardCard from "./LeaderBoardCard.svelte";
const MAX_ENTRIES = 8;
diff --git a/client/src/components/LeaderBoardCard.svelte b/client/src/components/LeaderBoardCard.svelte
index 446d734..f46c000 100644
--- a/client/src/components/LeaderBoardCard.svelte
+++ b/client/src/components/LeaderBoardCard.svelte
@@ -1,5 +1,5 @@
<script lang="ts">
- import { type LeaderBoardEntry } from "../../lib/interfaces";
+ import { type LeaderBoardEntry } from "@engine/interfaces";
export let entry: LeaderBoardEntry = {
name: "simponic",
diff --git a/client/tsconfig.json b/client/tsconfig.json
index eabe862..781d1b3 100644
--- a/client/tsconfig.json
+++ b/client/tsconfig.json
@@ -24,5 +24,8 @@
"src/**/*.js",
"src/**/*.svelte"
],
+ "paths": {
+ "@engine/*": ["../engine/*"]
+ },
"references": [{ "path": "./tsconfig.node.json" }]
}
diff --git a/client/vite.config.ts b/client/vite.config.ts
index d701969..0307338 100644
--- a/client/vite.config.ts
+++ b/client/vite.config.ts
@@ -1,7 +1,13 @@
-import { defineConfig } from 'vite'
-import { svelte } from '@sveltejs/vite-plugin-svelte'
+import { defineConfig } from "vite";
+import { svelte } from "@sveltejs/vite-plugin-svelte";
+import { fileURLToPath, URL } from "node:url";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [svelte()],
-})
+ resolve: {
+ alias: {
+ "@engine": fileURLToPath(new URL("../engine", import.meta.url)),
+ },
+ },
+});