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

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

 
阅读更多

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

/*
游戏脚本的设计与开发 第五章
*/
//添加显示层
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游戏开发技术精解

    12.6.2 游戏内容的实现脚本 333 12.6.3 农场层的实现 334 12.6.4 菜单层的实现 337 12.7 本章小结 338 第13章 Cocos2D-HTML5引擎版本 340 13.1 概述 340 13.2 HTML的发展史 341 13.2.1 HTML版本 341 13.2.2 XHTML...

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

    全书分为16章,内容包括HTML语句的基本语法,JSP指令与动作,JSP内部对象,JavaScript脚本在JSP编程中的使用,JavaBean在JSP中的基本概念及其属性与方法,数据库的连接方式,绘图方法,实现邮件的收发功能,打印Word...

    ASP.NET 3.5 开发大全11-15

    1.5 ASP.NET应用程序基础 1.5.1 创建ASP.NET应用程序 1.5.2 运行ASP.NET应用程序 1.5.3 编译ASP.NET应用程序 1.6 小结 第2章 C# 3.0程序设计基础 2.1 C#程序 2.1.1 C#程序的结构 2.1.2 C# IDE的代码设置 2.2 变量 ...

    ASP.NET 3.5 开发大全1-5

    1.5 ASP.NET应用程序基础 1.5.1 创建ASP.NET应用程序 1.5.2 运行ASP.NET应用程序 1.5.3 编译ASP.NET应用程序 1.6 小结 第2章 C# 3.0程序设计基础 2.1 C#程序 2.1.1 C#程序的结构 2.1.2 C# IDE的代码设置 2.2 变量 ...

    java程序设计与开发课件

    1.5 Java开发环境概述···························· (4) 1.5.1 JDK的安装、配置和使用························ (4) 1.5.2 JDK工具箱············...

    用C语言开发手机软件 -Windows+CE+6.0开发者参考

    1.5 剖析窗口应用程序 1.5.1 窗口 1.5.2 窗口类 1.5.3 窗口过程 1.5.4 消息的生命期 1.5.5 注册窗口 1.5.6 创建窗口 1.5.7 消息循环 1.5.8 窗口过程 1.6 HelloCE 1.7 运行HelloCE 第2章 在屏幕上绘图 2.1 绘图基础 ...

    ASP.NET 3.5 开发大全

    1.5 ASP.NET应用程序基础 1.5.1 创建ASP.NET应用程序 1.5.2 运行ASP.NET应用程序 1.5.3 编译ASP.NET应用程序 1.6 小结 第2章 C# 3.0程序设计基础 2.1 C#程序 2.1.1 C#程序的结构 2.1.2 C# IDE的代码设置 2.2 变量 ...

    C++Builder 6.0设计师之路 pdf版

    通过本书的学习,读者可以高效的利用c++ builder开发应用程序,能够理解关键操作的内部实现机制,有助于迅速利用c++ builder来实现大量的编程任务,成为一个成功的设计师。 本书适用于大中专院校学生、程序设计人员...

    ASPNET35开发大全第一章

    ASPNET35开发大全非常好 书名:ASP.NET 3.5 开发大全 署名:郭靖 页数:722 这是我见过的一本非常好的教程 第一篇 .NET基础 第1章 认识ASP.NET 3.5 1.1 什么是ASP.NET 1.1.1 .NET历史与展望 1.1.2 ASP.NET与ASP ...

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

    《php和mysql web开发(原书第4版)》:开发人员专业技术丛书。 目录 读者反馈 译者序 前言 作者简介 第一篇 使用PHP 第1章 PHP快速入门教程 1.1 开始之前:了解PHP 1.2 创建一个示例应用:Bob汽车零部件商店 ...

    ASP.NET 3.5 开发大全word课件

    1.5 ASP.NET应用程序基础 1.5.1 创建ASP.NET应用程序 1.5.2 运行ASP.NET应用程序 1.5.3 编译ASP.NET应用程序 1.6 小结 第2章 C# 3.0程序设计基础 2.1 C#程序 2.1.1 C#程序的结构 2.1.2 C# IDE的代码设置 2.2 变量 ...

    PHP和MySQL WEB开发(第4版)

    1.5 访问表单变量 1.5.1 简短、中等以及长风格的表单变量 1.5.2 字符串的连接 1.5.3 变量和文本 1.6 理解标识符 1.7 检查变量类型 1.7.1 PHP的数据类型 1.7.2 类型强度 1.7.3 类型转换 1.7.4 可变变量 1.8 声明和...

    用C语言开发手机软件-Windows CE 6.0开发者参考

    1.5 剖析窗口应用程序 1.5.1 窗口 1.5.2 窗口类 1.5.3 窗口过程 1.5.4 消息的生命期 1.5.5 注册窗口 1.5.6 创建窗口 1.5.7 消息循环 1.5.8 窗口过程 1.6 HelloCE 1.7 运行HelloCE 第2章 在屏幕上绘图 2.1 绘图基础 ...

    PHP和MySQL Web开发第4版

    《php和mysql web开发(原书第4版)》:开发人员专业技术丛书。 目录 读者反馈 译者序 前言 作者简介 第一篇 使用PHP 第1章 PHP快速入门教程 1.1 开始之前:了解PHP 1.2 创建一个示例应用:Bob汽车零部件商店 ...

    ASP.NET3.5从入门到精通

    1.5 ASP.NET 应用程序基础 1.5.1 创建ASP.NET 应用程序 1.5.2 运行ASP.NET 应用程序 1.5.3 编译ASP.NET 应用程序 1.6 小结 第 2 章 C# 3.0 程序设计基础 2.1 C#程序 2.1.1 C#程序的结构 第一篇窗口与界面编程 7 ...

    Java核心技术II(第8版)

    1.5 对象流与序列化 1.5.1 理解对象序列化的文件格式 1.5.2 修改缺省的序列化机制 1.5.3 序列化单例和类型安全的枚举 1.5.4 版本管理 1.5.5 为克隆使用序列化 1.6 文件管理 1.7 新I/O 1.7.1 内存映射文件 1.7.2 缓冲...

Global site tag (gtag.js) - Google Analytics