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

《游戏脚本的设计与开发》-第六章 按钮,脚本的暂停和标签

 
阅读更多

按钮

按钮在任何程序中都是必不可少的,本次先来看看如何脚本来实现按钮的各种功能。文章中要实现的几个脚本如下。

/*
游戏脚本的设计与开发 第六章
*/
//添加按钮
Button.add(layer01,button01,null,50,50,ok_button_up,ok_button_over,null);
function function_test01();
	//移除按钮
	Button.remove(button01);
endfunction;
//移除显示层
Layer.remove(layer01);
//给按钮添加点击事件
Button.mousedown(button01,function_test01);

下面是ScriptButton类的完整代码,用来实现上述脚本的解析

/*
* ScriptButton.js
**/
var ScriptButton = function (){};
ScriptButton.analysis = function (value){
	var start = value.indexOf("(");
	var end = value.indexOf(")");
	switch(value.substr(0,start)){
		case "Button.add"://添加按钮
			ScriptButton.addButton(value,start,end);
			break;
		case "Button.remove"://删除按钮
			ScriptButton.removeButton(value,start,end);
			break;
		case "Button.mousedown"://鼠标按下事件
			ScriptButton.mouseevent(value,start,end,LMouseEvent.MOUSE_DOWN);
			break;
		case "Button.mouseup"://鼠标弹起事件
			ScriptButton.mouseevent(value,start,end,LMouseEvent.MOUSE_UP);
			break;
		case "Button.mousemove"://鼠标移动事件
			ScriptButton.mouseevent(value,start,end,LMouseEvent.MOUSE_MOVE);
			break;
		default:
			LGlobal.script.analysis();
			
	}
};
/**
添加按钮脚本解析
Button.add(layer01,button01,null,50,50,ok_button_up,ok_button_over,null);
*/
ScriptButton.addButton = function (value,start,end){
	var script = LGlobal.script;
	var layer;
	//获取参数
	var lArr = value.substring(start+1,end).split(",");
	var layerStr = lArr[0];//显示层名称
	var nameStr = lArr[1];//按钮名称
	var labelStr = lArr[2];//按钮上的文字,如果设置为null,则不显示文字
	var x = parseInt(lArr[3]);//按钮坐标
	var y = parseInt(lArr[4]);//按钮坐标
	var dataUp = lArr[5];//按钮弹起样式的bitmapData对象名称
	var dataOver = lArr[6];//按钮点击后样式的bitmapData对象名称
	//获取按钮弹起和按下的样式的bitmapData对象
	var upimg = script.scriptArray.bitmapdataList[dataUp];
	var overimg = script.scriptArray.bitmapdataList[dataOver];
	//按钮弹起状态LSprite
	var upLayer = new LSprite();
	upLayer.addChild(new LBitmap(upimg));
	//按钮按下状态LSprite
	var overLayer = new LSprite();
	overLayer.addChild(new LBitmap(overimg));
	//如果设置了按钮文字,则开始在按钮上添加一个LTextField对象来显示文字
	if(labelStr && labelStr != "null"){
		var upText = new LTextField();
		upText.text = labelStr;
		upText.size = upimg.height * 0.5;
		upText.x = (upimg.width - upText.getWidth())*0.5;
		upText.y = upimg.height * 0.2;
		upLayer.addChild(upText);
		var overText = new LTextField();
		overText.text = labelStr;
		overText.size = upimg.height * 0.5;
		overText.x = (upimg.width - upText.getWidth())*0.5+2;
		overText.y = upimg.height * 0.2+2;
		overLayer.addChild(overText);
		//按钮的文字颜色
		if(lArr.length > 7){
			upText.color = lArr[7];
			overText.color = lArr[7];
		}
	}
	//利用按钮的两个状态,新建一个LButton按钮对象
	var btn = new LButton(upLayer,overLayer);
	btn.x = x;
	btn.y = y;
	//得到显示层
	layer = script.scriptArray.layerList[layerStr];
	//保存按钮
	script.scriptArray.btnList[nameStr] = btn;
	btn.name = nameStr;
	//将按钮添加到显示层
	layer.addChild(btn);
	script.analysis();
};
/**
删除按钮脚本解析
Button.remove(button01);
*/
ScriptButton.removeButton = function(value,start,end){
	//获取参数
	var lArr = value.substring(start+1,end).split(",");
	var nameStr = lArr[0];//按钮名称
	var script = LGlobal.script;
	//获取按钮
	var btn = script.scriptArray.btnList[nameStr];
	//如果按钮不存在,则解析下一行脚本
	if(btn == null){
		script.scriptArray.btnList[nameStr] = null;
		script.analysis();
		return;
	}
	//移除按钮
	btn.parent.removeChild(btn);
	script.scriptArray.btnList[nameStr] = null;
	script.analysis();
};
/**
按钮事件脚本解析
Button.mousedown(button01,function_test01);
*/
ScriptButton.mouseevent = function (value,start,end,e){
	var script = LGlobal.script;
	//获取参数
	var lArr = value.substring(start+1,end).split(",");
	var nameStr = lArr[0];//按钮名称
	var funStr = lArr[1];//函数名称
	//获取按钮
	var btn = script.scriptArray.btnList[nameStr];
	//添加匿名函数,然后匿名函数中利用Call脚本类来调用相应的函数
	var fun = function(event){
		ScriptFunction.analysis("Call." + funStr + "();");
	};
	//为按钮添加事件
	btn.addEventListener(e,fun);
	script.analysis();
};

