MC新手入门(四十九)------ 文件操作

来源:互联网 发布:python项目开发实例 编辑:程序博客网 时间:2024/06/11 02:42
文件操作
      就像看书一样,我们并不会总是一次性把游戏玩通关,往往需要做个记号,下次再继续。在单机游戏里,通常的记录方法就是做一个存档文件,把游戏里跟进度有关的参数存下来,然后下次读取存档的时候根据这些参数来还原上一次退出时的进度。在保存和读取存档的时候,就要用到文件操作的方法来实现。
相信大家都接触过不少单机RPG游戏吧,那么我们就以火焰纹章为例,来介绍一文件操作的在游戏中的实际应用。

9-4-1.png

图9-4-1       

      在图中,我们能看到两个角色站在地图上的特定位置,并且这两个人物也是有区别的,他们的外形,血量,移动距离等等的属性都不尽相同。当我们要对游戏当前的状态进行保存时,我们需要关注的数据就包括:地图代号,人物代号,位置坐标,人物各项属性等。那么,只要把这些与状态相关的数据写入到存档文件,读取存档的时候就能够根据这些数据还原游戏保存之前的状态。
下面我们将为你展示在MC中实现这种功能的方法。
相关函数
      对文件的操作主要有以下几种:打开、关闭、读取、写入、修改、删除。下面根据不同的功能将函数一一列出。


Var文件的基本操作
Var_OpenFile
void* Var_OpenFile(const char *fileName, char *mode);
功能: 打开一个Var文件。打开成功返回该文件的指针,打开失败返回0, 如果模式为“r+”时且没有该文件,也同样返回0
参数: 
            fileName :代表文件名。
            mode: 模式与C语言的模式相同,但需要注意的是,只能使用二进制文件的读写,即如果读文件模式为 “rb”;写文件模式为 “wb”;读写文件,且不覆盖原文件的模式为“rb+”;读写文件,并覆盖原文件的模式为“wb+”文件。


Var_CloseFile
int Var_CloseFile(void *fp);
功能: 关闭一个Var文件,关闭成功返回1,关闭失败返回0。
参数:
            fileName:代表文件名。


Var_GetOneDimArraySize
int Var_GetOneDimArraySize(void *fp, char *variableName, int *arraySize);
功能:从文件中获得名为variableName的一维数组的大小。返回1代表读取成功,返回0代表读取失败。
参数:
            fp:文件的指针。
            variableName:要读取的变量名。
            arraySize:接收读取到的数组的大小。


Var_GetTwoDimArraySize
int Var_GetTwoDimArraySize(void *fp, char *variableName, int *rows, int *cols);
功能:从文件中获得名为variableName的二维数组的行数和列数。返回1代表读取成功,返回0代表读取失败。
参数:
            fp:文件的指针
            variableName:要读取的变量名。
            rowSize:接收该数组的行数。
            colSize:接受该数组的列数。


  Var文件的读操作

Var_ReadData
int Var_ReadData(void *fp, char *variableName, void *acceptVariable, int dataFlag);
功能:从文件中读取名为variableName的整数,或是一维整型数组。返回1代表读取成功,返回0代表读取失败。
参数:
            fp:文件的指针
            variableName:要读取的变量名。
            acceptVariable:接收读取到的数据。
            dataFlag:值为0表示Int型,  1 表示Double型,2表示String型,3表示Char型


Var_ReadPart
int Var_ReadPart(void *fp, char *variableName, void *acceptVariable, int startIndex, int endIndex, int dataFlag);
功能:从文件中读取名为variableName的数组中的部分数据。返回1代表读取成功,返回0代表读取失败。
参数:
            fp:文件的指针。
            variableName:要读取的变量名。
            acceptVariable:接收读取到的数据。
            startIndex:文件中变量的开始下标。
            endIndex:文件中变量的结束下标。
            dataFlag:值为0表示Int型,1 表示Double型,2表示String型,3表示Char型。


Var文件的写操作


