完善文创展示控制与结果层基础
This commit is contained in:
@@ -13,10 +13,12 @@ import { type OrienteeringCourseData } from '../../utils/orienteeringCourse'
|
||||
import { isTileWithinBounds, type RemoteMapConfig, type TileZoomBounds } from '../../utils/remoteMapConfig'
|
||||
import { formatAnimationLevelText, resolveAnimationLevel, type AnimationLevel } from '../../utils/animationLevel'
|
||||
import { GameRuntime } from '../../game/core/gameRuntime'
|
||||
import { type GameControlDisplayContentOverride } from '../../game/core/gameDefinition'
|
||||
import { type GameEffect, type GameResult } from '../../game/core/gameResult'
|
||||
import { buildGameDefinitionFromCourse } from '../../game/content/courseToGameDefinition'
|
||||
import { FeedbackDirector } from '../../game/feedback/feedbackDirector'
|
||||
import { EMPTY_GAME_PRESENTATION_STATE, type GamePresentationState } from '../../game/presentation/presentationState'
|
||||
import { buildResultSummarySnapshot, type ResultSummarySnapshot } from '../../game/result/resultSummary'
|
||||
import { TelemetryRuntime } from '../../game/telemetry/telemetryRuntime'
|
||||
import { getHeartRateToneSampleBpm, type HeartRateTone } from '../../game/telemetry/telemetryConfig'
|
||||
|
||||
@@ -257,6 +259,8 @@ export interface MapEngineGameInfoSnapshot {
|
||||
globalRows: MapEngineGameInfoRow[]
|
||||
}
|
||||
|
||||
export type MapEngineResultSnapshot = ResultSummarySnapshot
|
||||
|
||||
const VIEW_SYNC_KEYS: Array<keyof MapEngineViewState> = [
|
||||
'animationLevel',
|
||||
'buildVersion',
|
||||
@@ -868,6 +872,7 @@ export class MapEngine {
|
||||
configSchemaVersion: string
|
||||
configVersion: string
|
||||
controlScoreOverrides: Record<string, number>
|
||||
controlContentOverrides: Record<string, GameControlDisplayContentOverride>
|
||||
defaultControlScore: number | null
|
||||
gameRuntime: GameRuntime
|
||||
telemetryRuntime: TelemetryRuntime
|
||||
@@ -882,6 +887,8 @@ export class MapEngine {
|
||||
autoFinishOnLastControl: boolean
|
||||
punchFeedbackTimer: number
|
||||
contentCardTimer: number
|
||||
currentContentCardPriority: number
|
||||
shownContentCardKeys: Record<string, true>
|
||||
mapPulseTimer: number
|
||||
stageFxTimer: number
|
||||
sessionTimerInterval: number
|
||||
@@ -1076,8 +1083,8 @@ export class MapEngine {
|
||||
showPunchFeedback: (text, tone, motionClass) => {
|
||||
this.showPunchFeedback(text, tone, motionClass)
|
||||
},
|
||||
showContentCard: (title, body, motionClass) => {
|
||||
this.showContentCard(title, body, motionClass)
|
||||
showContentCard: (title, body, motionClass, options) => {
|
||||
this.showContentCard(title, body, motionClass, options)
|
||||
},
|
||||
setPunchButtonFxClass: (className) => {
|
||||
this.setPunchButtonFxClass(className)
|
||||
@@ -1118,6 +1125,7 @@ export class MapEngine {
|
||||
this.configSchemaVersion = '1'
|
||||
this.configVersion = ''
|
||||
this.controlScoreOverrides = {}
|
||||
this.controlContentOverrides = {}
|
||||
this.defaultControlScore = null
|
||||
this.gameRuntime = new GameRuntime()
|
||||
this.telemetryRuntime = new TelemetryRuntime()
|
||||
@@ -1134,6 +1142,8 @@ export class MapEngine {
|
||||
this.gpsLockEnabled = false
|
||||
this.punchFeedbackTimer = 0
|
||||
this.contentCardTimer = 0
|
||||
this.currentContentCardPriority = 0
|
||||
this.shownContentCardKeys = {}
|
||||
this.mapPulseTimer = 0
|
||||
this.stageFxTimer = 0
|
||||
this.sessionTimerInterval = 0
|
||||
@@ -1405,6 +1415,15 @@ export class MapEngine {
|
||||
}
|
||||
}
|
||||
|
||||
getResultSceneSnapshot(): MapEngineResultSnapshot {
|
||||
return buildResultSummarySnapshot(
|
||||
this.gameRuntime.definition,
|
||||
this.gameRuntime.state,
|
||||
this.telemetryRuntime.getPresentation(),
|
||||
this.state.mapName || (this.gameRuntime.definition ? this.gameRuntime.definition.title : '本局结果'),
|
||||
)
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
this.clearInertiaTimer()
|
||||
this.clearPreviewResetTimer()
|
||||
@@ -1586,6 +1605,7 @@ export class MapEngine {
|
||||
this.skipRadiusMeters,
|
||||
this.skipRequiresConfirm,
|
||||
this.controlScoreOverrides,
|
||||
this.controlContentOverrides,
|
||||
this.defaultControlScore,
|
||||
)
|
||||
const result = this.gameRuntime.loadDefinition(definition)
|
||||
@@ -1723,6 +1743,12 @@ export class MapEngine {
|
||||
panelProgressFxClass: '',
|
||||
panelDistanceFxClass: '',
|
||||
}, true)
|
||||
this.currentContentCardPriority = 0
|
||||
}
|
||||
|
||||
resetSessionContentExperienceState(): void {
|
||||
this.shownContentCardKeys = {}
|
||||
this.currentContentCardPriority = 0
|
||||
}
|
||||
|
||||
clearSessionTimerInterval(): void {
|
||||
@@ -1878,7 +1904,22 @@ export class MapEngine {
|
||||
}, 1400) as unknown as number
|
||||
}
|
||||
|
||||
showContentCard(title: string, body: string, motionClass = ''): void {
|
||||
showContentCard(title: string, body: string, motionClass = '', options?: { contentKey?: string; autoPopup?: boolean; once?: boolean; priority?: number }): void {
|
||||
const autoPopup = !options || options.autoPopup !== false
|
||||
const once = !!(options && options.once)
|
||||
const priority = options && typeof options.priority === 'number' ? options.priority : 0
|
||||
const contentKey = options && options.contentKey ? options.contentKey : ''
|
||||
|
||||
if (!autoPopup) {
|
||||
return
|
||||
}
|
||||
if (once && contentKey && this.shownContentCardKeys[contentKey]) {
|
||||
return
|
||||
}
|
||||
if (this.state.contentCardVisible && priority < this.currentContentCardPriority) {
|
||||
return
|
||||
}
|
||||
|
||||
this.clearContentCardTimer()
|
||||
this.setState({
|
||||
contentCardVisible: true,
|
||||
@@ -1886,8 +1927,13 @@ export class MapEngine {
|
||||
contentCardBody: body,
|
||||
contentCardFxClass: motionClass,
|
||||
}, true)
|
||||
this.currentContentCardPriority = priority
|
||||
if (once && contentKey) {
|
||||
this.shownContentCardKeys[contentKey] = true
|
||||
}
|
||||
this.contentCardTimer = setTimeout(() => {
|
||||
this.contentCardTimer = 0
|
||||
this.currentContentCardPriority = 0
|
||||
this.setState({
|
||||
contentCardVisible: false,
|
||||
contentCardFxClass: '',
|
||||
@@ -1897,6 +1943,7 @@ export class MapEngine {
|
||||
|
||||
closeContentCard(): void {
|
||||
this.clearContentCardTimer()
|
||||
this.currentContentCardPriority = 0
|
||||
this.setState({
|
||||
contentCardVisible: false,
|
||||
contentCardFxClass: '',
|
||||
@@ -1955,11 +2002,19 @@ export class MapEngine {
|
||||
}
|
||||
|
||||
if (this.gameRuntime.state.status !== 'idle') {
|
||||
return
|
||||
if (this.gameRuntime.state.status === 'finished' || this.gameRuntime.state.status === 'failed') {
|
||||
const reloadedResult = this.loadGameDefinitionFromCourse()
|
||||
if (!reloadedResult || !this.gameRuntime.state) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
this.feedbackDirector.reset()
|
||||
this.resetTransientGameUiState()
|
||||
this.resetSessionContentExperienceState()
|
||||
this.clearStartSessionResidue()
|
||||
|
||||
if (!this.locationController.listening) {
|
||||
@@ -1985,9 +2040,10 @@ export class MapEngine {
|
||||
}
|
||||
|
||||
this.courseOverlayVisible = true
|
||||
const gameModeText = this.gameMode === 'score-o' ? '积分赛' : '顺序打点'
|
||||
const defaultStatusText = this.currentGpsPoint
|
||||
? `顺序打点已开始 (${this.buildVersion})`
|
||||
: `顺序打点已开始,GPS定位启动中 (${this.buildVersion})`
|
||||
? `${gameModeText}已开始 (${this.buildVersion})`
|
||||
: `${gameModeText}已开始,GPS定位启动中 (${this.buildVersion})`
|
||||
this.commitGameResult(gameResult, defaultStatusText)
|
||||
}
|
||||
|
||||
@@ -2000,6 +2056,7 @@ export class MapEngine {
|
||||
if (!this.courseData) {
|
||||
this.clearGameRuntime()
|
||||
this.resetTransientGameUiState()
|
||||
this.resetSessionContentExperienceState()
|
||||
this.feedbackDirector.handleEffects([{ type: 'session_cancelled' }])
|
||||
this.setState({
|
||||
gpsTracking: false,
|
||||
@@ -2012,6 +2069,7 @@ export class MapEngine {
|
||||
|
||||
this.loadGameDefinitionFromCourse()
|
||||
this.resetTransientGameUiState()
|
||||
this.resetSessionContentExperienceState()
|
||||
this.feedbackDirector.handleEffects([{ type: 'session_cancelled' }])
|
||||
this.setState({
|
||||
gpsTracking: false,
|
||||
@@ -2384,6 +2442,7 @@ export class MapEngine {
|
||||
this.configSchemaVersion = config.configSchemaVersion
|
||||
this.configVersion = config.configVersion
|
||||
this.controlScoreOverrides = config.controlScoreOverrides
|
||||
this.controlContentOverrides = config.controlContentOverrides
|
||||
this.defaultControlScore = config.defaultControlScore
|
||||
this.gameMode = config.gameMode
|
||||
this.punchPolicy = config.punchPolicy
|
||||
|
||||
Reference in New Issue
Block a user