`
20386053
  • 浏览: 432801 次
文章分类
社区版块
存档分类
最新评论

《游戏脚本的设计与开发》-第五章 显示层,绘图

 
阅读更多

我不止一次在文章中说过游戏分层的重要性,处理好游戏显示层的划分和这些显示层的顺序,就可以完美控制游戏中各元素的显示和遮挡,本章来使用脚本来实现游戏显示层的划分,并且在显示层上绘制各种图形。文章中要实现的几个脚本如下。

/*
游戏脚本的设计与开发 第五章
*/
//添加显示层
Layer.add(-,layer01,100,100);
//清空显示层
Layer.clear(layer01);
//移除显示层
Layer.remove(layer01);
//绘制实心矩形
Layer.drawRect(layer02,0,0,100,100,0xff0000);
//绘制空心矩形框
Layer.drawRectLine(layer02,0,0,100,100,0xff0000);
//绘制实心圆角矩形
Layer.drawRoundRect(layer01,0,0,100,100,10,0x880000);
//绘制空心圆角矩形框
Layer.drawRoundRectLine(layer01,0,0,100,100,10,0x880000);
//绘制实心三角形
Layer.drawTriangle(layer03,0,0,100,100,50,150,0xff0000);
//绘制空心三角形框
Layer.drawTriangleLine(layer03,0,0,100,100,50,0,0xff0000);
//对显示层进行缓动操作
Layer.transition(layer03,{x:50},1,Strong.easeOut);
下面我们就来一个一个的实现这些脚本的解析。

一,显示层的添加,清空和删除

要想实现游戏中的分层,首先需要将显示层添加到游戏中,首先修改ScriptLayer类的解析函数。

ScriptLayer.analysis = function (value){
	var start = value.indexOf("(");
	var end = value.indexOf(")");
	switch(value.substr(0,start)){
		case "Layer.add"://添加显示层
			ScriptLayer.setLayer(value,start,end);
			break;
		case "Layer.remove"://移除显示层
			ScriptLayer.removeLayer(value,start,end);
			break;
		case "Layer.clear"://清空显示层
			ScriptLayer.clearLayer(value,start,end);
			break;
		default:
	}
};

1,添加显示层

添加显示层最简单,看下面的代码
ScriptLayer.setLayer = function (value,start,end){
	var params = value.substring(start+1,end).split(",");
	var parentStr = params[0];
	var nameStr = params[1];
	var xInt = parseInt(params[2]);
	var yInt = parseInt(params[3]);
	var script = LGlobal.script;
	var layer,parent,i;
	parent = script.scriptArray.layerList[parentStr];
	layer = new LSprite();
	layer.x = xInt;
	layer.y = yInt;
	layer.name = nameStr;
	parent.addChild(layer);
	script.scriptArray.layerList[nameStr] = layer;
	script.analysis();
};
从下面的脚本中可以看到,添加显示层的一共需要4个参数,依次是被添加显示层的父级层,被添加显示层的名称,坐标x,坐标y。
Layer.add(-,layer01,100,100);
ScriptLayer.setLayer函数中,首先根据逗号,将参数分解出来,根据名字从script.scriptArray.layerList中找到父级显示层对象,然后新建一个LSprite,添加到父级显示层,最后保存到layerList数组。

下面来测试一下,修改脚本文件如下

Layer.add(-,layer01,100,100);
Layer.add(-,layer02,150,150);
Layer.add(layer01,layer03,200,200);
Load.img(backdata,lufy_legend.jpg);
Img.add(layer01,backimg01,backdata,0,0,100,100,1);
Img.add(layer02,backimg02,backdata,0,0,100,100,1);
Img.add(layer03,backimg03,backdata,0,0,100,100,1);

测试连接

http://lufylegend.com/demo/test/lsharp/05/index01.html

运行脚本,得到下面效果


2,清空显示层

清空显示层就是将该显示层上的所有子类都移除,看下面的代码

ScriptLayer.removeFromArray = function (obj){
	if(obj.childList == null)return;
	var count = obj.childList.length;
	for(var i = 0; i < count; i++){
		if(obj.type == "LSprite"){
			ScriptLayer.removeFromArray(obj.childList[i]);
		}else if(obj.type == "LBitmap"){
			LGlobal.script.scriptArray.imgList[obj.childList[i].name] = null;
		}else if(obj.type == "LTextField"){
			LGlobal.script.scriptArray.textList[obj.childList[i].name] = null;
		}
	}
};
ScriptLayer.clearLayer = function (value,start,end){
	var nameStr = LMath.trim(value.substring(start+1,end));
	var script = LGlobal.script;
	var layer = script.scriptArray.layerList[nameStr];
	if(!layer){
		script.analysis();
		return;
	}
	ScriptLayer.removeFromArray(layer);
	layer.die();
	layer.removeAllChild();
	script.analysis();
};

其实清空一个LSprite对象是很简单的,调用die函数,可以移除所有事件,调用removeAllChild可以移除所有的子对象,但是这里除了清空该对象之外,还是要将被移除的子对象以及子对象的子对象等等,都需要从layerList数组中移除,所以我添加了removeFromArray函数,这个函数中递归循环所有子对象,将他们从layerList中全部清除,这样就真正实现了从脚本引擎中清空一个LSprite对象了。

3,移除显示层

移除一个LSprite对象,只需要从它的父级显示层对象中removeChild就可以了,但是和上面的清空显示层一样,同样需要将子对象等清空。看下面代码。

ScriptLayer.removeLayer = function (value,start,end){
	var nameStr = LMath.trim(value.substring(start+1,end));
	var script = LGlobal.script;
	var layer,parent;
	layer = script.scriptArray.layerList[nameStr];
	if(!layer){
		script.analysis();
		return;
	}
	parent = layer.parent;
	ScriptLayer.removeFromArray(layer);
	parent.removeChild(layer);
	script.scriptArray.layerList[nameStr] = null;
	script.analysis();
}

移除显示层比清空显示层多了一步,就是将自己移除。下面来测试一下清空和移除操作。修改脚本如下

Layer.add(-,layer01,100,100);
Layer.add(-,layer02,150,150);
Layer.add(-,layer03,200,200);
Load.img(backdata,lufy_legend.jpg);
Img.add(layer01,backimg01,backdata,0,0,100,100,1);
Img.add(layer02,backimg02,backdata,0,0,100,100,1);
Img.add(layer03,backimg03,backdata,0,0,100,100,1);

测试连接

http://lufylegend.com/demo/test/lsharp/05/index02.html

运行脚本,得到下面效果


可以看到,显示层的清空和移除已经成功执行了。

二,绘制矩形,圆角矩形和三角形

下面来说一说如何使用脚本来绘制图形,从简单的矩形开始。

绘制一个实心矩形和空心矩形框的脚本如下,如下

Layer.drawRect(layer02,0,0,100,100,0xff0000);
Layer.drawRectLine(layer02,0,0,100,100,0xff0000,2);

几个参数分别为:显示层,起始坐标x,起始坐标y,宽,高,颜色。

如果是绘制矩形框,则多一个参数,用来设置线宽。

先修改ScriptLayer类的解析函数

ScriptLayer.analysis = function (value){
	var start = value.indexOf("(");
	var end = value.indexOf(")");
	switch(value.substr(0,start)){
		case "Layer.add"://添加显示层
			ScriptLayer.setLayer(value,start,end);
			break;
		case "Layer.remove"://移除显示层
			ScriptLayer.removeLayer(value,start,end);
			break;
		case "Layer.clear"://清空显示层
			ScriptLayer.clearLayer(value,start,end);
			break;
		case "Layer.drawRect"://绘制实心矩形
			ScriptLayer.drawRect(value,start,end);
			break;
		case "Layer.drawRectLine"://绘制空心矩形框
			ScriptLayer.drawRectLine(value,start,end);
			break;
		default:
	}
};

下面看drawRect函数和drawRectLine函数的代码。

ScriptLayer.drawRect = function (value,start,end){
	var params = value.substring(start+1,end).split(",");
	var nameStr = params[0];
	var color = params[5];
	color = color.replace("0x","#");
	var script = LGlobal.script;
	var layer = script.scriptArray.layerList[nameStr];
	layer.graphics.drawRect(1,color,[parseInt(params[1]),parseInt(params[2]),parseInt(params[3]),parseInt(params[4])],true,color);
	script.analysis();
};
ScriptLayer.drawRectLine = function (value,start,end){
	var params = value.substring(start+1,end).split(",");
	var nameStr = params[0];
	var color = params[5];
	color = color.replace("0x","#");
	var num = 1;
	if(params.length > 6)num = parseFloat(params[6]);
	var script = LGlobal.script;
	var layer = script.scriptArray.layerList[nameStr];
	layer.graphics.drawRect(num,color,[parseInt(params[1]),parseInt(params[2]),parseInt(params[3]),parseInt(params[4])]);
	script.analysis();
};

原理很简单,先用分号分割得到参数,根据显示层的名称取得相应的显示层,然后使用LGraphics的绘图函数在显示层上进行绘图

绘制圆角矩形和三角形跟上面的原理是一样的,都是使用LGraphics的相应的绘图函数,具体实现如下

ScriptLayer.analysis = function (value){
	var start = value.indexOf("(");
	var end = value.indexOf(")");
	switch(value.substr(0,start)){
		case "Layer.add"://添加显示层
			ScriptLayer.setLayer(value,start,end);
			break;
		case "Layer.remove"://移除显示层
			ScriptLayer.removeLayer(value,start,end);
			break;
		case "Layer.clear"://清空显示层
			ScriptLayer.clearLayer(value,start,end);
			break;
		case "Layer.drawRect"://绘制实心矩形
			ScriptLayer.drawRect(value,start,end);
			break;
		case "Layer.drawRectLine"://绘制空心矩形框
			ScriptLayer.drawRectLine(value,start,end);
			break;
		case "Layer.drawRoundRect"://绘制实心圆角矩形
			ScriptLayer.drawRoundRect(value,start,end);
			break;
		case "Layer.drawRoundRectLine"://绘制空心圆角矩形框
			ScriptLayer.drawRoundRectLine(value,start,end);
			break;
		case "Layer.drawTriangle"://绘制实心三角形
			ScriptLayer.drawTriangle(value,start,end);
			break;
		case "Layer.drawTriangleLine"://绘制空心三角形框
			ScriptLayer.drawTriangleLine(value,start,end);
			break;
		default:
	}
};
ScriptLayer.drawRoundRect = function (value,start,end){
	var params = value.substring(start+1,end).split(",");
	var nameStr = params[0];
	var color = params[6];
	color = color.replace("0x","#");
	var script = LGlobal.script;
	var layer = script.scriptArray.layerList[nameStr];
	layer.graphics.drawRoundRect(1,color,[parseInt(params[1]),parseInt(params[2]),parseInt(params[3]),parseInt(params[4]),parseInt(params[5])],true,color);
	script.analysis();
};
ScriptLayer.drawRoundRectLine = function (value,start,end){
	var params = value.substring(start+1,end).split(",");
	var nameStr = params[0];
	var color = params[6];
	color = color.replace("0x","#");
	var num = 1;
	if(params.length > 7)num = parseFloat(params[7]);
	var script = LGlobal.script;
	var layer = script.scriptArray.layerList[nameStr];
	layer.graphics.drawRoundRect(num,color,[parseInt(params[1]),parseInt(params[2]),parseInt(params[3]),parseInt(params[4]),parseInt(params[5])]);
	script.analysis();
};
ScriptLayer.drawTriangle = function (value,start,end){
	var params = value.substring(start+1,end).split(",");
	var nameStr = params[0];
	var color = params[7];
	color = color.replace("0x","#");
	var script = LGlobal.script;
	var layer = script.scriptArray.layerList[nameStr];
	layer.graphics.drawVertices(1,color,[[parseInt(params[1]),parseInt(params[2])],[parseInt(params[3]),parseInt(params[4])],[parseInt(params[5]),parseInt(params[6])]],true,color);
	script.analysis();
};
ScriptLayer.drawTriangleLine = function (value,start,end){
	var params = value.substring(start+1,end).split(",");
	var nameStr = params[0];
	var color = params[7];
	color = color.replace("0x","#");
	var num = 1;
	if(params.length > 8)num = parseFloat(params[8]);
	var script = LGlobal.script;
	var layer = script.scriptArray.layerList[nameStr];
	layer.graphics.drawVertices(num,color,[[parseInt(params[1]),parseInt(params[2])],[parseInt(params[3]),parseInt(params[4])],[parseInt(params[5]),parseInt(params[6])]]);
	script.analysis();
};

另外,绘制圆或者多边形等都是一样的,以后我会直接添加到里面,这里就不赘述了,有兴趣的话可以自己先实现一下。

下面来测试一下这几个脚本,修改脚本文件如下

Layer.add(-,layer01,0,0);
Layer.drawRect(layer01,0,0,100,60,0xff0000);
Layer.drawRectLine(layer01,0,100,100,60,0xff0000,5);
Layer.drawRoundRect(layer01,150,0,100,60,10,0x880000);
Layer.drawRoundRectLine(layer01,150,100,100,60,10,0x880000,5);
Layer.drawTriangle(layer01,350,0,300,60,400,60,0xff0000);
Layer.drawTriangleLine(layer01,350,100,300,160,400,160,0xff0000,5);
测试一下,得到效果如下

下面是测试连接

http://lufylegend.com/demo/test/lsharp/05/index03.html

三,对显示层进行缓动变换

这里的缓动和图片缓动基本是一样的,不同的是,图片的缓动针对的是单一图片,而这里的缓动是针对整个显示层来进行缓动。

Layer.transition(layer03,{x:50},1,Strong.easeOut); 

各参数和上一节中的图片缓动是一致的,不再赘述了。

看一下具体实现方法。

ScriptLayer.transition = function (value,start,end){
	var script = LGlobal.script;
	
	var lArr = value.substring(start+1,end).split(",");
	var nameStr = lArr[0];
	//将json对象还原
	var toObj = eval('(' + lArr[1] + ')');
	//获取缓动时间
	var time = parseFloat(lArr[2]);
	var eases = lArr[3].split(".");
	var runNow = false;
	//是否立即执行下一行脚本
	if(lArr.length > 4){
		runNow = (lArr[4] == "1");
	}
	toObj["ease"] = LEasing[eases[0]][eases[1]];
	if(!runNow){
		toObj["onComplete"] = function(){
			script.analysis();
		};
	}
	LTweenLite.to(script.scriptArray.layerList[nameStr],time,toObj);  
	//如果runNow为1,则立即执行下一行脚本
	if(runNow)script.analysis();
};

最后,来测试一下,修改Main.ls脚本文件如下

/*
游戏脚本的设计与开发 第五章
*/
Layer.add(-,layer01,100,20);
Layer.add(-,layer02,150,100);
Layer.add(-,layer03,250,250);
Load.img(backdata,lufy_legend.jpg);
Img.add(layer01,backimg01,backdata,0,0,100,100,1);
Layer.drawRectLine(layer02,0,0,100,100,0xff0000);
Layer.clear(layer01);
Layer.drawRoundRectLine(layer01,0,0,100,100,10,0x880000);
Layer.drawTriangle(layer03,0,0,100,100,50,150,0xff0000);
Layer.drawRect(layer03,100,0,100,60,0xff0000);
Layer.drawRoundRect(layer03,150,70,100,60,10,0x880000);
Layer.transition(layer03,{x:50},1,Strong.easeOut);
Layer.drawTriangleLine(layer03,0,0,100,100,50,0,0xff0000);

运行程序得到效果

测试连接如下

http://lufylegend.com/demo/test/lsharp/05/index.html

以上是本章的素有内容,下一章来讲一下按钮,脚本的暂停与查找等功能


本章为止的lufylegend.lsharp.js源码如下

http://lufylegend.com/demo/test/lsharp/05/lufylegend.lsharp.js

《游戏脚本的设计与开发》系列文章目录

http://blog.csdn.net/lufy_legend/article/details/8888787



本章就讲到这里,欢迎继续关注我的博客

转载请注明:转自lufy_legend的博客http://blog.csdn.net/lufy_legend

分享到:
评论

相关推荐

    Cocos2D-X游戏开发技术精解

    第5章 用户交互 147 5.1 概述 147 5.2 玩家交互信息 149 5.3 触摸操作的处理机制 149 5.4 接收操作 153 5.5 分发机制 154 5.6 处理响应 157 5.7 多点触碰 159 5.8 加速计的响应函数 161 5.9 本章小结 162 第6章 游戏...

    ASPNET35开发大全第一章

    第5章 Web窗体的基本控件 5.1 控件的属性 5.2 简单控件 5.2.1 标签控件(Label) 5.2.2 超链接控件(HyperLink) 5.2.3 图像控件(Image) 5.3 文本框控件(TextBox) 5.3.1 文本框控件的属性 5.3.2 文本框控件的...

    Jsp通用范例开发金典光盘源代码

     第5章JSP与JavaScript  第6章JSP与JavaBean 第7章数据库连接  第8章数据库操作  第9章JSP与文件操作 第10章JSP与图像 第11章邮件处理专题  第12章JSP与XML 第13章报表与打印 第14章JSP与Servlet  ...

    ActionScript 3.0 开发人员指南 (AS3开发帮助文档)

    第 5 章 : 使用正则表达式 第 6 章 : 使用 XML 第 7 章 : 使用本机 JSON 功能 第 8 章 : 处理事件 第 9 章 : 使用应用程序域 第 10 章 : 显示编程 第 11 章 : 使用几何结构 第 12 章 : 使用绘图 API 第 13 ...

    ASP.NET 3.5 开发大全1-5

    第5章 Web窗体的基本控件 5.1 控件的属性 5.2 简单控件 5.2.1 标签控件(Label) 5.2.2 超链接控件(HyperLink) 5.2.3 图像控件(Image) 5.3 文本框控件(TextBox) 5.3.1 文本框控件的属性 5.3.2 文本框控件的...

    ASP.NET 3.5 开发大全11-15

    第5章 Web窗体的基本控件 5.1 控件的属性 5.2 简单控件 5.2.1 标签控件(Label) 5.2.2 超链接控件(HyperLink) 5.2.3 图像控件(Image) 5.3 文本框控件(TextBox) 5.3.1 文本框控件的属性 5.3.2 文本框控件的...

    MFC Windows程序设计(第2版修订版)--源代码

     第5章 mfc集合数  第6章 文件i/o和串行化  第7章 控件  第8章 对话框和属性表 第ⅱ部分 文档/视图体系结构  第9章 文档、视图和单文档界面  第10章 滚动视图、html视图以及其他视图类型  第11章 多文档和多...

    PHP和MySQL Web开发第4版pdf以及源码

    第5章 代码重用与函数编写 5.1 代码重用的好处 5.1.1 成本 5.1.2 可靠性 5.1.3 一致性 5.2 使用require()和include()函数 5.2.1 文件扩展名和require()语句 5.2.2 使用require()制作Web站点的模版 5.2.3 ...

    网页与Web程序设计 课件 ppt 机械工业出版社 part1

    各章节的具体编写分工是:第1、2章由熊建强编写,第3、4章由宋麟编写,第5、8章由黄磊编写,第6、11章由周畅和汤建琴编写,第7、10章由杨鏖丞编写,第9、12、13章由吴黎兵和熊卿编写,第14、15章由余艳霞编写。...

    PHP和MySQL WEB开发(第4版)

    第5章 代码重用与函数编写 5.1 代码重用的好处 5.1.1 成本 5.1.2 可靠性 5.1.3 一致性 5.2 使用require()和include()函数 5.2.1 文件扩展名和require()语句 5.2.2 使用require()制作Web站点的模版 5.2.3 使用auto_...

    精通Qt4编程 pdf 中文版 part2

    第5章 布局管理 5.1 Qt布局管理器——QLayout 5.2 分裂器部件Qsplitter 5.3 栈部件Qstackedwidget 5.4 工作空间部件QWorkspace 5.5 多文档区部件QMdiArea 5.6 小结 中级篇 第6章 2D绘图 第7章 拖放操作和剪贴机 第8...

    精通Qt4编程 pdf 中文版 part3

    第5章 布局管理 5.1 Qt布局管理器——QLayout 5.2 分裂器部件Qsplitter 5.3 栈部件Qstackedwidget 5.4 工作空间部件QWorkspace 5.5 多文档区部件QMdiArea 5.6 小结 中级篇 第6章 2D绘图 第7章 拖放操作和剪贴机 第8...

    精通Qt4编程 pdf 中文版 part1

    第5章 布局管理 5.1 Qt布局管理器——QLayout 5.2 分裂器部件Qsplitter 5.3 栈部件Qstackedwidget 5.4 工作空间部件QWorkspace 5.5 多文档区部件QMdiArea 5.6 小结 中级篇 第6章 2D绘图 第7章 拖放操作和剪贴机 第8...

    vc++ 开发实例源码包

    内含各种例子(vc下各种控件的使用方法、标题栏与菜单栏、工具栏与状态栏、图标与光标、程序窗口、程序控制、进程与线程、字符串、文件读写操作、文件与文件夹属性操作、文件与文件夹系统操作、系统控制操作、程序...

    MFC Windows程序设计(第2版修订版)--详细书签版1卷

     第5章 mfc集合数  第6章 文件i/o和串行化  第7章 控件  第8章 对话框和属性表 第ⅱ部分 文档/视图体系结构  第9章 文档、视图和单文档界面  第10章 滚动视图、html视图以及其他视图类型  第11章 多文档和多...

    MFC Windows程序设计(第2版修订版)--详细书签版2卷

     第5章 mfc集合数  第6章 文件i/o和串行化  第7章 控件  第8章 对话框和属性表 第ⅱ部分 文档/视图体系结构  第9章 文档、视图和单文档界面  第10章 滚动视图、html视图以及其他视图类型  第11章 多文档和多...

    简单的 t-sne 绘图仪:这是用于绘制 2 维和 3 维 t 分布随机邻域嵌入 (t-SNE) 的 Matlab 脚本。-matlab开发

    标签的排列-第一栏应为“标签名称”,其顺序应与四、 数据的标签名称。 3. Data 和 Label 中的每一行都是一个样本。 4. 用相同的名称替换文件夹输入目录中的数据和标签。 5. 运行脚本 tsne_exampl

Global site tag (gtag.js) - Google Analytics