Var_WriteData   (会先删除掉文件中已有的变量)
int Var_WriteData(void *fp, char *variableName, char *groupName, void *writeVariable, int dataRows, int dataCols, int spaceRows, int spaceCols, int dataFlag);
功能:从文件中写入名为variableName,组为groupName的整数, 或是一维整型数组。返回1代表写入成功,返回0代表写入失败。
参数:
            fp:文件的指针。
            variableName:要写入的变量名。
            groupName:变量的组名。
            writeVariable:要写入的数据。
            dataRows:要写入数据的行数。若为单个数据或一维数组,那么值为1。
            dataCols:要写入数据的列数,若为单个数据,那么值等于1,如果为一维数组那么值大于1。 
            spaceRows:数据要开辟的行数。若为单个数据或一维数组,那么值为1。
            spaceCols:数据要开辟的列数。若为单个数据,那么值等于1,如果为一维数组那么值大于1。
            dataFlag:值为0表示int型,1 表示double型,2表示string型,3表示char型。


Var_WritePart
int Var_WritePart(void *fp, char *variableName, char *groupName, void *writeVariable, int startIndex, int endIndex, int dataFlag);
功能:从文件中写入名为variableName,组为groupName的一维整型数组中的部分数据。返回1代表写入成功,返回0代表写入失败。
参数:
            fp:文件的指针。
            variableName:要写入的变量名。
            groupName:变量的组名。
            writeVariable:要写入的数据。
            startIndex:一维数组中表示文件中变量的开始下标, 二维数组中表示文件中变量的开始行下标。
            endIndex:一维数组中表示文件中变量的结束下标, 二维数组中表示文件中变量的结束行下标。
            dataFlag:值为0表示Int型,1 表示Double型,2表示String型,3表示Char型。


Var文件记录的删除操作

Var_DelateVariable
int Var_DelateVariable(void *fp, char *variableName);
功能:从文件中删除变量variableName,返回1代表删除成功,返回0代表删除失败。
参数:
            fp:文件的指针。
            variableName:要删除的变量。


Var_DelateFile
int Var_DelateFile(const char *FileName);
功能:删除该文件。返回1代表删除成功,返回0代表删除失败。
参数:
            FileName:文件的名字


   实例运用
在这里我们要模拟实现RPG游戏通常用到的存储,我们将创建一个玩家角色,以下记录的数据:人物所在坐标,姓名,金币,经验值,包裹信息。当我们捡起硬币、经验块或者物品的时候,对应的数值会增加。通过保存按钮,将这些数据写入文档,通过读取来还原现场。
下面进行实例的制作。
第一步,按照图示,摆好各个角色

9-4-2.png

图9-4-2-1

第二步:给各角色添加脚本和自定义变量
在脚本中添加自定义变量,如下所示:


9-4-3.png

图9-4-2-2

其中,cha_name,cha_gold,cha_exp,cha_pos,bag_1,bag_2这六个角色是用来显示数值的,对他们都添加“绘制角色”事件。
                      cha_name:
                      sprintf(text, ”Name:%s”, strName);
                      cha_gold:
                      sprintf(text, ”Gold:%d”, iGold);


                      cha_exp:
                      sprintf(text, ”Exp:%d”, iExp);


                      cha_pos:
                      sprintf(text, ”(%d,%d)”, actPlayer. x, image0. y);


                      bag_1:
                      sprintf(text, ”x%d”, iBag[0]);

                      bag_2:
                      sprint(text, “x%d”, iBag[1]);


      gold,exp,wood,box这四个角色模拟场景中的宝物,用于捡取以改变角色的数据。这里不做捡取后消失的设定,故对这四个角色添加“物体碰撞”事件,碰撞条件“任何边沿”。其脚本如下:
                      actGold:
                      iGold += 100;


                      actExp:
                      iExp += 100;


                      actItem1:
                      iBag[0] += 1;


                      actItem2:
                      iBag[1] += 1;
