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

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

 

/*

游戏脚本的设计与开发 第五章

*/

//添加显示层

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

 

你可能感兴趣的:(脚本)