Skip to content

Commit 0039c5d

Browse files
committed
refactor: clean up player state interface
1 parent f68d71a commit 0039c5d

4 files changed

Lines changed: 22 additions & 40 deletions

File tree

src/player/Player.ts

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import { StateMachine } from "./StateMachine";
2020
import { InputState, PlayerEffect, PlayerSnapshot, PlayerState } from "./types";
2121

2222
type DashHorizontalCollisionResult = "none" | "corrected" | "ducked";
23-
type PlayerMachineState = "normal" | "climb" | "dash";
2423

2524
const EPSILON = 0.0001;
2625
const EMPTY_INPUT: InputState = {
@@ -58,7 +57,7 @@ export class Player {
5857
private autoJump = false;
5958
private autoJumpTimer = 0;
6059

61-
private readonly stateMachine: StateMachine<PlayerMachineState>;
60+
private readonly stateMachine: StateMachine<PlayerState>;
6261
private frameDt = 0;
6362
private input: InputState = EMPTY_INPUT;
6463

@@ -115,7 +114,7 @@ export class Player {
115114
this.wallSlideTimer = toFloat(cfg.gravity.wallSlideTime);
116115
this.maxFall = toFloat(cfg.gravity.maxFall);
117116

118-
this.stateMachine = new StateMachine<PlayerMachineState>("normal");
117+
this.stateMachine = new StateMachine<PlayerState>("normal");
119118
this.stateMachine.setCallbacks(
120119
"normal",
121120
() => this.normalUpdate(),
@@ -409,26 +408,11 @@ export class Player {
409408
}
410409

411410
get state(): PlayerState {
412-
const state = this.stateMachine.state;
413-
if (state === "climb") {
414-
return "grab";
415-
}
416-
if (state === "normal" && this.ducking) {
417-
return "duck";
418-
}
419-
return state;
411+
return this.stateMachine.state;
420412
}
421413

422-
set state(value: PlayerState) {
423-
if (value === "grab") {
424-
this.stateMachine.state = "climb";
425-
return;
426-
}
427-
if (value === "dash" || value === "dashAttack") {
428-
this.stateMachine.state = "dash";
429-
return;
430-
}
431-
this.stateMachine.state = "normal";
414+
forceState(state: PlayerState): void {
415+
this.stateMachine.forceState(state);
432416
}
433417

434418
private refreshEnvironment(): void {
@@ -450,7 +434,7 @@ export class Player {
450434
this.hopWaitXSpeed = 0;
451435
}
452436

453-
private normalUpdate(): PlayerMachineState {
437+
private normalUpdate(): PlayerState {
454438
const dt = this.frameDt;
455439
const input = this.input;
456440

@@ -599,7 +583,7 @@ export class Player {
599583
this.wallSpeedRetentionTimer = 0;
600584
}
601585

602-
private climbUpdate(): PlayerMachineState {
586+
private climbUpdate(): PlayerState {
603587
const dt = this.frameDt;
604588
const input = this.input;
605589
this.climbNoMoveTimer = subFloat(this.climbNoMoveTimer, dt);
@@ -748,7 +732,7 @@ export class Player {
748732
private dashEnd(): void {
749733
}
750734

751-
private dashUpdate(): PlayerMachineState {
735+
private dashUpdate(): PlayerState {
752736
if (this.dashDir.y === 0) {
753737
this.applyDashJumpThruNudge();
754738

@@ -935,7 +919,7 @@ export class Player {
935919
return this.hasDashPress() && this.dashCooldownTimer <= 0 && this.dashesLeft > 0;
936920
}
937921

938-
private startDash(): PlayerMachineState {
922+
private startDash(): PlayerState {
939923
this.consumeDashPress();
940924
this.dashesLeft = Math.max(0, this.dashesLeft - 1);
941925
return "dash";

src/player/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export type PlayerState = "normal" | "duck" | "grab" | "dash" | "dashAttack";
1+
export type PlayerState = "normal" | "climb" | "dash";
22

33
export interface InputState {
44
x: number;

src/view/PlayerView.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,7 @@ export class PlayerView {
397397
const enteredDuck =
398398
!this.prevCrouched &&
399399
snapshot.isCrouched &&
400-
snapshot.onGround &&
401-
snapshot.state === "duck";
400+
snapshot.onGround;
402401
if (enteredDuck) {
403402
this.squash(PLAYER_VISUALS.duckSquashX, PLAYER_VISUALS.duckSquashY);
404403
return;
@@ -408,7 +407,6 @@ export class PlayerView {
408407
this.prevCrouched &&
409408
!snapshot.isCrouched &&
410409
this.prevOnGround &&
411-
this.prevState === "duck" &&
412410
snapshot.onGround;
413411
if (exitedDuck) {
414412
this.squash(PLAYER_VISUALS.unduckSquashX, PLAYER_VISUALS.unduckSquashY);
@@ -608,7 +606,7 @@ export class PlayerView {
608606
}
609607

610608
private resolveSqrt11Pose(snapshot: PlayerSnapshot): Sqrt11Pose {
611-
return snapshot.state === "duck" || snapshot.isCrouched ? "duck" : "idle";
609+
return snapshot.isCrouched ? "duck" : "idle";
612610
}
613611

614612
private applyGlyphSprite(

tests/tech/climb-tech.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe("Climb and dashless tech", () => {
2727
let climbedOut = false;
2828
for (let frame = 0; frame < 400; frame++) {
2929
const result = stepOnce(player, makeInput({ grab: true, y: -1 }));
30-
if (frame > 10 && result.snapshot.state !== "grab") {
30+
if (frame > 10 && result.snapshot.state !== "climb") {
3131
climbedOut = true;
3232
expect(result.snapshot.vy).toBeCloseTo(-120, 5);
3333
break;
@@ -56,7 +56,7 @@ describe("Climb and dashless tech", () => {
5656
snapshot = stepOnce(player, makeInput({ grab: true, y: -1 })).snapshot;
5757
}
5858

59-
expect(snapshot.state).toBe("grab");
59+
expect(snapshot.state).toBe("climb");
6060
expect(snapshot.vx).toBe(0);
6161
expect(snapshot.vy).toBeCloseTo(0, 5);
6262
});
@@ -94,7 +94,7 @@ describe("Climb and dashless tech", () => {
9494
);
9595

9696
stepOnce(player, makeInput({ grab: true }));
97-
expect(player.getSnapshot().state).toBe("grab");
97+
expect(player.getSnapshot().state).toBe("climb");
9898

9999
stepOnce(player, makeInput({ grab: true, jump: true, jumpPressed: true, x: 0 }));
100100
expect(player.getSnapshot().stamina).toBeCloseTo(82.5, 5);
@@ -175,12 +175,12 @@ describe("Climb and dashless tech", () => {
175175
);
176176

177177
stepOnce(player, makeInput({ grab: true }));
178-
expect(player.getSnapshot().state).toBe("grab");
178+
expect(player.getSnapshot().state).toBe("climb");
179179

180180
let exhausted: ReturnType<typeof player.getSnapshot> | null = null;
181181
for (let frame = 0; frame < 240; frame++) {
182182
const result = stepOnce(player, makeInput({ grab: true, y: -1 }));
183-
if (result.snapshot.state !== "grab") {
183+
if (result.snapshot.state !== "climb") {
184184
exhausted = result.snapshot;
185185
break;
186186
}
@@ -200,13 +200,13 @@ describe("Climb and dashless tech", () => {
200200
const wallBottom = 17 * WORLD.tile;
201201
const player = createPlayer(world, 20 * WORLD.tile - PLAYER_GEOMETRY.hitboxW, wallBottom);
202202
const internals = player as unknown as {
203-
state: string;
203+
forceState: (state: PlayerSnapshot["state"]) => void;
204204
facing: 1 | -1;
205205
refreshEnvironment: () => void;
206206
climbCheck: (dir: number, yAdd?: number) => boolean;
207207
};
208208

209-
internals.state = "grab";
209+
internals.forceState("climb");
210210
internals.facing = 1;
211211
internals.refreshEnvironment();
212212

@@ -227,12 +227,12 @@ describe("Climb and dashless tech", () => {
227227
const player = createPlayer(world, 20 * WORLD.tile - PLAYER_GEOMETRY.hitboxW, wallBottom - 1);
228228
const internals = player as unknown as {
229229
climbNoMoveTimer: number;
230-
state: string;
230+
forceState: (state: PlayerSnapshot["state"]) => void;
231231
facing: 1 | -1;
232232
refreshEnvironment: () => void;
233233
};
234234

235-
internals.state = "grab";
235+
internals.forceState("climb");
236236
internals.facing = 1;
237237
internals.refreshEnvironment();
238238
internals.climbNoMoveTimer = 0;
@@ -243,7 +243,7 @@ describe("Climb and dashless tech", () => {
243243
stepOnce(player, makeInput({ x: 1, grab: true }));
244244
const secondTap = stepOnce(player, makeInput({ x: 1, y: 1, grab: true }));
245245

246-
expect(secondTap.snapshot.state).toBe("grab");
246+
expect(secondTap.snapshot.state).toBe("climb");
247247
expect(secondTap.snapshot.y).toBe(wallBottom);
248248
});
249249
});

0 commit comments

Comments
 (0)