feat: add puzzle residence configuration and reflection progress logic

- Introduced `puzzleResidences.ts` to define puzzle residence configurations including properties like display name, position, and puzzle availability.
- Added `reflectionProgress.ts` to manage badge unlocking logic based on place completion, including functions to determine unlocked badges and video sources for scenes.
This commit is contained in:
zhongyidian committed 2026-04-27 11:49:30 +08:00
1 parent e0fa47d21a
commit f5f36f75b5
153 files changed
+3846 -2352

No files matched your search

+43 -52
View File
@@ -15,11 +15,15 @@ import { getBackgroundImage, getPublicPath, getStaticImage } from '@/lib/utils'
import { useEffect, useMemo, useRef, useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { useNieerStore, saveNieerStore } from '@/store/nieerStore'
import { usePuzzleAnimation } from '@/contexts/PuzzleAnimationContext'
const NieerPlace5 = () => {
const navigate = useNavigate()
const { moduleName } = useParams<{ moduleName: string }>()
// 获取碎片动画触发方法
const { triggerPuzzleAnimation } = usePuzzleAnimation()
const starName = 'nieer'
const place = 'place5'
const { markExhibitVisited, getVisitedExhibits } = useNieerStore()
@@ -66,10 +70,10 @@ const NieerPlace5 = () => {
const subtitle = completed ? '已完成' : `${progressCount}/${total}`
const { isEnabled } = useCursorController({
initialEnabled: [1],
initialEnabled: [2],
dependencies: {
2: [1],
3: [2],
1: [2],
3: [1],
},
visited: visitedExhibits,
})
@@ -85,8 +89,8 @@ const NieerPlace5 = () => {
const exhibitSrcMap: Record<1 | 2 | 3, string> = {
1: 'nieer/place5/场景5展品1',
2: 'nieer/place5/场景5展品2',
3: 'nieer/place5/场景5展品3',
2: 'nieer/place5/场景5展品3',
3: 'nieer/place5/场景5展品2',
}
const handleOpenExhibit = (id: 1 | 2 | 3) => {
@@ -163,6 +167,17 @@ const NieerPlace5 = () => {
<ExhibitOverlay
visible={activeExhibitId !== null}
src={activeExhibitId ? exhibitSrcMap[activeExhibitId] : ''}
onOpen={() => {
if (activeExhibitId === 1) {
triggerPuzzleAnimation(10)
}
if (activeExhibitId === 2) {
triggerPuzzleAnimation(11)
}
if (activeExhibitId === 3) {
triggerPuzzleAnimation(12)
}
}}
onClose={() => {
const closingId = activeExhibitId
setActiveExhibitId(null)
@@ -170,10 +185,16 @@ const NieerPlace5 = () => {
setGuide2Visible(false)
setGuide3Visible(false)
// 光标1:只需要对话,关窗即完成
if (closingId == 2) {
markExhibitVisited(place, 2)
}
// 展品1关闭后完成光标1,并触发光标2的两道题
if (closingId === 1) {
markExhibitVisited(place, 1)
saveNieerStore()
setQuiz2_1Visible(true)
}
if (closingId === 3) {
setQuiz3_1Visible(true)
}
}}
/>
@@ -188,57 +209,34 @@ const NieerPlace5 = () => {
highlightSelectors={[]}
zIndex={10001}
>
<GuideStepsItem
speaker="student"
audioSrc={getPublicPath('audio/nieer/mp3_nieer_place5_01.mp3')}
>
<GuideStepsItem speaker="student" audioSrc={getPublicPath('audio/nieer/mp3_nieer_22.mp3')}>
那2004年的宪法修正案又对国歌做了什么重要规定呢?为什么要把它写入宪法呀?
</GuideStepsItem>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/nieer/mp3_nieer_place5_02.mp3')}
>
<GuideStepsItem speaker="guide" audioSrc={getPublicPath('audio/nieer/mp3_nieer_23.mp3')}>
2004年3月14日,第十届全国人民代表大会二次会议通过宪法修正案,明确规定“中华人民共和国国歌是《义勇军进行曲》”,这让国歌的地位有了根本大法的保障。
</GuideStepsItem>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/nieer/mp3_nieer_place5_03.mp3')}
>
<GuideStepsItem speaker="guide">
把它写入宪法,是因为这首歌不仅记录了民族救亡的历史,更凝聚了中华民族的精神气节。从抗战时期的冲锋号到新时代的强国音,它早已成为国家尊严的象征,写入宪法能更好地培育全民的爱国意识和国家观念。
</GuideStepsItem>
</GuideSteps>
{/* 光标2对话(图2) - 对话结束后依次出现两道题 */}
{/* 光标2对话(图2) */}
<GuideSteps
visible={guide2Visible}
currentStep={guide2Step}
onStepChange={setGuide2Step}
onVisibleChange={(nextVisible) => {
setGuide2Visible(nextVisible)
if (!nextVisible) {
setQuiz2_1Visible(true)
}
}}
onVisibleChange={setGuide2Visible}
showMask={false}
highlightSelectors={[]}
zIndex={10001}
>
<GuideStepsItem
speaker="student"
audioSrc={getPublicPath('audio/nieer/mp3_nieer_place5_03.mp3')}
>
<GuideStepsItem speaker="student" audioSrc={getPublicPath('audio/nieer/mp3_nieer_20.mp3')}>
小沪,从抗日战歌到正式被确立为国歌,中间经历了多久呀?《义勇军进行曲》第一次作为国歌奏响是在什么时候呢?
</GuideStepsItem>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/nieer/mp3_nieer_place5_04.mp3')}
>
<GuideStepsItem speaker="guide" audioSrc={getPublicPath('audio/nieer/mp3_nieer_21.mp3')}>
时间跨度还真不短呢!1949年9月27日,中国人民政治协商会议第一届全体会议决定,在国歌未正式制定前,以《义勇军进行曲》作为代国歌。
</GuideStepsItem>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/nieer/mp3_nieer_place5_05.mp3')}
>
<GuideStepsItem speaker="guide">
同年10月1日开国大典上,它第一次在天安门广场作为国歌庄严奏响,见证了新中国的诞生。直到1982年12月4日,第五届全国人民代表大会第五次会议才正式将它定为中华人民共和国国歌,完成了从代国歌到正式国歌的跨越。
</GuideStepsItem>
</GuideSteps>
@@ -319,35 +317,27 @@ const NieerPlace5 = () => {
visible={success2_2Visible}
onContinue={() => {
setSuccess2_2Visible(false)
markExhibitVisited(place, 2)
markExhibitVisited(place, 1)
saveNieerStore()
}}
onClose={() => {
setSuccess2_2Visible(false)
markExhibitVisited(place, 2)
markExhibitVisited(place, 1)
saveNieerStore()
}}
/>
{/* 光标3对话(图5) - 对话结束后依次出现两道题 */}
{/* 光标3对话(图5) - 关闭展品3后依次出现两道题 */}
<GuideSteps
visible={guide3Visible}
currentStep={guide3Step}
onStepChange={setGuide3Step}
onVisibleChange={(nextVisible) => {
setGuide3Visible(nextVisible)
if (!nextVisible) {
setQuiz3_1Visible(true)
}
}}
onVisibleChange={setGuide3Visible}
showMask={false}
highlightSelectors={[]}
zIndex={10001}
>
<GuideStepsItem
speaker="guide"
audioSrc={getPublicPath('audio/nieer/mp3_nieer_place5_05.mp3')}
>
<GuideStepsItem speaker="guide" audioSrc={getPublicPath('audio/nieer/mp3_nieer_24.mp3')}>
根据宪法,2017年9月1日第十二届全国人民代表大会常务委员会第二十九次会议通过《中华人民共和国国歌法》,通过国家立法对国歌的奏唱场合、奏唱礼仪和宣传教育进行规范。
</GuideStepsItem>
</GuideSteps>
@@ -356,7 +346,7 @@ const NieerPlace5 = () => {
<MatchQuizPanel
visible={quiz3_1Visible}
zIndex={10001}
title="【配对】请将左侧《义勇军进行曲》的关键事件与右侧时间进行匹配"
title="【连线】请将左侧《义勇军进行曲》的关键事件与右侧时间进行匹配"
leftItems={[
{
id: 'e1982',
@@ -454,6 +444,7 @@ const NieerPlace5 = () => {
/>
<SuccessAlert
title="恭喜你,判断正确!"
visible={success3_2Visible}
onContinue={() => {
setSuccess3_2Visible(false)