登录社区:用户名: 密码: 忘记密码 网页功能:加入收藏 设为首页 网站搜索  

文档

下载

图书

论坛

安全

源码

硬件

游戏
首页 信息 空间 VB VC Delphi Java Flash 补丁 控件 安全 黑客 电子书 笔记本 手机 MP3 杀毒 QQ群 产品库 分类信息 编程网站
  立华软件园 - 安全技术中心 - 技术文档 - 入门基础 技术文章 | 相关下载 | 电子图书 | 攻防录像 | 安全网站 | 在线论坛 | QQ群组 | 搜索   
 安全技术技术文档
  · 安全配制
  · 工具介绍
  · 黑客教学
  · 防火墙
  · 漏洞分析
  · 破解专题
  · 黑客编程
  · 入侵检测
 安全技术工具下载
  · 扫描工具
  · 攻击程序
  · 后门木马
  · 拒绝服务
  · 口令破解
  · 代理程序
  · 防火墙
  · 加密解密
  · 入侵检测
  · 攻防演示
 安全技术论坛
  · 安全配制
  · 工具介绍
  · 防火墙
  · 黑客入侵
  · 漏洞检测
  · 破解方法
 其他安全技术资源
  · 攻防演示动画
  · 电子图书
  · QQ群组讨论区
  · 其他网站资源
最新招聘信息

脚本系统的实现
发表日期:2007-03-28作者:[转贴] 出处:  

 作者:Flysky 2006

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

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

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

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

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

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

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

    bool CScript::LoadScript(char *FileName)
    {
        ifstream is;
        int ZS;
        int sta,end;
        if (IsFile(FileName)==false) return false; //直接返回,因为不存在
        IsNextLine=true;
        strcpy(Name,FileName);
        is.open(FileName);
        if (IsNextLine==true) getline(is,str);
        ZS=int(str.find("//"));
        str=str.substr(0,ZS); //去掉注释语句
        replace_all_distinct(str,"'",""); //自己写的替换函数
        replace_all_distinct(str,syh,""); //自己写的替换函数,syh是双引号的ASCII码
        if (stricmp(str.c_str(),"return;")==0||stricmp(str.c_str(),"return();")==0) break;
        else RunScript();
        //IF语句的实现
        if (stricmp(M_CMD.c_str(),"If")==0)
        {
            int IfP=2;
            //If(X(Y)) 肯定条件,相符运行语句
            if (M_CANX[0].find("(")!=-1)
            {
                sta=int(M_CANX[0].find("(")); //比如IF(XX[(]XX))
                end=int(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);//获取if里的变量
                //strcpy(SMessage,M_IFO.c_str());
                if (M_IFO==M_IFT) IfP=0; //0为通过
                else IfP=1; //1为不通过
            }
            //If(X[Y]) 否定条件,不符运行语句  
            if (M_CANX[0].find("[")!=-1)
            {
                sta=int(M_CANX[0].find("[")); //比如IF(XX[XX])
                end=int(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);//获取if里的变量
                if (M_IFO!=M_IFT)IfP=0; //0为通过
                else IfP=1; //1为不通过
            }

            if (IfP!=2)
            {
                if (IfP==0)
                {
                    while(str!="}") //什么时候结束
                    {
                        if (IsNextLine==true) getline(is,str);
                        ZS=int(str.find("//"));
                        str=str.substr(0,ZS); //去掉注释语句
                        replace_all_distinct(str,"'","");
                        replace_all_distinct(str,syh,"");
                        if (str.find("return;")!=str.npos||str.find("return();")!=str.npos) {break;break;} //结束脚本
                        else RunScript();
                        //二级IF
                        //完成
                    }
                }
                else
                {
                    while(str!="}") //什么时候结束
                    {
                        getline(is,str); //到"{"这一行
                    }
                }
            }
            IfP=2;
            M_IFO.clear();
            M_IFT.clear();
            } //IF结束
            //结束
        }
        M_IFO.clear();
        M_IFT.clear();
        is.close();
        return true;
    }

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

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

    void CScript::RunScript() //运行一行脚本
    {
        int VarVa=int(str.find_first_of("="));
        int sta=int(str.find_first_of("("));
        int end=int(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 (int i=0;i<int(VARA.size());i++) 
        {
            replace_all_distinct(M_CAN,"["+VARA[i].Name+"]",VARA[i].value);
            replace_all_distinct(M_CAN,VARA[i].Name,VARA[i].value);
        }
        for (int i=0;i<MAX_CANX;i++)
        {
            sta=int(M_CAN.find(","));
            M_CANX[i]=M_CAN.substr(0,sta);
            M_CAN.replace(0,sta+1,"");
            if (stricmp(M_CANX[i].c_str(),"False")==0) CanB[i]=0;
            else if (stricmp(M_CANX[i].c_str(),"True")==0) CanB[i]=1; //布尔变量读取
        }
        if (M_CMD.length()!=0)FenJScript(); //执行脚本
        if (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的string,具体的资料可以上网查.

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

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

    else if (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);
    }

    else if (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);
    }
    else if (stricmp(M_CMD.c_str(),"NewVar")==0) AddVar(M_CANX[0],M_CANX[1]);//创建变量
    else if (stricmp(M_CMD.c_str(),"ClearVar")==0) ClearVar();//清除所有的变量
    .....  //后面的大同小异

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

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

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

    void CScript::FenJVar()
    {
        if (M_value.length()==0)
        {
            M_value=M_RIGHT;
            replace_all_distinct(M_value,";","");
        }
        for (int i=0;i<int(VARA.size());i++)
            if (VARA[i].Name==M_VAR)   VARA[i].value=M_value;
        M_value.clear();//返回清空
    }

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

    bool CScript::ClearVar()
    {
        //清空变量
        VARA.clear();
        return true;
    }

  再补充stVariable结构:

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

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

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

[全文完]

我来说两句】 【发送给朋友】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 脚本系统的实现

 ■ [欢迎对本文发表评论]
用  户:  匿名发出:
您要为您所发的言论的后果负责,故请各位遵纪守法并注意语言文明。

最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放 / 友情链接  
Copyright ©2001-2006 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00215