-
-
Notifications
You must be signed in to change notification settings - Fork 346
Feat/continue game #961
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Feat/continue game #961
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,3 +1,4 @@ | ||||||||||||||||||||||||
| import { useEffect, useMemo, useState } from 'react'; | ||||||||||||||||||||||||
| import { useDispatch, useSelector } from 'react-redux'; | ||||||||||||||||||||||||
| import { RootState } from '@/store/store'; | ||||||||||||||||||||||||
| import { fullScreenOption } from '@/store/userDataInterface'; | ||||||||||||||||||||||||
|
|
@@ -9,13 +10,17 @@ import useApplyStyle from '@/hooks/useApplyStyle'; | |||||||||||||||||||||||
| import { keyboard } from '@/hooks/useHotkey'; | ||||||||||||||||||||||||
| import useConfigData from '@/hooks/useConfigData'; | ||||||||||||||||||||||||
| import { playBgm } from '@/Core/controller/stage/playBgm'; | ||||||||||||||||||||||||
| import { continueGame, startGame } from '@/Core/controller/gamePlay/startContinueGame'; | ||||||||||||||||||||||||
| import { startGame } from '@/Core/controller/gamePlay/startContinueGame'; | ||||||||||||||||||||||||
| import { loadGameFromStageData } from '@/Core/controller/storage/loadGame'; | ||||||||||||||||||||||||
| import { getLatestSaveData } from '@/Core/controller/storage/savesController'; | ||||||||||||||||||||||||
| import { showGlogalDialog } from '../GlobalDialog/GlobalDialog'; | ||||||||||||||||||||||||
| import styles from './title.module.scss'; | ||||||||||||||||||||||||
| import { loadFastSaveGame, removeFastSaveGameRecord } from '@/Core/controller/storage/fastSaveLoad'; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /** 标题页 */ | ||||||||||||||||||||||||
| export default function Title() { | ||||||||||||||||||||||||
| const userDataState = useSelector((state: RootState) => state.userData); | ||||||||||||||||||||||||
| const userSaveData = useSelector((state: RootState) => state.saveData); | ||||||||||||||||||||||||
| const GUIState = useSelector((state: RootState) => state.GUI); | ||||||||||||||||||||||||
| const dispatch = useDispatch(); | ||||||||||||||||||||||||
| const fullScreen = userDataState.optionData.fullScreen; | ||||||||||||||||||||||||
|
|
@@ -24,6 +29,11 @@ export default function Title() { | |||||||||||||||||||||||
| const t = useTrans('title.'); | ||||||||||||||||||||||||
| const tCommon = useTrans('common.'); | ||||||||||||||||||||||||
| const { playSeEnter, playSeClick } = useSoundEffect(); | ||||||||||||||||||||||||
| const saveData = userSaveData.saveData; | ||||||||||||||||||||||||
| const fastSaveData = userSaveData.quickSaveData; | ||||||||||||||||||||||||
| const enableContinue = userDataState.globalGameVar.Enable_Continue !== false; | ||||||||||||||||||||||||
| const latestSave = useMemo(() => getLatestSaveData(saveData), [saveData]); | ||||||||||||||||||||||||
| const [fastSaveLoaded, setFastSaveLoaded] = useState(false); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| const applyStyle = useApplyStyle('title'); | ||||||||||||||||||||||||
| useConfigData(); // 监听基础ConfigData变化 | ||||||||||||||||||||||||
|
|
@@ -38,6 +48,24 @@ export default function Title() { | |||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| useEffect(() => { | ||||||||||||||||||||||||
| if (!fastSaveLoaded && (!GUIState.isShowLogo || GUIState.logoImage.length === 0) && GUIState.showTitle && fastSaveData) { | ||||||||||||||||||||||||
| showGlogalDialog({ | ||||||||||||||||||||||||
| title: t('fastSaveLoadConfirm'), | ||||||||||||||||||||||||
| leftText: tCommon('yes'), | ||||||||||||||||||||||||
| rightText: tCommon('no'), | ||||||||||||||||||||||||
| leftFunc: () => { | ||||||||||||||||||||||||
| loadFastSaveGame(); | ||||||||||||||||||||||||
| setFastSaveLoaded(true); | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
|
Comment on lines
+57
to
+60
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||||||||
| rightFunc: () => { | ||||||||||||||||||||||||
| removeFastSaveGameRecord(); | ||||||||||||||||||||||||
| setFastSaveLoaded(true); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| }, [GUIState.isShowLogo, GUIState.logoImage, GUIState.showTitle, fastSaveData, fastSaveLoaded]); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||
| <> | ||||||||||||||||||||||||
| {GUIState.showTitle && <div className={applyStyle('Title_backup_background', styles.Title_backup_background)} />} | ||||||||||||||||||||||||
|
|
@@ -72,17 +100,21 @@ export default function Title() { | |||||||||||||||||||||||
| > | ||||||||||||||||||||||||
| {renderButtonText(t('start.title'))} | ||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| <div | ||||||||||||||||||||||||
| className={applyStyle('Title_button', styles.Title_button)} | ||||||||||||||||||||||||
| onClick={async () => { | ||||||||||||||||||||||||
| playSeClick(); | ||||||||||||||||||||||||
| dispatch(setVisibility({ component: 'showTitle', visibility: false })); | ||||||||||||||||||||||||
| continueGame(); | ||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||
| onMouseEnter={playSeEnter} | ||||||||||||||||||||||||
| > | ||||||||||||||||||||||||
| {renderButtonText(t('continue.title'))} | ||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| {enableContinue && ( | ||||||||||||||||||||||||
| <div | ||||||||||||||||||||||||
| className={`${applyStyle('Title_button', styles.Title_button)} ${ | ||||||||||||||||||||||||
| !latestSave ? applyStyle('Title_button_disabled', styles.Title_button_disabled) : '' | ||||||||||||||||||||||||
| }`} | ||||||||||||||||||||||||
| onClick={() => { | ||||||||||||||||||||||||
| if (!latestSave) return; | ||||||||||||||||||||||||
| playSeClick(); | ||||||||||||||||||||||||
| loadGameFromStageData(latestSave); | ||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||
|
Comment on lines
+108
to
+112
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. “继续游戏”按钮逻辑中缺少了隐藏标题界面的 dispatch 调用。这会导致在加载存档数据后,标题界面仍然显示在最上层,用户无法看到游戏画面。建议添加
Suggested change
|
||||||||||||||||||||||||
| onMouseEnter={latestSave ? playSeEnter : undefined} | ||||||||||||||||||||||||
| > | ||||||||||||||||||||||||
| {renderButtonText(t('continue.title'))} | ||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||
| <div | ||||||||||||||||||||||||
| className={applyStyle('Title_button', styles.Title_button)} | ||||||||||||||||||||||||
| onClick={() => { | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| import { getFastSaveFromStorage, getSavesFromStorage } from '@/Core/controller/storage/savesController'; | ||
| import { getFastSaveFromStorage, getSavesFromStorage, MAX_SAVE_SIZE } from '@/Core/controller/storage/savesController'; | ||
| import { getStorage } from '@/Core/controller/storage/storageController'; | ||
| import { setEbg } from '@/Core/gameScripts/changeBg/setEbg'; | ||
| import { assetSetter, fileType } from '@/Core/util/gameAssetsAccess/assetSetter'; | ||
|
|
@@ -49,7 +49,7 @@ const useConfigData = () => { | |
| WebGAL.gameKey = val; | ||
| getStorage(); | ||
| getFastSaveFromStorage(); | ||
| getSavesFromStorage(0, 0); | ||
| getSavesFromStorage(0, MAX_SAVE_SIZE); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| break; | ||
| } | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里存在一个差一错误 (off-by-one error)。如果
MAX_SAVE_SIZE为 200,且getSavesFromStorage内部使用i <= endIndex进行循环,则会处理 201 个存档位(0 到 200)。建议将结束索引改为MAX_SAVE_SIZE - 1。