在MFC中制作Breakout游戏时,我选择序列化CBlock对象,以便播放器可以在我制作的关卡编辑器上制作自己的“地图”,保存时一切都很好。因为我将所有CBlock对象都放在for
上,所以我要做的就是用vector<CBlock*>
序列化所有CBlock对象。读取文件时出现问题。主要问题是文件结束时我的程序不知道如何停止读取。我已经尝试了bool
中的大多数CArchive
方法。唯一有效的方法是CArchive::IsLoading()
,但问题是尽管到达了文件末尾,它仍然继续从文件读取。
CString m_filter = TEXT("Super Breakout Maker Files (*.sbm)|*.sbm|All Files (*.*)|*.*||");
CFile m_loadFile;
CFileDialog m_fileDlg(TRUE, TEXT(".sbm"), TEXT("mylayout"), OFN_HIDEREADONLY, m_filter, NULL, 0, TRUE);
//CFileDialog m_fileDlg(FALSE, TEXT(".sbm"), TEXT("mylayout"), 0, m_filter);
if (m_fileDlg.DoModal() == IDOK)
{
if (m_blockLayout.size() > 0)
{
for (int i = 0; i < m_blockLayout.size(); i++)
{
delete(m_blockLayout[i]);
}
m_blockLayout.clear();
}
m_loadFile.Open(m_fileDlg.GetFileName(), CFile::modeRead);
CArchive m_loadArchive(&m_loadFile, CArchive::load);
while (m_loadArchive.IsLoading()==true)
{
CBlock* block = new CBlock;
block->Serialize(m_loadArchive);
block->AssignBlockType();
block->m_blockState.CreateCompatibleDC(pDC);
LoadBlock(block->m_blockState, m_blockStateArray, block->GetBlockType(), block->GetHits());
m_blockLayout.push_back(block);
}
m_loadArchive.Close();
if (m_blockLayout.size() > 0)
{
MessageBox(TEXT("Your layout was successfully loaded! Resume game to play."), TEXT("Notification"), MB_ICONINFORMATION);
m_pBall->SetInitialPosition(m_ballBMP, m_pBar, m_barBMP);
}
else
{
MessageBox(TEXT("Unable to read file. Corrupted or incompatible data."), TEXT("Notification"), MB_ICONERROR);
}
}
else
{
return;
}
m_loadFile.Close();
这是我的加载方法,但是正如我提到的,迭代不知道从何处结束读取。
答案 0 :(得分:1)
最简单的选项结合在一起,最简单的方法是将文件中存储多少个块作为存储块之前的文件中的第一件事。阅读那么多块,然后退出。
具有一个带有特定属性和成员变量的预定义块,它是您的“文件末尾”块,每当您读取该特定块时,便知道将其丢弃并停止读取。
另一种选择是在所有块数据的末尾仅包含一些特定的字符串,并在读取每个块之后检查该特定字符串的下一行(不过,这需要在文件中为该行添加一些指针变量)