Created
August 22, 2024 13:01
-
-
Save al-arz/2d40ef777f1292e4b6504e1b9782564e to your computer and use it in GitHub Desktop.
An excerpt of player movement processing logic in a turn-based roguelite game, utilizing chain of responisbility pattern.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Somewhere within the main gameplay controller class | |
private processHeroMove(nextPos: GlobalGridCoords) { | |
const interaction = new InteractionHandler(gameState); | |
const movement = new MovementHandler(gameState); | |
const combat = new CombatHandler(gameState); | |
const start = interaction; | |
interaction.next = movement; | |
movement.next = combat; | |
start.process(nextPos); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Handlers that can be chained to process player's move | |
export interface MoveHandler { | |
process(nextPos: GlobalGridCoords): void; | |
} | |
export abstract class BaseMoveHandler implements MoveHandler { | |
protected dungeon: Dungeon; // Game state object | |
public next: MoveHandler; | |
constructor(dungeon: Dungeon) { | |
this.dungeon = dungeon; | |
} | |
public process(nextPos: GlobalGridCoords) { | |
if (this.next) { | |
this.next.process(nextPos); | |
} | |
} | |
} | |
export class CombatHandler extends BaseMoveHandler { | |
constructor(dungeon: Dungeon) { | |
super(dungeon); | |
} | |
public process(nextPos: GlobalGridCoords): void { | |
const monsters = this.dungeon.findMonstersAround(this.dungeon.hero); | |
if (monsters.length > 0) { | |
EventBus.emit(DUNGEON_EVENTS.monstersContacted, monsters); | |
return; | |
} else { | |
super.process(nextPos); | |
} | |
} | |
} | |
export class InteractionHandler extends BaseMoveHandler { | |
constructor(dungeon: Dungeon) { | |
super(dungeon); | |
} | |
public process(nextPos: GlobalGridCoords): void { | |
const interactable = this.dungeon.findInteractable(nextPos); | |
if (interactable) { | |
const interactionResult = interactable.heroInteraction(this.dungeon.hero); | |
if (!interactionResult.move) { | |
return; | |
} | |
} | |
super.process(nextPos); | |
} | |
} | |
export class MovementHandler extends BaseMoveHandler { | |
constructor(dungeon: Dungeon) { | |
super(dungeon); | |
} | |
public process(nextPos: GlobalGridCoords): void { | |
const tileToMoveTo = dungeon.findTileToMove(dungeon.hero, nextPos); | |
if (tileToMoveTo) { | |
this.dungeon.hero.moveTo(nextPos); | |
EventBus.emit(PROGRESS_EVENTS.stepTaken); | |
EventBus.emit("PLAY_SOUND", "step"); | |
EventBus.emit(DUNGEON_EVENTS.heroMoved); | |
} | |
super.process(nextPos); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment