脚本指令《游戏脚本的设计与开发》-第一章 读取和解析一个脚本文件
2013-05-13 22:50
447 查看
本文个人在北京吃饭的时候突然想到的...今天就有想写几篇关于脚本指令的文章,所以回家到以后就奋笔疾书的写出来发表了
上一篇《游戏脚本的计划与开辟》-序中我介绍了游戏脚本的基本概念和准备工作,本篇来说说具体如何剖析一个脚本
所谓剖析脚本,就是按照自己定义的语法,将每个脚本命令还原成不同的代码逻辑进行执行,比如,我规定绘制一个矩形的脚本
和一个绘制圆的脚本
那么,当我读取到了字符串“draw rect”的时候,就在屏幕上画一个矩形,读取到了字符串“draw arc”的时候,就在屏幕上画一个圆。
如果你已经按照上一篇序中的说明安装了xampp,那么请找到xampp中的htdocs文件夹,在里面新建一个lsharp文件夹,然后再按照下面结构新建一些文件和文件夹
lsharp
|-script文件夹
|-index.html
|-Main.js
|-lufylegend.lsharp.js
|-lufylegend-1.7.5.js
index.html文件代码如下
注意:lufylegend-1.7.5.js你须要自己下载。
剖析脚本,须要建立一个剖析脚本的函数analysis,每剖析完一个脚本,就返回调用一次analysis函数,让剖析一直的进行,直到脚本文件全体剖析结束。
首先,在lufylegend.lsharp.js文件中新建一个LScript.js类,作为脚本剖析对象,用来控制脚本的剖析和执行。
代码剖析:
LScript.js类接受两个参数,第一个参数scriptLayer是显示层,也是应用L#脚本制作游戏的最底层画板,以后的脚本命令的全部绘图都将绘制到这个显示层上,第二个参数是一个字符串脚本,也是LScript.js对象被创建后立即会被剖析的脚本。
LGlobal.script将脚本剖析对象保存起来,便利回调脚本的剖析函数。
将显示层保存起来,便利以后应用。
保存脚本到缓存数组。
这一行是将整个字符串脚本进行分解,得到单个的脚本命令数组。
看一下toList函数:
代码剖析:
在L#中,我设定了各个的脚本指令之间是以分号来分割的,所以应用字符串的split函数对字符串进行分割,得到单个的脚本命令数组,并将其存入到脚本剖析对象的lineList。
copyList用来保存当前所执行的lineList,当有新的脚本命令lineList被添加进来的时候,当前的lineList就会被保存起来,当新的脚本命令lineList全体剖析完以后,就会对上一个未被剖析完的脚本命令继承进行剖析执行。
开始剖析脚本命令。
下面看一下症结的脚本剖析函数analysis。
代码剖析:
上面代码判断lineList数组内的脚本指令是不是被剖析完,如果被剖析完了的话,检查一下dataList数组中是否有其他未被执行的脚本,有则继承执行。
上面代码用来获得一个lineList数组中的脚本指令
如果当前脚本指令为空,则执行下一条指令
这行代码用来debug,发布的时候可以不要
在L#中,全部被执行的脚本指令,都是[类.命令]的格式,如果你在设定脚本的时候应用了其他格式,则请根据你的格式来做响应的处理。所以应用split函数,对每一条指令进行分割,获得须要的信息,进行剖析。
接着,我们在Main.js中参加以下代码
那么脚本剖析类会对["aaa;Load.script(script/Main.ls);bbb;"]这个脚本进行剖析,里面的脚本指令是我随便写的,并非准确的指令。
运行一下代码,
你当地的执行URL为http://localhost/lsharp/index.html
看看debug函数会输出的信息,如下
图1
可以看到,剖析类对脚本进行了剖析,按照分号将脚本分割为了三个指令,那么接下来就须要增加对每一条指令的剖析,当涌现了无法剖析的指令的时候,会自动跳过对下一个指令进行剖析。
下面,先来进行第一个脚本指令的剖析,应用这个脚原来读取一个脚本文件。
首先,我规定,在L#中读取一个脚本文件的语法如下
并且在script文件夹中新建一个Main.ls文件,用记事本打开Main.ls文件写入以下内容
接着,修改剖析函数中的switch部份,如下
所以,现在须要一个静态类ScriptLoad,来对Load指令进行剖析,新建一个ScriptLoad类,如下
每日一道理
人生是洁白的画纸,我们每个人就是手握各色笔的画师;人生也是一条看不到尽头的长路,我们每个人则是人生道路的远足者;人生还像是一块神奇的土地,我们每个人则是手握农具的耕耘者;但人生更像一本难懂的书,我们每个人则是孜孜不倦的读书郎。
ScriptLoad类的剖析函数analysis中,首先将脚本中括号外和括号内的内容[Load.script]和[script/Main.ls]分解出来,然后再利用switch函数进一步剖析。当遇到字符串“Load.script”的时候,调用loadScript函数来读取一个脚本文件。
看下面的代码
代码剖析
loadScript函数比较简单,就是应用LURLLoader对象来读取一个文件,读取完以后调用loadScriptOver函数。
loadScriptOver函数中利用下面三行代码,将读取进来的内容存入脚本剖析类的数组中,进行下一步剖析。
其中的saveList函数如下
所做的处理就是前面所说的,将当前正在执行的脚本数组保存起来
运行代码,debug输出以下信息
图2
可以看到,Main.ls脚本文件中的脚本指令都被剖析了出来,只是Text.label这个脚本我们还没有对其进行剖析,所以只是将其跳过了。
其实,我们还可以在脚本文件中再读取脚本文件,比如将Main.ls中的内容换成下面:
并且,再添加一个test.ls脚本文件,test.ls中的内容如下
运行一下程序,看debug输出如下信息:
图3
可以看到,test.ls中的脚本指令也被读取出来了。
测试连接
http://lufylegend.com/demo/test/lsharp/01/index.html
关于源码
现在代码比较少,我就直接贴出来了
Main.js
lufylegend.lsharp.js
本章就讲到这里,下一章我们真正的进入正题,一起来hello world!
最后做个广告,有奖征集活动系列——【HTML5游戏编程之旅】
欢送大家介入
/article/1399457.html
文章结束给大家分享下程序员的一些笑话语录:
面试官:熟悉哪种语言
应聘者:JAVA
面试官:知道什么叫类么
应聘者:我这人实在,工作努力,不知道什么叫累
面试官:知道什么是包?
应聘者:我这人实在 平常不带包 也不用公司准备了
面试官:知道什么是接口吗?
应聘者:我这个人工作认真。从来不找借口偷懒
面试官:知道什么是继承么
应聘者:我是孤儿没什么可以继承的
面试官:知道什么叫对象么?
应聘者:知道,不过我工作努力,上进心强,暂时还没有打算找对象。
面试官:知道多态么?
应聘者:知道,我很保守的。我认为让心爱的女人为了自已一时的快乐去堕胎是不道德的行为!请问这和C#有什么关系??
上一篇《游戏脚本的计划与开辟》-序中我介绍了游戏脚本的基本概念和准备工作,本篇来说说具体如何剖析一个脚本
所谓剖析脚本,就是按照自己定义的语法,将每个脚本命令还原成不同的代码逻辑进行执行,比如,我规定绘制一个矩形的脚本
draw rect
和一个绘制圆的脚本
draw arc
那么,当我读取到了字符串“draw rect”的时候,就在屏幕上画一个矩形,读取到了字符串“draw arc”的时候,就在屏幕上画一个圆。
如果你已经按照上一篇序中的说明安装了xampp,那么请找到xampp中的htdocs文件夹,在里面新建一个lsharp文件夹,然后再按照下面结构新建一些文件和文件夹
lsharp
|-script文件夹
|-index.html
|-Main.js
|-lufylegend.lsharp.js
|-lufylegend-1.7.5.js
index.html文件代码如下
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>L#</title> </head> <body> <div id="mylegend">loading......</div> <script type="text/javascript" src="./lufylegend-1.7.5.js"></script> <script type="text/javascript" src="./lufylegend.lsharp.js"></script> <script type="text/javascript" src="./Main.js"></script> </body> </html>
注意:lufylegend-1.7.5.js你须要自己下载。
剖析脚本,须要建立一个剖析脚本的函数analysis,每剖析完一个脚本,就返回调用一次analysis函数,让剖析一直的进行,直到脚本文件全体剖析结束。
首先,在lufylegend.lsharp.js文件中新建一个LScript.js类,作为脚本剖析对象,用来控制脚本的剖析和执行。
/** LScript.js **/ function LScript(scriptLayer,value){ var self = this; LGlobal.script = self; self.scriptLayer = scriptLayer; self.dataList = new Array(); var arr=[value]; self.dataList.unshift(arr); self.toList(value); }
代码剖析:
LScript.js类接受两个参数,第一个参数scriptLayer是显示层,也是应用L#脚本制作游戏的最底层画板,以后的脚本命令的全部绘图都将绘制到这个显示层上,第二个参数是一个字符串脚本,也是LScript.js对象被创建后立即会被剖析的脚本。
LGlobal.script = self;
LGlobal.script将脚本剖析对象保存起来,便利回调脚本的剖析函数。
self.scriptLayer = scriptLayer;
将显示层保存起来,便利以后应用。
self.dataList = new Array(); var arr=[value]; self.dataList.unshift(arr);
保存脚本到缓存数组。
self.toList(value);
这一行是将整个字符串脚本进行分解,得到单个的脚本命令数组。
看一下toList函数:
toList:function(ltxt){ var self = this; self.lineList = ltxt.split(";"); self.copyList = self.lineList.slice(0); self.analysis(); }
代码剖析:
self.lineList = ltxt.split(";");
在L#中,我设定了各个的脚本指令之间是以分号来分割的,所以应用字符串的split函数对字符串进行分割,得到单个的脚本命令数组,并将其存入到脚本剖析对象的lineList。
self.copyList = self.lineList.slice(0);
copyList用来保存当前所执行的lineList,当有新的脚本命令lineList被添加进来的时候,当前的lineList就会被保存起来,当新的脚本命令lineList全体剖析完以后,就会对上一个未被剖析完的脚本命令继承进行剖析执行。
self.analysis();
开始剖析脚本命令。
下面看一下症结的脚本剖析函数analysis。
analysis:function(){ var self = this; var lineValue = ""; if(self.lineList.length == 0){ self.dataList.shift(); if(self.dataList.length > 0){ arr=self.dataList[0]; self.lineList = arr[1]; self.copyList = arr[2]; self.analysis(); } return; } while(self.lineList.length > 0){ lineValue = LMath.trim(self.lineList[0]); self.lineList.shift(); } if(lineValue.length == 0){ self.analysis(); return; } trace("analysis lineValue = " + lineValue); var sarr = lineValue.split("."); switch(sarr[0]){ default: self.analysis(); } }
代码剖析:
if(self.lineList.length == 0){ self.dataList.shift(); if(self.dataList.length > 0){ arr=self.dataList[0]; self.lineList = arr[1]; self.copyList = arr[2]; self.analysis(); } return; }
上面代码判断lineList数组内的脚本指令是不是被剖析完,如果被剖析完了的话,检查一下dataList数组中是否有其他未被执行的脚本,有则继承执行。
var lineValue = ""; while(self.lineList.length > 0 && lineValue.length == 0){ lineValue = LMath.trim(self.lineList[0]); self.lineList.shift(); }
上面代码用来获得一个lineList数组中的脚本指令
if(lineValue.length == 0){ self.analysis(); return; }
如果当前脚本指令为空,则执行下一条指令
trace("analysis lineValue = " + lineValue);
这行代码用来debug,发布的时候可以不要
var sarr = lineValue.split("."); switch(sarr[0]){ default: self.analysis(); }
在L#中,全部被执行的脚本指令,都是[类.命令]的格式,如果你在设定脚本的时候应用了其他格式,则请根据你的格式来做响应的处理。所以应用split函数,对每一条指令进行分割,获得须要的信息,进行剖析。
接着,我们在Main.js中参加以下代码
init(50,"mylegend",400,100,main); function main(){ LGlobal.setDebug(true); var sc = "aaa;Load.script(script/Main.ls);bbb;"; var sp = new LSprite(); addChild(sp); var script = new LScript(sp,sc); }
那么脚本剖析类会对["aaa;Load.script(script/Main.ls);bbb;"]这个脚本进行剖析,里面的脚本指令是我随便写的,并非准确的指令。
运行一下代码,
你当地的执行URL为http://localhost/lsharp/index.html
看看debug函数会输出的信息,如下
图1
可以看到,剖析类对脚本进行了剖析,按照分号将脚本分割为了三个指令,那么接下来就须要增加对每一条指令的剖析,当涌现了无法剖析的指令的时候,会自动跳过对下一个指令进行剖析。
下面,先来进行第一个脚本指令的剖析,应用这个脚原来读取一个脚本文件。
首先,我规定,在L#中读取一个脚本文件的语法如下
Load.script(script/Main.ls);
并且在script文件夹中新建一个Main.ls文件,用记事本打开Main.ls文件写入以下内容
Text.label(-,txt,测试a,0,0,30,#000000); Text.label(-,txt,测试b,0,0,30,#000000);
接着,修改剖析函数中的switch部份,如下
switch(sarr[0]){ case "Load": ScriptLoad.analysis(lineValue); break; default: self.analysis(); }
所以,现在须要一个静态类ScriptLoad,来对Load指令进行剖析,新建一个ScriptLoad类,如下
每日一道理
人生是洁白的画纸,我们每个人就是手握各色笔的画师;人生也是一条看不到尽头的长路,我们每个人则是人生道路的远足者;人生还像是一块神奇的土地,我们每个人则是手握农具的耕耘者;但人生更像一本难懂的书,我们每个人则是孜孜不倦的读书郎。
/* * ScriptLoad.js **/ var ScriptLoad = function (){}; ScriptLoad.data = ""; ScriptLoad.urlloader = null; ScriptLoad.analysis = function (value){ var start = value.indexOf("("); var end = value.indexOf(")"); ScriptLoad.data = value.substring(start+1,end).split(","); switch(LMath.trim(value.substr(0,start))){ case "Load.script": ScriptLoad.loadScript(); break; default: LGlobal.script.analysis(); } };
ScriptLoad类的剖析函数analysis中,首先将脚本中括号外和括号内的内容[Load.script]和[script/Main.ls]分解出来,然后再利用switch函数进一步剖析。当遇到字符串“Load.script”的时候,调用loadScript函数来读取一个脚本文件。
看下面的代码
ScriptLoad.loadScript = function (){ ScriptLoad.urlloader = new LURLLoader(); ScriptLoad.urlloader.addEventListener(LEvent.COMPLETE,ScriptLoad.loadScriptOver); ScriptLoad.urlloader.load(ScriptLoad.data[0],"text"); }; ScriptLoad.loadScriptOver = function (event){ var script = LGlobal.script; var data = event.target.data; ScriptLoad.urlloader.die(); ScriptLoad.urlloader = null; script.saveList(); script.dataList.unshift([data]); script.toList(data); };
代码剖析
loadScript函数比较简单,就是应用LURLLoader对象来读取一个文件,读取完以后调用loadScriptOver函数。
loadScriptOver函数中利用下面三行代码,将读取进来的内容存入脚本剖析类的数组中,进行下一步剖析。
script.saveList(); script.dataList.unshift([data]); script.toList(data);
其中的saveList函数如下
saveList:function(){ var self = this; var arr=self.dataList[0]; if(arr){ arr[1]=self.lineList; arr[2]=self.copyList; } }
所做的处理就是前面所说的,将当前正在执行的脚本数组保存起来
运行代码,debug输出以下信息
图2
可以看到,Main.ls脚本文件中的脚本指令都被剖析了出来,只是Text.label这个脚本我们还没有对其进行剖析,所以只是将其跳过了。
其实,我们还可以在脚本文件中再读取脚本文件,比如将Main.ls中的内容换成下面:
Text.label(-,txt,测试a,0,0,30,#000000); Load.script(script/test.ls); Text.label(-,txt,测试b,0,0,30,#000000);
并且,再添加一个test.ls脚本文件,test.ls中的内容如下
Text.label(-,txt,测试c,0,0,30,#000000);
运行一下程序,看debug输出如下信息:
图3
可以看到,test.ls中的脚本指令也被读取出来了。
测试连接
http://lufylegend.com/demo/test/lsharp/01/index.html
关于源码
现在代码比较少,我就直接贴出来了
Main.js
init(50,"mylegend",400,100,main); function main(){ LGlobal.setDebug(true); var sc = "Load.script(script/Main.ls);"; var sp = new LSprite(); addChild(sp); var script = new LScript(sp,sc); }
lufylegend.lsharp.js
/*
* LScript.js
**/
function LScript(scriptLayer,value){
var self = this;
LGlobal.script = self;
self.scriptLayer = scriptLayer;
self.dataList = new Array(); var arr=[value]; self.dataList.unshift(arr);
self.toList(value);
}
LScript.prototype = {
toList:function(ltxt){ var self = this; self.lineList = ltxt.split(";"); self.copyList = self.lineList.slice(0); self.analysis(); },
saveList:function(){ var self = this; var arr=self.dataList[0]; if(arr){ arr[1]=self.lineList; arr[2]=self.copyList; } },
analysis:function(){
var self = this;
var arr;
if(self.lineList.length == 0){ self.dataList.shift(); if(self.dataList.length > 0){ arr=self.dataList[0]; self.lineList = arr[1]; self.copyList = arr[2]; self.analysis(); } return; }
var lineValue = ""; while(self.lineList.length > 0 && lineValue.length == 0){ lineValue = LMath.trim(self.lineList[0]); self.lineList.shift(); }
if(lineValue.length == 0){ self.analysis(); return; }
trace("analysis lineValue = " + lineValue);
var sarr = lineValue.split(".");
switch(sarr[0]){ case "Load": ScriptLoad.analysis(lineValue); break; default: self.analysis(); }
}
};
/* * ScriptLoad.js **/ var ScriptLoad = function (){}; ScriptLoad.data = ""; ScriptLoad.urlloader = null; ScriptLoad.analysis = function (value){ var start = value.indexOf("("); var end = value.indexOf(")"); ScriptLoad.data = value.substring(start+1,end).split(","); switch(LMath.trim(value.substr(0,start))){ case "Load.script": ScriptLoad.loadScript(); break; default: LGlobal.script.analysis(); } };
ScriptLoad.loadScript = function (){ ScriptLoad.urlloader = new LURLLoader(); ScriptLoad.urlloader.addEventListener(LEvent.COMPLETE,ScriptLoad.loadScriptOver); ScriptLoad.urlloader.load(ScriptLoad.data[0],"text"); }; ScriptLoad.loadScriptOver = function (event){ var script = LGlobal.script; var data = event.target.data; ScriptLoad.urlloader.die(); ScriptLoad.urlloader = null; script.saveList(); script.dataList.unshift([data]); script.toList(data); };
本章就讲到这里,下一章我们真正的进入正题,一起来hello world!
最后做个广告,有奖征集活动系列——【HTML5游戏编程之旅】
欢送大家介入
/article/1399457.html
文章结束给大家分享下程序员的一些笑话语录:
面试官:熟悉哪种语言
应聘者:JAVA
面试官:知道什么叫类么
应聘者:我这人实在,工作努力,不知道什么叫累
面试官:知道什么是包?
应聘者:我这人实在 平常不带包 也不用公司准备了
面试官:知道什么是接口吗?
应聘者:我这个人工作认真。从来不找借口偷懒
面试官:知道什么是继承么
应聘者:我是孤儿没什么可以继承的
面试官:知道什么叫对象么?
应聘者:知道,不过我工作努力,上进心强,暂时还没有打算找对象。
面试官:知道多态么?
应聘者:知道,我很保守的。我认为让心爱的女人为了自已一时的快乐去堕胎是不道德的行为!请问这和C#有什么关系??
相关文章推荐
- 《游戏脚本的设计与开发》-1.1 读取和解析一个脚本文件
- 《游戏脚本的设计与开发》-1.4 图片的读取显示
- 《游戏脚本的设计与开发》-第一章总结 文字脚本的功能扩展和一个游戏测试
- 设计一个学生类,其中包含学号、姓名、成绩等数据成员,创建学生对象并且倒入到文件file.txt,然后由文件读取到另一个学生对象并输出,试编程实现。
- Cocos2d-x 游戏开发中读取XML文件拷贝
- [转]电子商务文件存储及读取服务的设计和开发思路
- 6.游戏特别离不开脚本(3)-JS脚本操作java(直接解析JS公式,并非完整JS文件或者函数)
- 6.游戏特别离不开脚本(3)-JS脚本操作java(2)(直接解析JS公式,并非完整JS文件或者函数)
- 《游戏脚本的设计与开发》-序
- 《游戏脚本的设计与开发》-(RPG部分)3.1 RPG地图到底怎么做?
- Android下使用TinyXml读取xml配置文件(Cocos2d-x游戏开发)
- Android开发之Pull解析读取和生成XML文件
- Linux脚本设计练习2——一个游戏菜单的简单实现
- 批处理脚本读取文件内容赋值给一个变量
- 电子商务文件存储及读取服务的设计和开发思路(JMagick用于生成高清的缩略图)
- shell脚本按行读取文件并解析
- 一个脚本文件的解析
- 一个读取文件内容的shell脚本
- android 2D游戏开发,引擎设计(二)脚本思考
- shell脚本按行读取配置文件并解析