系统垃圾清理脚本:脚本系统的实现



作者:Flysky 2006

  终于又有时间写文章了,这回我们要实现个简单脚本系统(很简单)!

  说实话原来电脑报 2004年合订本有个很好直角90度游戏开发系列里面游戏脚本系统讲得还可以,如果你对本文还存在疑惑可以看那个游戏开发系列

  和以前我在脚本系统中没有掺合任何有关DirectX内容只讲理论!

  看看KGameV1.0(2005年5月初次在gameres中出现,就是13岁开发游戏那个文章:))脚本系统实现.

  首先是脚本类:
     Cscript
    {
        char Name[64];
        vector<stVariable> VARA;  
        bool ScrIsFill; //脚本运行时是否使用黑屏
         str; //行完整指令
         M_CMD;  //M_CMD 命令M_CAN 临时储存参数
         M_CANX[MAX_CANX];  //参数
         M_CAN,M_RIGHT;
         M_VAR;  //变量
         M_value;  //变量,如果为空就为"="右边去掉";"数据否则为"="右边脚本返回值
         M_IFO,M_IFT;
         CanB[MAX_CANX]; //参数是布尔话在这里储存
        public:
        Cscript;
        ~Cscript;
        bool Loadscript(char *FileName);
        void scriptXCanC;
        void ShowERROR( M_CMD); //显示
        void FenJscript;
        void Runscript;
        void FenJVar;
        bool BscriptBg(char *FileName);
        bool AddVar( Name, value);
        bool ClearVar;
    };

  其实就只有这些东西,读取个脚本弄出内容分析内容(这时候边分析边执行相应),添加个变量删除个变量等等.....

  读取脚本实现(其实这个KGameV1.0写得并不好我自己承认但起码做出来了,呵呵!)

    bool Cscript::Loadscript(char *FileName)
    {
        stream is;
         ZS;
         sta,end;
         (IsFile(FileName)false)  false; //直接返回不存在
        IsNextLine=true;
        strcpy(Name,FileName);
        is.open(FileName);
         (IsNextLinetrue) getline(is,str);
        ZS=(str.find("//"));
        str=str.substr(0,ZS); //去掉注释语句
        replace_all_distinct(str,"'",""); //自己写替换
        replace_all_distinct(str,syh,""); //自己写替换,syh是双引号ASCII码
         (stricmp(str.c_str,";")0||stricmp(str.c_str,";")0) ;
         Runscript;
        //IF语句实现
         (stricmp(M_CMD.c_str,"If")0)
        {
             IfP=2;
            //If(X(Y)) 肯定条件相符运行语句
             (M_CANX[0].find("(")!=-1)
            {
                sta=(M_CANX[0].find("(")); //比如IF(XX[(]XX))
                end=(M_CANX[0].find_last_of(")"));//比如IF(XX(XX[)])
                M_IFO=M_CANX[0].substr(0,sta);//获取IF里命令


                M_IFT=M_CANX[0].substr(sta+1,end-sta-1);//获取变量
                //strcpy(SMessage,M_IFO.c_str);
                 (M_IFOM_IFT) IfP=0; //0为通过
                 IfP=1; //1为不通过
            }
            //If(X[Y]) 否定条件不符运行语句  
             (M_CANX[0].find("[")!=-1)
            {
                sta=(M_CANX[0].find("[")); //比如IF(XX[XX])
                end=(M_CANX[0].find_last_of("]"));//比如IF(XX[XX])
                M_IFO=M_CANX[0].substr(0,sta);//获取IF里命令
                M_IFT=M_CANX[0].substr(sta+1,end-sta-1);//获取变量
                 (M_IFO!=M_IFT)IfP=0; //0为通过
                 IfP=1; //1为不通过
            }

             (IfP!=2)
            {
                 (IfP0)
                {
                    while(str!="}") //什么时候结束
                    {
                         (IsNextLinetrue) getline(is,str);
                        ZS=(str.find("//"));
                        str=str.substr(0,ZS); //去掉注释语句
                        replace_all_distinct(str,"'","");
                        replace_all_distinct(str,syh,"");
                         (str.find(";")!=str.npos||str.find(";")!=str.npos) {;;} //结束脚本
                         Runscript;
                        // 2级IF
                        //完成
                    }
                }
                
                {
                    while(str!="}") //什么时候结束
                    {
                        getline(is,str); //到"{"
                    }
                }
            }
            IfP=2;
            M_IFO.clear;


            M_IFT.clear;
            } //IF结束
            //结束
        }
        M_IFO.clear;
        M_IFT.clear;
        is.close;
         true;
    }

  其实IF语句实现占了代码比较多比例,简单思路方法就是stream这个东西有个读取substr具体自己研究下吧也可以用KGame V1.0代码学习.

  运行了这段代码后脚本就被切成(此时"//"和这行后面内容早已删去),下:

    void Cscript::Runscript //运行行脚本
    {
         VarVa=(str.find_first_of("="));
         sta=(str.find_first_of("("));
         end=(str.find_last_of(")"));
        M_VAR=str.substr(0,VarVa);//获取变量
        M_CMD=str.substr(VarVa+1,sta-VarVa-1);//获取命令
        M_CAN=str.substr(sta+1,end-sta-1);//获取全部参数
        M_RIGHT=str.substr(VarVa+1,strlen(str.c_str));
        for ( i=0;i<(VARA.size);i
        {
            replace_all_distinct(M_CAN,"["+VARA.Name+"]",VARA.value);
            replace_all_distinct(M_CAN,VARA.Name,VARA.value);
        }
        for ( i=0;i<MAX_CANX;i)
        {
            sta=(M_CAN.find(","));
            M_CANX=M_CAN.substr(0,sta);
            M_CAN.replace(0,sta+1,"");
             (stricmp(M_CANX.c_str,"False")0) CanB=0;
              (stricmp(M_CANX.c_str,"True")0) CanB=1; //布尔变量读取
        }
         (M_CMD.length!=0)FenJscript; //执行脚本
         (M_VAR.length!=0)FenJVar;   //分析变量脚本有有返回值
    }

  我代码风格不是很好凑合看看吧!

  这段就是把这行给拆开,M_CMD就是gggg(1fs,fs)gggg,M_CAN是1fs,fs串,M_CANX就是里面存贮着个个参数,比如这里M_CANX[0]="1fs",M_CANX[1]="fs",注意我使用是STL具体资料可以上网查.

  把命令和参数分开了步就是执行了.

     (stricmp(M_CMD.c_str,"Close")0) RunMessage(MS_Close,0,NULL,0,0,0,0,NULL,0); //命令2,关闭引擎

      (stricmp(M_CMD.c_str,"NewMap")0) //创建地图
    {
        strcpy(Tempc,M_CANX[0].c_str);t5=atoi(Tempc);

        strcpy(Tempc,M_CANX[2].c_str);t1=atoi(Tempc);
        strcpy(Tempc,M_CANX[3].c_str);t2=atoi(Tempc);
        strcpy(Tempc,M_CANX[4].c_str);t3=atoi(Tempc);
        strcpy(Tempc,M_CANX[5].c_str);t4=atoi(Tempc);
        strcpy(Tempc,M_CANX[6].c_str);t6=atoi(Tempc);
        strcpy(Tempc,M_CANX[1].c_str);
        strcpy(tmpc,M_CANX[7].c_str);
        RunMessage(MS_NWMAP,t5,Tempc,t1,t2,t3,t4,tmpc,t6);
    }

      (stricmp(M_CMD.c_str,"ReadATile")0) //读取个TILE资源到表面
    {
        strcpy(Tempc,M_CANX[0].c_str);t1=atoi(Tempc);
        strcpy(Tempc,M_CANX[1].c_str);
        RunMessage(MS_RAT,t1,Tempc,0,0,0,0,NULL,0);
    }
      (stricmp(M_CMD.c_str,

"NewVar")0) AddVar(M_CANX[0],M_CANX[1]);//创建变量
      (stricmp(M_CMD.c_str,"ClearVar")0) ClearVar;//清除所有变量
    .....  //后面大同小异

  再声明这个脚本系统只是我学习C的作现在绝对不会这样写了使用KGameV1.0这个源代码也是迫不得已目前我只对这个源代码熟(虽然圣剑得更好但他实现太麻烦)

  可以看出这里基本都重复了就是把这些参数给消息系统(当然现在我实现思路方法不会说 :))

  剩下就是变量处理了看到这部分代码上面不明白代码基本就明白了!

    void Cscript::FenJVar
    {
         (M_value.length0)
        {
            M_value=M_RIGHT;
            replace_all_distinct(M_value,";","");
        }
        for ( i=0;i<(VARA.size);i)
             (VARA.NameM_VAR)   VARA.value=M_value;
        M_value.clear;//返回清空
    }

    bool Cscript::AddVar( Name, value)
    {
        stVariable TVar;
        TVar.Name=Name;
        TVar.value=value;
        VARA.push_back(TVar); //压这个变量
         true;
    }

    bool Cscript::ClearVar
    {
        //清空变量
        VARA.clear;
         true;
    }

  再补充stVariable结构:

    //变量结构
    struct stVariable{
         Name; //名称
         value; //当前值
    };

  这段代码是后期写前期不好构架所以后期也不能大改了 :( 详细地看注释吧!

  再次草草完成篇文章其实这篇文章是给自己看免得以后忘了这段游戏开发经历!

[全文完] 
Tags:  系统发布脚本不运行 系统优化脚本 系统清理脚本 系统垃圾清理脚本

延伸阅读

最新评论

发表评论