对actPlayer角色,添加如下五个事件:
①“绘制角色”事件,添加“脚本编辑器”行为
代码:
         //初始化站位
                      x = 0;
                      y = 0;
②上下左右四个“按键按下”事件,“脚本编辑器”行为
由于图片尺寸为33x33,所以偏移量统一设置成33。
                      上:     下:     左:     右:
                      y -= 33;   y += 33;   x -= 33;   x += 33;


btnSave角色,用于存储数据,添加左键“鼠标键按下”事件,“脚本编辑器”行为
代码:
                      int size;
        //打开文件
                      FILE *fp = Var_OpenFile("cha.sav", "wb");


        //对角色命名并保存
                      strcpy(strName,"Nero");
                      Var_WriteData(fp, "cha_name", "player", &strName, 1, 10, 1, 10, 2);


        //保存黄金数
                      Var_WriteData(fp, "cha_gold", "player", &iGold, 1, 1, 1, 1, 0);


        //保存经验值
                      Var_WriteData(fp, "cha_exp", "player", &iExp, 1, 1, 1, 1, 0);


       //先判断是否创建过坐标,通过读取cha_pos的位数来判断,然后进行写入,其中,写入的函数是不一样的
                      Var_GetOneDimArraySize(fp, "cha_pos", &size)
                      if( size != 2 )
                      {
                              iPos[0] = actPlayer.x;
                              iPos[1] = actPlayer.y;
                              Var_WriteData(fp, "cha_pos", "player", &iPos, 1, 2, 1, 2, 0);
                      }
                      else
                      {
                              iPos[0] = image0.x;
                              iPos[1] = image0.y;
                              Var_WritePart(fp, "cha_pos", "player", &iPos[0], 0, 0, 1);
                              Var_WritePart(fp, "cha_pos", "player", &cha_pos[1], 1, 1, 1);
                      }


        //存储包裹信息
                      Var_WriteData(fp, "cha_bag", "player", &iBag, 1, 2, 1, 2, 0);


       //关闭文件
                      Var_CloseFile(fp);


btnLoad角色,用于读取存档,添加左键“鼠标键按下”事件,“脚本编辑器”行为
代码:
       //打开文件
                      FILE *fp = Var_OpenFile("cha.sav", "rb");
       //读取操作
                      Var_ReadData(fp, "cha_name", &strName, 2);


                      Var_ReadData(fp, "cha_gold", &iGold, 0);


                      Var_ReadData(fp, "cha_exp", &iExp, 0);


                      Var_ReadPart(fp, "cha_pos", &iPos[0], 0, 0, 0);
                      Var_ReadPart(fp, "cha_pos", &iPos[1], 1, 1, 0);
                      actPlayer.x = iPos[0];
                      actPlayer.y = iPos[1];


                      Var_ReadData(fp, "cha_bag", &iBag, 0);


                      Var_CloseFile(fp) ;
      btnDel角色,用于删除存档,添加左键“鼠标键按下”事件,“脚本编辑器”行为
代码:
                      FILE *fp = Var_OpenFile("cha.sav", "wb+") ;
       //这是删除变量使用的,在不删除文件的情况下使用
                      Var_DelateVariable(fp, "cha_pos") ;


                      Var_CloseFile(fp) ;
       //这是删除存档文件,这里只是列出使用方法,具体做法酌情而定
                      Var_DelateFile("cha.sav") ;
现在,编码结束,可以导出文件进行测试了。
运行以后,我们可以通过方向键控制角色小人的移动,通过吃宝物增加财富或者能力或者物品,数值在屏幕左上方显示,通过保存按钮可以生成存档文件,保存当前状态,点击读取按钮将读取存档文件,还原保存时的状态与数据,删除按钮会删除存档文件。

本例只使用了整型和字符串数据,而上述的函数还能对实型和字符型数据进行处理,这些在未来的实践中慢慢体会吧。

Demo下载地址:http://www.dongyo.cn/bbs/forum.php?mod=viewthread&tid=2531&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline%26orderby%3Ddateline


原创粉丝点击