| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- import { type GameDefinition } from './gameDefinition'
- import { type GameEvent } from './gameEvent'
- import { type GameResult } from './gameResult'
- import { type GameSessionState } from './gameSessionState'
- import { EMPTY_GAME_PRESENTATION_STATE, type GamePresentationState } from '../presentation/presentationState'
- import { EMPTY_HUD_PRESENTATION_STATE, type HudPresentationState } from '../presentation/hudPresentationState'
- import { EMPTY_MAP_PRESENTATION_STATE, type MapPresentationState } from '../presentation/mapPresentationState'
- import { ClassicSequentialRule } from '../rules/classicSequentialRule'
- import { ScoreORule } from '../rules/scoreORule'
- import { type RulePlugin } from '../rules/rulePlugin'
- export class GameRuntime {
- definition: GameDefinition | null
- plugin: RulePlugin | null
- state: GameSessionState | null
- presentation: GamePresentationState
- mapPresentation: MapPresentationState
- hudPresentation: HudPresentationState
- lastResult: GameResult | null
- constructor() {
- this.definition = null
- this.plugin = null
- this.state = null
- this.presentation = EMPTY_GAME_PRESENTATION_STATE
- this.mapPresentation = EMPTY_MAP_PRESENTATION_STATE
- this.hudPresentation = EMPTY_HUD_PRESENTATION_STATE
- this.lastResult = null
- }
- clear(): void {
- this.definition = null
- this.plugin = null
- this.state = null
- this.presentation = EMPTY_GAME_PRESENTATION_STATE
- this.mapPresentation = EMPTY_MAP_PRESENTATION_STATE
- this.hudPresentation = EMPTY_HUD_PRESENTATION_STATE
- this.lastResult = null
- }
- loadDefinition(definition: GameDefinition): GameResult {
- this.definition = definition
- this.plugin = this.resolvePlugin(definition)
- this.state = this.plugin.initialize(definition)
- const result: GameResult = {
- nextState: this.state,
- presentation: this.plugin.buildPresentation(definition, this.state),
- effects: [],
- }
- this.presentation = result.presentation
- this.mapPresentation = result.presentation.map
- this.hudPresentation = result.presentation.hud
- this.lastResult = result
- return result
- }
- startSession(startAt = Date.now()): GameResult {
- return this.dispatch({ type: 'session_started', at: startAt })
- }
- dispatch(event: GameEvent): GameResult {
- if (!this.definition || !this.plugin || !this.state) {
- const emptyState: GameSessionState = {
- status: 'idle',
- startedAt: null,
- endedAt: null,
- completedControlIds: [],
- currentTargetControlId: null,
- inRangeControlId: null,
- score: 0,
- guidanceState: 'searching',
- modeState: null,
- }
- const result: GameResult = {
- nextState: emptyState,
- presentation: EMPTY_GAME_PRESENTATION_STATE,
- effects: [],
- }
- this.lastResult = result
- this.presentation = result.presentation
- this.mapPresentation = result.presentation.map
- this.hudPresentation = result.presentation.hud
- return result
- }
- const result = this.plugin.reduce(this.definition, this.state, event)
- this.state = result.nextState
- this.presentation = result.presentation
- this.mapPresentation = result.presentation.map
- this.hudPresentation = result.presentation.hud
- this.lastResult = result
- return result
- }
- getPresentation(): GamePresentationState {
- return this.presentation
- }
- getMapPresentation(): MapPresentationState {
- return this.mapPresentation
- }
- getHudPresentation(): HudPresentationState {
- return this.hudPresentation
- }
- resolvePlugin(definition: GameDefinition): RulePlugin {
- if (definition.mode === 'classic-sequential') {
- return new ClassicSequentialRule()
- }
- if (definition.mode === 'score-o') {
- return new ScoreORule()
- }
- throw new Error(`未支持的玩法模式: ${definition.mode}`)
- }
- }
|