我在上面的代码中添加了非常详细的代码,基本上不用我再多解释什么了,下面来看看这些脚本的使用,修改Main.ls如下。

Layer.add(-,layer01,100,100);
Layer.add(-,layer02,20,50);
Text.label(layer02,txt01,点击下面按钮,被点击按钮就会消失,0,0,30,#000000);
Load.img(ok_button_over,ok_button_over.png);
Load.img(ok_button_up,ok_button_up.png);
//添加按钮
Button.add(layer01,button01,null,50,50,ok_button_up,ok_button_over);
Button.add(layer01,button02,测试1,150,50,ok_button_up,ok_button_over,#880000);
Button.add(layer01,button03,测试2,250,50,ok_button_up,ok_button_over,#008800);
//声明函数,以备按钮事件使用
function function_test01();
	//移除按钮
	Button.remove(button01);
endfunction;
function function_test02();
	Button.remove(button02);
endfunction;
function function_test03();
	Button.remove(button03);
endfunction;
//给按钮添加点击事件
Button.mousedown(button01,function_test01);
Button.mousedown(button02,function_test02);
Button.mousedown(button03,function_test03);

测试连接

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

上面的测试中,我利用脚本添加了三个按钮,并且给这三个按钮分别添加了点击事件,点击按钮后,被点击的按钮就会被移除。

脚本暂停

在游戏脚本运行过程中,如果脚本没有暂停功能,不间断的进行解析,那么就完全不受控制了,脚本什么时候运行结束了,整个程序也就结束了。这显然是不符合我们的意愿的,而且在游戏中,也尝尝会遇到一种情况,就是点击鼠标后才继续进行下面程序,这就要用到脚本暂停了,就是脚本执行到某一行后暂停解析,等待用户的命令,然后才进行下一行的脚本解析。

下面尝试定义的脚本,如下

//暂停1秒
Wait.time(1000);
//等待点击
Wait.click();
//等待运行控制脚本的执行
Wait.ctrl();
//结束Wait.ctrl,继续进行解析
Wait.play();

下面是完整的ScriptWait.js类,用来解析暂停脚本相关的各种操作。

/*
* ScriptWait.js
**/
var ScriptWait = function (){};
ScriptWait.analysis = function (value){
	var start = value.indexOf("(");
	var end = value.indexOf(")");
	switch(value.substr(0,start)){
		case "Wait.click"://暂停,等待点击鼠标
			ScriptWait.waitclick();
			break;
		case "Wait.ctrl"://暂停,等待运行脚本
			 if(int(value.substring(start + 1,end)) > 0)LGlobal.script.lineList.unshift("Wait.ctrl()");
			break;
		case "Wait.play"://脚本继续运行
			LGlobal.script.analysis();
			break;
		case "Wait.time"://脚本暂停一段时间
			ScriptWait.timeId = setTimeout(function(){
				ScriptWait.timeId = null;
				LGlobal.script.analysis();
			}, 1000);
			break;
		case "Wait.clickOver"://结束等待点击脚本(Wait.click)
			LGlobal.script.scriptLayer.removeEventListener(LMouseEvent.MOUSE_UP,ScriptWait.clickEvent);
			LGlobal.script.analysis();
			break;
		case "Wait.timeOver"://结束时间暂停脚本(Wait.time)
			ScriptWait.timeOver();
			break;
		case "Wait.Over"://结束所有暂停脚本
			LGlobal.script.scriptLayer.removeEventListener(LMouseEvent.MOUSE_UP,ScriptWait.clickEvent);
			ScriptWait.timeOver();
			break;
		default:
			LGlobal.script.analysis();
	}
};
/*
* 结束时间暂停脚本(Wait.time)
**/
ScriptWait.timeOver = function (){
	if(ScriptWait.timeId){
		clearTimeout(ScriptWait.timeId);
		ScriptWait.timeId = null;
	}
	LGlobal.script.analysis();
};
/*
* 暂停,等待点击鼠标
**/
ScriptWait.waitclick = function (){
	var layer = LGlobal.script.scriptLayer;
	//添加一个鼠标点击事件,当鼠标点击屏幕的时候,调用clickEvent函数,开始运行脚本
	layer.addEventListener(LMouseEvent.MOUSE_UP,ScriptWait.clickEvent);
};
/*
* 鼠标点击运行脚本
**/
ScriptWait.clickEvent = function (event){
	LGlobal.script.scriptLayer.removeEventListener(LMouseEvent.MOUSE_UP,ScriptWait.clickEvent);
	LGlobal.script.analysis();
};

上面的代码同样加了详细的注释,下面来测试一下这几个脚本,修改脚本文件如下

Layer.add(-,layer01,20,20);
Text.label(layer01,txt01,暂停测试,请等待一秒钟,0,0,20,#000000);
Wait.time(1000);
Text.label(layer01,txt01,一秒钟结束,请点击一下屏幕,0,30,20,#000000);
Wait.click();
Text.label(layer01,txt01,你点击了屏幕,脚本继续,0,60,20,#000000);
Load.img(ok_button_over,ok_button_over.png);
Load.img(ok_button_up,ok_button_up.png);
Button.add(layer01,button01,null,50,200,ok_button_up,ok_button_over);
function function_test01();
	Wait.play();
endfunction;
Button.mousedown(button01,function_test01);
Text.label(layer01,txt01,脚本暂停,你可以点击OK按钮来继续解析脚本,0,90,20,#000000);
Wait.ctrl();
Button.remove(button01);
Text.label(layer01,txt01,脚本结束,0,120,20,#000000);

测试连接如下

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

可以看到,上述的各种脚本,都在程序中正常运行了。

标签

标签功能,类似于某些程序中的go语句,就是直接跳到某个代码的位置,然后开始继续执行,下面我依然在脚本中实现以下这个功能,先来定义两个脚本,如下。

//设置标签
Mark.drawRoundRect;
//跳到drawRoundRect标签位置
Mark.goto(drawRoundRect);

在脚本解析的时候,遇到不认识的脚本,会自动跳过,所以设置标签的时候,不需要任何处理,直接跳过即可,下面看一下ScriptMark.js类中如何来具体实现标签的寻找。

/*
* ScriptMark.js
**/
var ScriptMark = function (){};
ScriptMark.analysis = function (value){
	var start = value.indexOf("(");
	var end = value.indexOf(")");
	switch(value.substr(0,start)){
		case "Mark.goto"://跳至标签位置
			ScriptMark.goto(value,start,end);
			break;
		default:
			LGlobal.script.analysis();
	}
};
ScriptMark.goto = function (value,start,end){
	var mark = LMath.trim(value.substring(start+1,end));
	//copyList是当前正在解析的脚本序列的副本,再复制一个脚本序列的副本
	var copyArray = LGlobal.script.copyList.concat();
	var foundStr;
	while(copyArray.length){
		//从复制的脚本序列中开始查找标签,没查找一行,则将其删除
		foundStr = copyArray.shift();
		if(foundStr.indexOf("Mark."+mark) >= 0){
			//如果找到标签,则将当前正在解析的脚本序列替换为复制序列
			LGlobal.script.lineList = copyArray;
			LGlobal.script.analysis();
			return;
		}
	}
	//如果没有找到标签,则什么都不做,进行下一行脚本的解析
	LGlobal.script.analysis();
};

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

Layer.add(-,layer01,0,0);
//跳到标签drawTriangle
Mark.goto(drawTriangle);
//绘制矩形
Layer.drawRect(layer01,0,0,100,60,0xff0000);
Layer.drawRectLine(layer01,0,100,100,60,0xff0000,5);
//设置drawRoundRect标签
Mark.drawRoundRect;
//绘制圆角矩形
Layer.drawRoundRect(layer01,150,0,100,60,10,0x880000);
Layer.drawRoundRectLine(layer01,150,100,100,60,10,0x880000,5);
//跳到标签over
Mark.goto(over);
//设置drawTriangle标签
Mark.drawTriangle;
//绘制三角形
Layer.drawTriangle(layer01,350,0,300,60,400,60,0xff0000);
Layer.drawTriangleLine(layer01,350,100,300,160,400,160,0xff0000,5);
//跳到标签drawRoundRect
Mark.goto(drawRoundRect);
//设置over标签
Mark.over;

解释一下上面的脚本,如果没有这些标签操作的话,脚本按照顺序执行,会绘制两个矩形,两个圆角矩形和两个三角形,但是脚本一开始就遇到了跳到标签,跳转到了drawTriangle,开始绘制三角形,绘制完三角形,又跳转到了drawRoundRect标签,开始绘制圆角矩形,绘制完圆角矩形后,又直接跳转到了over标签,从而脚本结束,所以,最初的两个矩形最终没有绘制出来。

测试连接如下

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

这个是运行效果

以上是本章的素有内容,下一章来扩展一下文字脚本,实现打字机效果文字显示,然后脚本引擎的第一部分算是讲的差不多了,会试着用这些脚本做个小游戏给大家看看。


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

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

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

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



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

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

分享到:
评论

相关推荐

    vc++ 开发实例源码包

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

    Visual C++ 数据库系统开发完全手册.part2

    第6章 MFC原理及方法 6.1 MFC概述 6.2 Windows编程思想 6.2.1 Windows API 6.2.2 事件驱动程序 6.2.3 消息概述 6.3 MFC微软类库 6.3.1 MFC发展历史 6.3.2 MFC应用程序的生与死 6.3.3 常用MFC文件及库文件 6.4 常用的...

    Visual C++ 数据库系统开发完全手册.part1

    第6章 MFC原理及方法 6.1 MFC概述 6.2 Windows编程思想 6.2.1 Windows API 6.2.2 事件驱动程序 6.2.3 消息概述 6.3 MFC微软类库 6.3.1 MFC发展历史 6.3.2 MFC应用程序的生与死 6.3.3 常用MFC文件及库文件 6.4 常用的...

    Java开发技术大全 电子版

    第6章Java的异常处理220 6.1异常的基本概念和作用220 6.2Java的异常处理机制221 6.3异常类的层次结构222 6.3.1运行时异常222 6.3.2检查型异常223 6.3.3自定义异常224 6.4捕获和处理异常224 6.5抛出异常228 ...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    第六章 认我测在线检测服务系统实现与测试 33 6.1认我测在线检测服务框架设计 33 6.2 系统运行环境搭建及配置 34 6.2.1 AndroidManifest.xml主程序环境配置 34 6.2.2 移动端工程资源布局 35 6.3 认我测在线认证检测...

    AUTOIT生成自动安装的工具

    7.模式切换分为控件模式和鼠标位置模式,切换快捷键和暂停捕捉快捷键均可自定义设置 8.可自定义是否在控件点击时左上角提示相关信息 9.可自定义运行脚本是否需要托盘提示目前代码行数和对应代码 10.其他功能(打包、...

    flex3的cookbook书籍完整版dpf(包含目录)

    第六章. DataGrid和高级DataGrid(179) 6.1节. 创建DataGrid自定义列 6.2节. 为DataGrid列设定排序函数 6.3节. 启动DataGrid多列排序 6.4节. 过滤DataGrid数据项 6.5节. 为AdvancedDataGrid创建自定义表头 6.6节. ...

    GTM声纳「GTM Sonar」-crx插件

    调试您的页面模板,查看它是否适用于Google跟踪代码管理器的自动事件侦听器。 GTM Sonar可用于调试页面模板及其与Google Tag ... - 再次单击浏览器动作,删除由该扩展插入的所有脚本和事件处理程序 支持语言:English

    入门学习Linux常用必会60个命令实例详解doc/txt

    这是因为Linux和许多版本的Unix一样,提供了虚拟控制台的访问方式,允许用户在同一时间从控制台(系统的控制台是与系统直接相连的监视器和键盘)进行多次登录。每个虚拟控制台可以看作是一个独立的工作站,工作台...

    文章管理系统

    1.[新增]前台会员投稿和后台文章编辑 新增重复性标题检查按钮和本地获取关键词 2.[新增]新增本地关键词库(位置:inc/keyWord.txt),可以根据自己需求往里面编辑需要的关键词 3.[新增]前台 文章管理 新增查询栏 4....

    网管教程 从入门到精通软件篇.txt

    、Lipper、FoxPro、Arago、Wordtech、Xbase和类似数据库或与数据库有关产品识别;可用数据文件(能被Excel 97打开);Oracle 8.1.x表格空间文件 DBX:DataBearn图像;Microsoft Visual FoxPro表格文件 DCT:...

    易语言 茶凉专用模块

    参数 状态, 整数型, 可空, 可空:按键(按下+放开) 1 #按键_ 3 #按下_ 4 #放开_ 如果状态大于等于5则为按下与放开之间的延时,可解决某些屏蔽 .参数 功能键方式, 逻辑型, 可空, 默认为普通键, 真:功能键方式模拟,如ctrl...

    StrongOD v0.2.6

    分别对应二进制复制,二进制粘贴,无空格二进制复制(方便写OD脚本的兄弟),复制选中的第一个字节的地址 注:Shift+V 只需要选中起始地址即可. Shift+C与Shift+X的区别如下: 55 8B EC 8B 45 0C 48 74 42 48 74 37 83 ...

Global site tag (gtag.js) - Google Analytics