游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2199|回复: 6

昨天的问题刚解决,又有新的问题了。还望大哥们赐教。

[复制链接]

3

主题

13

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2006-5-9 11:25:00 | 显示全部楼层 |阅读模式
现在我可以把地图数据存入文件了。
这是我定义的地图结构
Type M
x1 As Integer
y1 As Integer
End Type

Public map() As M

比如现在的地图数据为:
map(0,0).x1=0
map(0,0).y1=0
map(0,1).x1=0
map(0,1).y1=1
map(0,2).X1=1
map(0,2).y1=0
map(1,0).X1=1
map(1,0).y1=1
map(1,1).x1=0
map(1,1).y1=1

也就是说现在的地图是二行三列(当然实际情况要比这大)。
用:
Open App.Path + filename For Binary As #1
Put #1, , map
Close #1

这样就把这个二行三列的数组存入filename文件了。

现在问题就来了,当打开地图时
Open App.Path + filename For Binary As #1
get #1, , map
Close #1
我怎么知道这个map数组有多少维数,每维最大数又是多少呢?
因为只有知道这些内容才能通过循环来画地图。

希望各位大哥们赐教,谢谢。

3

主题

13

帖子

13

积分

新手上路

Rank: 1

积分
13
 楼主| 发表于 2006-5-9 15:46:00 | 显示全部楼层

Re: 昨天的问题刚解决,又有新的问题了。还望大哥们赐教

实际就是读二进制文件的问题。
在网上翻了很多相关内容,但还是不得要领,希望大侠们帮小弟一把。

10

主题

62

帖子

68

积分

注册会员

Rank: 2

积分
68
发表于 2006-5-9 20:25:00 | 显示全部楼层

Re: 昨天的问题刚解决,又有新的问题了。还望大哥们赐教

我怎么知道这个map数组有多少维数,每维最大数又是多少呢?


A.自己用结构体定义一个文件头,存储相关信息
B.用Lof函数返回文件大小。文件大小除以结构体大小就是项目个数

7

主题

229

帖子

247

积分

中级会员

Rank: 3Rank: 3

积分
247
QQ
发表于 2006-5-10 00:49:00 | 显示全部楼层

Re:昨天的问题刚解决,又有新的问题了。还望大哥们赐教。

我补充一下。除了用楼上的那种定义一个文件头,用来存储该地图信息的描述的方法之外,还有一种最简单的方法,那就是二进制存储方式。一般C/C++程序员绝大多数都是用这种办法来存储应用程序中的结构等复杂类型!

下面那段代码是引用我之前编写的BFRussia。你可参考参考SDK是怎么做这个的,用VB实现可能会有点难度。不过可用尝试用RtlCopyMemory等内存操作函数来处理。。。

