summaryrefslogtreecommitdiff
path: root/engine/entities
diff options
context:
space:
mode:
Diffstat (limited to 'engine/entities')
-rw-r--r--engine/entities/Entity.ts33
-rw-r--r--engine/entities/Floor.ts31
-rw-r--r--engine/entities/Player.ts68
-rw-r--r--engine/entities/index.ts3
4 files changed, 135 insertions, 0 deletions
diff --git a/engine/entities/Entity.ts b/engine/entities/Entity.ts
new file mode 100644
index 0000000..e57ccde
--- /dev/null
+++ b/engine/entities/Entity.ts
@@ -0,0 +1,33 @@
+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/engine/entities/Floor.ts b/engine/entities/Floor.ts
new file mode 100644
index 0000000..d51badc
--- /dev/null
+++ b/engine/entities/Floor.ts
@@ -0,0 +1,31 @@
+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/engine/entities/Player.ts b/engine/entities/Player.ts
new file mode 100644
index 0000000..0ba5a41
--- /dev/null
+++ b/engine/entities/Player.ts
@@ -0,0 +1,68 @@
+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/engine/entities/index.ts b/engine/entities/index.ts
new file mode 100644
index 0000000..a921512
--- /dev/null
+++ b/engine/entities/index.ts
@@ -0,0 +1,3 @@
+export * from "./Entity";
+export * from "./Floor";
+export * from "./Player";