Add score-o mode and split game map HUD presentation
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { type LonLatPoint } from '../../utils/projection'
|
||||
import { type GameAudioConfig } from '../audio/audioConfig'
|
||||
|
||||
export type GameMode = 'classic-sequential'
|
||||
export type GameMode = 'classic-sequential' | 'score-o'
|
||||
export type GameControlKind = 'start' | 'control' | 'finish'
|
||||
export type PunchPolicyType = 'enter' | 'enter-confirm'
|
||||
|
||||
|
||||
@@ -2,4 +2,5 @@ export type GameEvent =
|
||||
| { type: 'session_started'; at: number }
|
||||
| { type: 'gps_updated'; at: number; lon: number; lat: number; accuracyMeters: number | null }
|
||||
| { type: 'punch_requested'; at: number }
|
||||
| { type: 'control_focused'; at: number; controlId: string | null }
|
||||
| { type: 'session_ended'; at: number }
|
||||
|
||||
@@ -3,7 +3,10 @@ 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 {
|
||||
@@ -11,6 +14,8 @@ export class GameRuntime {
|
||||
plugin: RulePlugin | null
|
||||
state: GameSessionState | null
|
||||
presentation: GamePresentationState
|
||||
mapPresentation: MapPresentationState
|
||||
hudPresentation: HudPresentationState
|
||||
lastResult: GameResult | null
|
||||
|
||||
constructor() {
|
||||
@@ -18,6 +23,8 @@ export class GameRuntime {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -26,6 +33,8 @@ export class GameRuntime {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -39,6 +48,8 @@ export class GameRuntime {
|
||||
effects: [],
|
||||
}
|
||||
this.presentation = result.presentation
|
||||
this.mapPresentation = result.presentation.map
|
||||
this.hudPresentation = result.presentation.hud
|
||||
this.lastResult = result
|
||||
return result
|
||||
}
|
||||
@@ -58,6 +69,7 @@ export class GameRuntime {
|
||||
inRangeControlId: null,
|
||||
score: 0,
|
||||
guidanceState: 'searching',
|
||||
modeState: null,
|
||||
}
|
||||
const result: GameResult = {
|
||||
nextState: emptyState,
|
||||
@@ -66,12 +78,16 @@ export class GameRuntime {
|
||||
}
|
||||
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
|
||||
}
|
||||
@@ -80,11 +96,23 @@ export class GameRuntime {
|
||||
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}`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export type GameSessionStatus = 'idle' | 'running' | 'finished' | 'failed'
|
||||
export type GuidanceState = 'searching' | 'approaching' | 'ready'
|
||||
export type GameModeState = Record<string, unknown> | null
|
||||
|
||||
export interface GameSessionState {
|
||||
status: GameSessionStatus
|
||||
@@ -10,4 +11,5 @@ export interface GameSessionState {
|
||||
inRangeControlId: string | null
|
||||
score: number
|
||||
guidanceState: GuidanceState
|
||||
modeState: GameModeState
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user