////////////////////////////////////////////////////////////////////////////////////////////////
// 加载存档文件
void LoadGameFile()
{
    HANDLE hFile;
    DWORD dwBytesRead;
    DWORD dwFileSize;
       
    OPENFILENAME ofn;
    //OVERLAPPED *Overlap;

    // 构造文件名
    TCHAR szInitialDir[MAX_PATH] = TEXT("\0");
    TCHAR szFileName[MAX_PATH] = TEXT("\0");
    TCHAR szFilter[MAX_PATH] = TEXT("\0");
   
    // 内存指针
    PBYTE pFileBuffer=NULL, p=NULL;
   
    wsprintf(szInitialDir, TEXT("%ssave"), g_szAppPath);

    GetFirstFileName(szFileName, szInitialDir, TEXT("*.bfrs"));
   
    wsprintf(szFilter, TEXT("BFRussia Save File(*.bfrs)\0*.bfrs\0\0"));
   
    // 填充打开文件结构
    ofn.lStructSize         = sizeof(OPENFILENAME);
    ofn.hwndOwner      = g_hwndMain;
    ofn.hInstance          = g_hInstance;
    ofn.lpstrFilter           = szFilter;
    ofn.lpstrCustomFilter = NULL;
    ofn.nMaxCustFilter    = 0;
    ofn.nFilterIndex       = 0;
    ofn.lpstrFile             = szFileName;
    ofn.nMaxFile            = sizeof(szFileName);
    ofn.lpstrFileTitle       = NULL;
    ofn.nMaxFileTitle     = 0;
    ofn.lpstrInitialDir      = szInitialDir;
    ofn.lpstrTitle           = TEXT("打开游戏存档");
    ofn.nMaxFileTitle     = strlen(ofn.lpstrTitle) + 1;
    ofn.nFileOffset       = 0;
    ofn.nFileExtension   = 0;
    ofn.lpstrDefExt       = NULL;
    ofn.lCustData         = NULL;
    ofn.lpfnHook         = NULL;
    ofn.lpTemplateName = NULL;
    ofn.Flags              = OFN_EXPLORER | OFN_LONGNAMES | OFN_CREATEPROMPT |
                                OFN_NODEREFERENCELINKS | OFN_ALLOWMULTISELECT;

    // 如果得到一个存档的文件名,就开始读取数据
    if ( GetOpenFileName(&ofn) )
    {
        hFile = CreateFile( szFileName,
                            GENERIC_READ,
                            0,
                            NULL,
                            OPEN_EXISTING,
                            FILE_FLAG_SEQUENTIAL_SCAN,
                            0
                          );
                  
        if ( hFile == INVALID_HANDLE_VALUE )
            return;
        
        dwFileSize = GetFileSize(hFile, NULL);
        
        // 检查存档文件
        if ( dwFileSize == 0xFFFFFFFF || dwFileSize != GetBufferSize() )
        {
            CloseHandle(hFile);
            MessageBox(g_hwndMain, TEXT("无效的存档文件!"), g_szAppTitle, MB_ICONWARNING );
            return;
        }
        
        pFileBuffer = (PBYTE) GlobalAlloc(GPTR, dwFileSize);
        
        // 读到数据到内存中
        if ( ReadFile(hFile, pFileBuffer, dwFileSize, &dwBytesRead, NULL) )
        {
            COLORREF clrPrevText = GetTextColor(g_pwdRussia->hdc);
            LPTSTR pText = TEXT("成功加载!");
            BYTE bColor = 0;
            BOOL bEnable;
            
            DWORD dwTimer = 0;
            DWORD dwInterval;
            UINT uMenuItemDisabled = MF_DISABLED | MF_GRAYED;
            
            UINT gs;
            int i;
            
            // 恢复Russia的前景颜色和字体
            if ( g_ptdGameOver->hfontBak )
            {
                SetTextColor(g_pwdRussia->hdc, g_ptdGameOver->clrBak);
                SelectObject(g_pwdRussia->hdc, g_ptdGameOver->hfontBak);
                g_ptdGameOver->hfontBak = NULL;
            }
            
            p = pFileBuffer;
            
            // 暂停当前状态
            if ( g_fGameState > GS_PAUSEING )
                g_fGameState = GS_PAUSEING;
            
            // GAME_STATE
            memcpy((void*)&gs, (void*)p, sizeof(UINT) );
            p += sizeof(UINT);
         
            // GAME_LOOP_INTERVAL
            memcpy(&GAME_LOOP_INTERVAL, (void*)p, sizeof(UINT) );
            p += sizeof(UINT);
            
            // MAX_SHAPE
            memcpy((void*)&MAX_SHAPE, (void*)p, sizeof(UINT) );
            p += sizeof(UINT);
            
            // g_aGameArea
            memcpy((void*)&g_aGameArea, (void*)p, sizeof(g_aGameArea) );
            p += sizeof(g_aGameArea);
            
            // g_Player
            memcpy((void*)&g_Player, (void*)p, sizeof(PLAYER) );
            p += sizeof(PLAYER);
            
            // g_KeyState
            memcpy((void*)&g_KeyState, (void*)p, sizeof(VKSTATE) );
            p += sizeof(VKSTATE);
            
            // g_uIDTimerGameAreaAct
            memcpy((void*)&g_uIDTimerGameAreaAct, (void*)p, sizeof(UINT) );
            p += sizeof(UINT);
            
            // Start
            memcpy((void*)&bEnable, (void*)p, sizeof(BOOL) );
            p += sizeof(BOOL);
            EnableWindow(GetDlgItem(g_hwndMain, IDC_BTNSTART), bEnable);
            EnableMenuItem(g_hmenuMain, IDM_FILE_NEW, MF_BYCOMMAND | (bEnable?MF_ENABLED:uMenuItemDisabled) );
            
            // Pause
            memcpy((void*)&bEnable, (void*)p, sizeof(bEnable) );
            p += sizeof(BOOL);
            if ( gs == GS_PAUSEING )
                SetPauseState(bEnable, TEXT("暂  停"), TEXT("暂停(&amp)"));
            else
                SetPauseState(bEnable, TEXT("返  回"), TEXT("返回游戏(&R)"));
            
            // Stop        
            memcpy((void*)&bEnable, (void*)p, sizeof(BOOL) );
            p += sizeof(BOOL);
            EnableWindow(GetDlgItem(g_hwndMain, IDC_BTNSTOP), bEnable);
            EnableMenuItem(g_hmenuMain, IDM_FILE_STOP, MF_BYCOMMAND | (bEnable?MF_ENABLED:uMenuItemDisabled) );
            
            // Close
            memcpy((void*)&bEnable, (void*)p, sizeof(BOOL) );
            p += sizeof(BOOL);
            EnableWindow(GetDlgItem(g_hwndMain, IDC_BTNCLOSE), bEnable);
            EnableMenuItem(g_hmenuMain, IDM_FILE_EXIT, MF_BYCOMMAND | (bEnable?MF_ENABLED:uMenuItemDisabled) );

            // Speed
            memcpy((void*)&g_dwSpeed, (void*)p, sizeof(DWORD) );
            p += sizeof(DWORD);
            
            // Level
            memcpy((void*)&g_dwLevel, (void*)p, sizeof(DWORD) );
            p += sizeof(DWORD);
            
            // Player Name
            memcpy((void*)&g_aTopList[10], (void*)p, sizeof(TOP_LIST) );
            p += sizeof(TOP_LIST);
            
            // 游戏者名称
            if ( !strlen(g_aTopList[10].szName) )
                strcpy(g_aTopList[10].szName, TEXT("<无名>"));
            
            g_aTopList[10].bFromSavedFile = TRUE;
            GetLocalTime(&g_aTopList[10].stRuntime);
            
            // 修改主程式窗口标题
            {
                TCHAR szTitle[MAX_PATH] = TEXT("\0");
                wsprintf(szTitle, TEXT("%s - %s"), g_szAppTitle, g_aTopList[10].szName);
                SetWindowText( g_hwndMain, szTitle);
            }
            
            // 播放打开成功消息
            dwInterval = GetTickCount() + 1020;

            // 成功
            while ( dwTimer < dwInterval )
            {
                bColor = dwInterval - dwTimer;
                SetTextColor( g_pwdRussia->hdc, RGB(0xFF, bColor, bColor) );
                TextOut(g_pwdRussia->hdc, 0, 0, pText, strlen(pText) );
                Flip();
                dwTimer = GetTickCount();
            }
            SetTextColor( g_pwdRussia->hdc, clrPrevText );

            DrawGameArea();
            DrawPreview();
            DrawToolsArea();
            SetGameProperties( SGP_ALL );
            SetDlgItemInt( g_hwndMain, IDC_SCORE, g_pPlayer->dwScore, FALSE );

            EnableWindow( GetDlgItem(g_hwndMain, IDC_SPINLEVEL), FALSE );
            EnableWindow( GetDlgItem(g_hwndMain, IDC_SPINSPEED), FALSE );

            // 刷新数据
            if ( gs != GS_PAUSEING )
                g_fGameState = gs;
            else
            {
                ResumeGame();
            }
        }
        
        GlobalFree(pFileBuffer);
        CloseHandle(hFile);
    }

}

