Skip to content

Commit 8f6bbac

Browse files
committed
components initialization before main loop & zip script
1 parent 388df08 commit 8f6bbac

File tree

6 files changed

+140
-12
lines changed

6 files changed

+140
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ node_modules
1111
dist
1212
dist-ssr
1313
*.local
14+
zipped.zip
1415

1516
# Editor directories and files
1617
.vscode/*

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
"typescript": "^4.6.4",
1313
"vite": "^3.0.7"
1414
}
15-
}
15+
}

scripts/zip.ps1

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# compress dist contents to zip and force write if ./zipped.zip already exists
2+
Compress-Archive -Force -Path .\dist\* -DestinationPath .\zipped.zip
3+
# prints file size in KB
4+
Write-Host((Get-Item .\zipped.zip).length/1KB)

src/components.ts

Lines changed: 124 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import { Entity } from "./entities";
22
import { INPUT } from "./input";
33

4+
interface Renderer {
5+
render(ctx: CanvasRenderingContext2D): void;
6+
}
7+
48
export type Components = {
59
transform: TransformComponent;
6-
renderer: RenderComponent;
7-
movement: Movement;
10+
renderer: Renderer;
11+
movement: Component;
812
};
913

1014
class Component {
@@ -13,6 +17,37 @@ class Component {
1317
constructor(entity: Entity) {
1418
this.entity = entity;
1519
}
20+
21+
update?(deltaTime: number): void;
22+
start?(): void;
23+
}
24+
25+
class DeathRenderComponent extends Component implements Renderer {
26+
render(ctx: CanvasRenderingContext2D) {
27+
const transformComponent = COMPONENTS[this.entity]["transform"];
28+
if (!transformComponent) {
29+
console.error(`no transform component on ${this.entity}`);
30+
return;
31+
}
32+
33+
const { x, y } = transformComponent;
34+
ctx.font = "40px sans-serif";
35+
ctx.fillText("💀", x, y);
36+
}
37+
}
38+
39+
class NPCRenderComponent extends Component implements Renderer {
40+
render(ctx: CanvasRenderingContext2D) {
41+
const transformComponent = COMPONENTS[this.entity]["transform"];
42+
if (!transformComponent) {
43+
console.error(`no transform component on ${this.entity}`);
44+
return;
45+
}
46+
47+
const { x, y } = transformComponent;
48+
ctx.font = "40px sans-serif";
49+
ctx.fillText("😐", x, y);
50+
}
1651
}
1752

1853
export class RenderComponent extends Component {
@@ -39,14 +74,10 @@ export class TransformComponent extends Component {
3974
}
4075
}
4176

42-
interface Movement {
43-
move(deltaTime: number): void;
44-
}
45-
46-
class PlayerMovement extends Component implements Movement {
77+
class PlayerMovement extends Component {
4778
speed: number = 0.5;
4879

49-
move(deltaTime: number) {
80+
update(deltaTime: number) {
5081
const transform = COMPONENTS[this.entity].transform;
5182
if (!transform) {
5283
console.error("no transform component on player");
@@ -84,10 +115,94 @@ class PlayerMovement extends Component implements Movement {
84115
}
85116
}
86117

118+
class NPCMovement extends Component {
119+
speed: number = 0.2;
120+
direction = [0, 0];
121+
accumulatedTime: number = 0;
122+
// @ts-ignore
123+
transform: TransformComponent;
124+
125+
start() {
126+
this.transform = COMPONENTS[this.entity].transform!;
127+
if (!this.transform) {
128+
throw `no transform component on ${this.entity}`;
129+
}
130+
}
131+
132+
private recomputeDirection() {
133+
const axis = Math.floor(Math.random() * 2);
134+
this.direction[axis] = Math.random() > 0.5 ? -1 : 1;
135+
this.direction[Math.abs(axis - 1)] = 0;
136+
}
137+
138+
private isOutOfBoundsBy(distance: number) {
139+
return (
140+
this.transform.x > window.innerWidth + distance ||
141+
this.transform.x < -distance ||
142+
this.transform.y < -distance ||
143+
this.transform.y > window.innerHeight + distance
144+
);
145+
}
146+
147+
update(deltaTime: number) {
148+
if (this.isOutOfBoundsBy(20) && this.accumulatedTime > 0) {
149+
this.direction[0] = -this.direction[0];
150+
this.direction[1] = -this.direction[1];
151+
this.accumulatedTime = 0;
152+
return;
153+
}
154+
155+
if (this.accumulatedTime >= 2000) {
156+
this.recomputeDirection();
157+
this.accumulatedTime = 0;
158+
return;
159+
}
160+
161+
this.accumulatedTime += deltaTime;
162+
163+
const moveBy = this.speed * deltaTime;
164+
if (this.direction[1] === 1) {
165+
this.transform.y -= moveBy;
166+
return;
167+
}
168+
if (this.direction[1] === -1) {
169+
this.transform.y += moveBy;
170+
return;
171+
}
172+
if (this.direction[0] === -1) {
173+
this.transform.x -= moveBy;
174+
return;
175+
}
176+
if (this.direction[0] === 1) {
177+
this.transform.x += moveBy;
178+
return;
179+
}
180+
}
181+
}
182+
87183
export const COMPONENTS: Record<Entity, Partial<Components>> = {
88184
player: {
89185
transform: new TransformComponent("player", 100, 100),
90-
renderer: new RenderComponent("player"),
186+
renderer: new DeathRenderComponent("player"),
91187
movement: new PlayerMovement("player"),
92188
},
189+
npc: {
190+
transform: new TransformComponent("npc", 200, 200),
191+
renderer: new NPCRenderComponent("npc"),
192+
movement: new NPCMovement("npc"),
193+
},
93194
};
195+
196+
// const ENTITIES = {
197+
// player: 0,
198+
// npc1: 1,
199+
// npc2: 2,
200+
// npc3: 3,
201+
// };
202+
// const COMPONENTS_MATRIX = [
203+
// [
204+
// new TransformComponent(ENTITIES.player, 100, 100),
205+
// new DeathRenderComponent(ENTITIES.player),
206+
// new PlayerMovement(ENTITIES.player),
207+
// ],
208+
// ];

src/entities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export const ENTITIES = ["player"] as const;
1+
export const ENTITIES = ["player", "npc"] as const;
22

33
export type Entity = typeof ENTITIES[number];

src/main.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,15 @@ function renderingSystem() {
2424

2525
function movementSystem(deltaTime: number) {
2626
for (const c of components) {
27-
c.movement?.move(deltaTime);
27+
c.movement?.update?.(deltaTime);
28+
}
29+
}
30+
31+
// initialize all components
32+
for (const cs of Object.values(COMPONENTS)) {
33+
for (const c of Object.values(cs)) {
34+
// @ts-ignore
35+
c?.start?.();
2836
}
2937
}
3038

0 commit comments

Comments
 (0)