1

主题

86

帖子

86

积分

注册会员

Rank: 2

积分
86
发表于 2006-5-10 08:39:00 | 显示全部楼层

Re:昨天的问题刚解决,又有新的问题了。还望大哥们赐教。

2进制处理果然很快。不过是不是复杂点啊。

7

主题

229

帖子

247

积分

中级会员

Rank: 3Rank: 3

积分
247
QQ
发表于 2006-5-10 10:14:00 | 显示全部楼层

Re:昨天的问题刚解决,又有新的问题了。还望大哥们赐教。

不???碗s,不?你必?要定?每?????拇笮『晚?序。主要文件操作代?如下:

        hFile = CreateFile( szFileName,
                            GENERIC_READ,
                            0,
                            NULL,
                            OPEN_EXISTING,
                            FILE_FLAG_SEQUENTIAL_SCAN,
                            0
                          );
                  
        if ( hFile == INVALID_HANDLE_value )
            return;
        
        dwFileSize = GetFileSize(hFile, NULL);
        
        // 检查存档文件
        if ( dwFileSize == 0xFFFFFFFF || dwFileSize != GetBufferSize() )
        {
            CloseHandle(hFile);
            MessageBox(g_hwndMain, TEXT("无效的存档文件!"), g_szAppTitle, MB_ICONWARNING );
            return;
        }
        
        pFileBuffer = (PBYTE) GlobalAlloc(GPTR, dwFileSize);
        
        // 读到数据到内存中
        if ( ReadFile(hFile, pFileBuffer, dwFileSize, &dwBytesRead, NULL) )
        {
            p = pFileBuffer;
            
            // GAME_STATE
            memcpy((void*)&gs, (void*)p, sizeof(UINT) );
            p += sizeof(UINT);
         
            // GAME_LOOP_INTERVAL
            memcpy(&GAME_LOOP_INTERVAL, (void*)p, sizeof(UINT) );
            p += sizeof(UINT);
            
            // MAX_SHAPE
            memcpy((void*)&MAX_SHAPE, (void*)p, sizeof(UINT) );
            p += sizeof(UINT);
            
            // g_aGameArea
            memcpy((void*)&g_aGameArea, (void*)p, sizeof(g_aGameArea) );
            p += sizeof(g_aGameArea);
            
            // g_Player
            memcpy((void*)&g_Player, (void*)p, sizeof(PLAYER) );
            p += sizeof(PLAYER);
            
            // g_KeyState
            memcpy((void*)&g_KeyState, (void*)p, sizeof(VKSTATE) );
            p += sizeof(VKSTATE);
            
            // g_uIDTimerGameAreaAct
            memcpy((void*)&g_uIDTimerGameAreaAct, (void*)p, sizeof(UINT) );
            p += sizeof(UINT);
            
            // Start
            memcpy((void*)&bEnable, (void*)p, sizeof(BOOL) );
            p += sizeof(BOOL);
            EnableWindow(GetDlgItem(g_hwndMain, IDC_BTNSTART), bEnable);
            EnableMenuItem(g_hmenuMain, IDM_FILE_NEW, MF_BYCOMMAND | (bEnable?MF_ENABLED:uMenuItemDisabled) );
            
            // Pause
            memcpy((void*)&bEnable, (void*)p, sizeof(bEnable) );
            p += sizeof(BOOL);
            if ( gs == GS_PAUSEING )
                SetPauseState(bEnable, TEXT("暂  停"), TEXT("暂停(&amp)"));
            else
                SetPauseState(bEnable, TEXT("返  回"), TEXT("返回游戏(&R)"));
            
            // Stop        
            memcpy((void*)&bEnable, (void*)p, sizeof(BOOL) );
            p += sizeof(BOOL);
            EnableWindow(GetDlgItem(g_hwndMain, IDC_BTNSTOP), bEnable);
            EnableMenuItem(g_hmenuMain, IDM_FILE_STOP, MF_BYCOMMAND | (bEnable?MF_ENABLED:uMenuItemDisabled) );
            
            // Close
            memcpy((void*)&bEnable, (void*)p, sizeof(BOOL) );
            p += sizeof(BOOL);
            EnableWindow(GetDlgItem(g_hwndMain, IDC_BTNCLOSE), bEnable);
            EnableMenuItem(g_hmenuMain, IDM_FILE_EXIT, MF_BYCOMMAND | (bEnable?MF_ENABLED:uMenuItemDisabled) );

            // Speed
            memcpy((void*)&g_dwSpeed, (void*)p, sizeof(DWORD) );
            p += sizeof(DWORD);
            
            // Level
            memcpy((void*)&g_dwLevel, (void*)p, sizeof(DWORD) );
            p += sizeof(DWORD);
            
            // Player Name
            memcpy((void*)&g_aTopList[10], (void*)p, sizeof(TOP_LIST) );
            p += sizeof(TOP_LIST);
            
                        // to do refreah etc...
        }
        
        GlobalFree(pFileBuffer);
        CloseHandle(hFile);

最好把上面的代?拷到VS2003 下的VC++或是C#的代??看

3

主题

13

帖子

13

积分

新手上路

Rank: 1

积分
13
 楼主| 发表于 2006-5-11 09:53:00 | 显示全部楼层

Re:昨天的问题刚解决,又有新的问题了。还望大哥们赐教。

VC还是太难了,我慢慢试着用VB看能不能解了。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-24 11:34

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表