博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何制作一款HTML5 RPG游戏引擎——第四篇,情景对话
阅读量:4984 次
发布时间:2019-06-12

本文共 8805 字,大约阅读时间需要 29 分钟。

今天我们来实现情景对话。这是一个重要的功能,没有它,游戏将变得索然无味。所以我们不得不来完成它。

但是要知道,使用对话可不是一件简单的事,因为它内部的东西很多,比如说人物头像,人物名称,对话内容。。。

因此我们只能通过数组+JSON来将对话信息装起来,然后根据信息作出不同的显示。接下来我便要向大家展示实现方法。

 

先看本系列文章目录:

如何制作一款HTML5 RPG游戏引擎——第一篇,地图类的实现

如何制作一款HTML5 RPG游戏引擎——第二篇,烟雨+飞雪效果

如何制作一款HTML5 RPG游戏引擎——第三篇,利用幕布切换场景

 

 

该引擎是基于lufylegend开发的,学习时请先了解lufylegend。

官方网站地址:

API地址:

1,实现后的代码

为了向大家展示封装的必要性,所以我们先看实现后的代码:

 

		
LTalk

这78行代码就可以实现进行5次对话的效果,先发两张截图,如下:

 

由此可见,本次封装还是很有作用的。

但是如何实现呢?请看接下来的讲解。

2,LTalk类

LTalk是一个对话类,构造器如下:

 

function LTalk(content){	var s = this;	base(s,LSprite,[]);	if(!content){		s.content = [];	}else{		s.content = content;	}	s.x = 0;	s.y = 0;	s.textWidth = LStage.width;	s.talkIndex = 0;	s.faceX = 0;	s.faceY = 0;	s.nameX = 0;	s.nameY = 0;	s.nameColor = "black";	s.nameFont = "宋体";	s.nameSize = "15";	s.msgX = 0;	s.msgY = 0;	s.msgColor = "black";	s.msgFont = "宋体";	s.msgSize = "15";}

其中,textWidth属性是为了设置文字区宽度的,设置后,如果文字过多而超出这个区域就会自动换行。talkIndex指对话编号。faceX,faceY指人物头像位置。nameX,nameY指人物名称的位置;nameColor,nameFont,nameSize分别用来设置名称颜色,字体,尺寸。msgX,msgY,msgColor,msgFont,msgSize同分别代表对话内容的x坐标,y坐标,颜色,字体,尺寸。

设定好刚才的那些属性后,就可以自定义对话样式了。

这个类构造时要传个参数,这个参数是对话内容。是一个数组套JSON的格式,如下:

 

[	{name:"名称",msg:"内容",face:头像图片},	{name:"名称",msg:"内容",face:头像图片},	{name:"名称",msg:"内容",face:头像图片},	{name:"名称",msg:"内容",face:头像图片},	{name:"名称",msg:"内容",face:头像图片},];

 

每往这个列表里加一条,就会多一段对话。

3,wind方法

接下来看看wind方法:

 

LTalk.prototype.wind = function(num,completeFunc){	var s = this;	if(!num || num == null)num = 0;	if(!completeFunc)completeFunc = null;	s.talkIndex = num;	s.removeAllChild();	if(s.talkIndex < s.content.length){		var talkObject = s.content[s.talkIndex];		var faceBitmapdata = new LBitmapData(talkObject.face);		var faceBitmap = new LBitmap(faceBitmapdata);		faceBitmap.x = s.faceX;		faceBitmap.y = s.faceY;		s.addChild(faceBitmap);		var name = new LTextField();		name.x = s.nameX;		name.y = s.nameY;		name.size = s.nameSize;		name.color = s.nameColor;		name.font = s.nameFont;		name.text = talkObject.name;		name.width = s.textWidth;		name.setWordWrap(true,name.getHeight()+5);		s.addChild(name);		var msg = new LTextField();		msg.x = s.msgX;		msg.y = s.msgY;		msg.size = s.msgSize;		msg.color = s.msgColor;		msg.font = s.msgFont;		msg.text = talkObject.msg;		msg.width = s.textWidth;		msg.setWordWrap(true,msg.getHeight()+7);		msg.wind(completeFunc);		s.addChild(msg);	}else{		trace("Error: Param exceeds the size of the content!");	}}

这个方法有两个参数,第一个是播放序号,第二个参数是输出完成后调用的函数。

 

首先我们判断一下参数num是不是没定义,如果是就自动设0,然后再判断第二个参数是否定义,如果没有,就设为null。这样做可以确保程序运行无误。接着,我们把控制播放序号的属性talkIndex设为num,然后清空一次,以便不和上次输出的重叠在一起。接着判断talkIndex有没有超出最大值,没有的话就执行输出命令。代码如下:

 

var talkObject = s.content[s.talkIndex];var faceBitmapdata = new LBitmapData(talkObject.face);var faceBitmap = new LBitmap(faceBitmapdata);faceBitmap.x = s.faceX;faceBitmap.y = s.faceY;s.addChild(faceBitmap);var name = new LTextField();name.x = s.nameX;name.y = s.nameY;name.size = s.nameSize;name.color = s.nameColor;name.font = s.nameFont;name.text = talkObject.name;name.width = s.textWidth;name.setWordWrap(true,name.getHeight()+5);s.addChild(name);var msg = new LTextField();msg.x = s.msgX;msg.y = s.msgY;msg.size = s.msgSize;msg.color = s.msgColor;msg.font = s.msgFont;msg.text = talkObject.msg;msg.width = s.textWidth;msg.setWordWrap(true,msg.getHeight()+7);msg.wind(completeFunc);s.addChild(msg);

熟悉lufylegend的朋友不难理解这些,就是将名称,内容,头像全部加到界面上。显示内容为构造器参数中对应的内容。

wind做好后,大家想让文本逐字显示时只用写一行obj.wind();就行了。

 

4,更改样式&手动清空对话&重设数据

刚才我们看了控制文字,图片样式的几个属性,有很多,如果一个一个用手改就会很麻烦,而且要写很多行代码,因此我们加几个控制样式的方法,它们分别是:setFaceStyle,setNameStyle,setMsgStyle。运用时只用传入参数就行了。

实现方法如下:

 

LTalk.prototype.setFaceStyle = function(styleData){	var s = this;	if(!styleData.x){s.faceX = 0;}else{s.faceX = styleData.x;}	if(!styleData.y){s.faceY = 0;}else{s.faceY = styleData.y;}}LTalk.prototype.setNameStyle = function(styleData){	var s = this;	if(!styleData.x){s.nameX = 0;}else{s.nameX = styleData.x;}	if(!styleData.y){s.nameY = 0;}else{s.nameY = styleData.y;}	if(!styleData.color){s.nameColor = "black";}else{s.nameColor = styleData.color;}	if(!styleData.font){s.nameFont = "宋体";}else{s.nameFont = styleData.font;}	if(!styleData.size){s.nameSize = "15";}else{s.nameSize = styleData.size;}}LTalk.prototype.setMsgStyle = function(styleData){	var s = this;	if(!styleData.x){s.msgX = 0;}else{s.msgX = styleData.x;}	if(!styleData.y){s.msgY = 0;}else{s.msgY = styleData.y;}	if(!styleData.color){s.msgColor = "black";}else{s.msgColor = styleData.color;}	if(!styleData.font){s.msgFont = "宋体";}else{s.msgFont = styleData.font;}	if(!styleData.size){s.msgSize = "15";}else{s.msgSize = styleData.size;}}

值得注意的是,参数是一个JSON对象。格式如下:

 

 

/*给msg和name设置样式时传的参数*/{x:x坐标,y:y坐标,color:文字颜色,size:文字尺寸}/*给face设置样式时传的参数*/{x:x坐标,y:y坐标}

OK,给对话设定样式就搞定了。

 

再加一个手动清空对话的方法,这样一来可以方便用户手动清空对话:

 

LTalk.prototype.clear = function(){	var s = this;	s.removeAllChild();	s.die();}

 

最后加一个重设对话数据的函数:

 

LTalk.prototype.setData = function(content){	var s = this;	s.content = content;}

 

5,Debug输出

前面在设计类时,没考虑到大家debug,所以都没加入什么debug输出。这次想到了,就顺便做一下,顺便把以前的也做了一下。今天就只呈现LTalk中的Debug输出,代码如下:

 

LTalk.prototype.showData = function(){	var s = this;	for(var key in s.content){		trace("----------No."+key+"----------");		trace("Name: " + s.content[key].name);		trace("Msg: " + s.content[key].msg);		trace("Face: " + s.content[key].face);	}}

 

调用此方法输出如下:

6,源代码

源代码不多,大家可以拿下去测试一下:

 

/***LTalk.js*/function LTalk(content){	var s = this;	base(s,LSprite,[]);	if(!content){		s.content = [];	}else{		s.content = content;	}	s.x = 0;	s.y = 0;	s.textWidth = LStage.width;	s.talkIndex = 0;	s.faceX = 0;	s.faceY = 0;	s.nameX = 0;	s.nameY = 0;	s.nameColor = "black";	s.nameFont = "宋体";	s.nameSize = "15";	s.msgX = 0;	s.msgY = 0;	s.msgColor = "black";	s.msgFont = "宋体";	s.msgSize = "15";}LTalk.prototype.setData = function(content){	var s = this;	s.content = content;}LTalk.prototype.showData = function(){	var s = this;	for(var key in s.content){		trace("----------No."+key+"----------");		trace("Name: " + s.content[key].name);		trace("Msg: " + s.content[key].msg);		trace("Face: " + s.content[key].face);	}}LTalk.prototype.setFaceStyle = function(styleData){	var s = this;	if(!styleData.x){s.faceX = 0;}else{s.faceX = styleData.x;}	if(!styleData.y){s.faceY = 0;}else{s.faceY = styleData.y;}}LTalk.prototype.setNameStyle = function(styleData){	var s = this;	if(!styleData.x){s.nameX = 0;}else{s.nameX = styleData.x;}	if(!styleData.y){s.nameY = 0;}else{s.nameY = styleData.y;}	if(!styleData.color){s.nameColor = "black";}else{s.nameColor = styleData.color;}	if(!styleData.font){s.nameFont = "宋体";}else{s.nameFont = styleData.font;}	if(!styleData.size){s.nameSize = "15";}else{s.nameSize = styleData.size;}}LTalk.prototype.setMsgStyle = function(styleData){	var s = this;	if(!styleData.x){s.msgX = 0;}else{s.msgX = styleData.x;}	if(!styleData.y){s.msgY = 0;}else{s.msgY = styleData.y;}	if(!styleData.color){s.msgColor = "black";}else{s.msgColor = styleData.color;}	if(!styleData.font){s.msgFont = "宋体";}else{s.msgFont = styleData.font;}	if(!styleData.size){s.msgSize = "15";}else{s.msgSize = styleData.size;}}LTalk.prototype.wind = function(num,completeFunc){	var s = this;	if(!num || num == null)num = 0;	if(!completeFunc)completeFunc = null;	s.talkIndex = num;	s.removeAllChild();	if(s.talkIndex < s.content.length){		var talkObject = s.content[s.talkIndex];		var faceBitmapdata = new LBitmapData(talkObject.face);		var faceBitmap = new LBitmap(faceBitmapdata);		faceBitmap.x = s.faceX;		faceBitmap.y = s.faceY;		s.addChild(faceBitmap);		var name = new LTextField();		name.x = s.nameX;		name.y = s.nameY;		name.size = s.nameSize;		name.color = s.nameColor;		name.font = s.nameFont;		name.text = talkObject.name;		name.width = s.textWidth;		name.setWordWrap(true,name.getHeight()+5);		s.addChild(name);		var msg = new LTextField();		msg.x = s.msgX;		msg.y = s.msgY;		msg.size = s.msgSize;		msg.color = s.msgColor;		msg.font = s.msgFont;		msg.text = talkObject.msg;		msg.width = s.textWidth;		msg.setWordWrap(true,msg.getHeight()+7);		msg.wind(completeFunc);		s.addChild(msg);	}else{		trace("Error: Param exceeds the size of the content!");	}}LTalk.prototype.clear = function(){	var s = this;	s.removeAllChild();	s.die();}

运用时,就只用写这些代码:

 

 

var talkContent = [	{name:"[Yorhom]",msg:"你好,lufy",face:imglist["yorhom_face"]},	{name:"[lufy]",msg:"你好,yorhom",face:imglist["lufy_face"]},	{name:"[Yorhom]",msg:"lufylegend最新版本是哪个版本啊?",face:imglist["yorhom_face"]},	{name:"[lufy]",msg:"……你不知道自己看吗?",face:imglist["lufy_face"]},	{name:"[Yorhom]",msg:"……说得也是",face:imglist["yorhom_face"]},];var talk = new LTalk(talkContent);addChild(talk);talk.wind();

顺便提示一下,LTalk构造时所传的对话内容参数是一个数组套JSON的格式,它要在游戏图片加载完成后再初始化,否则显示不出对话头像。

 

最后把测试链接给大家:

进入后点击黑框开始对话。祝大家测试愉快~

近天就先说到这里,下次我们接着研究。

谢谢大家阅读本文,支持就是最大的鼓励。(^_^)

 

----------------------------------------------------------------

欢迎大家转载我的文章。

转载请注明:转自

欢迎继续关注我的博客

 

转载于:https://www.cnblogs.com/snake-hand/archive/2013/06/12/3132999.html

你可能感兴趣的文章
349. Intersection of Two Arrays java solutions
查看>>
1. 考虑使用静态工厂方法替代构造方法
查看>>
windows server常用命令
查看>>
python模块整理6-tarfile模块
查看>>
POJ2955Brackets——dp
查看>>
tyvj1659中中救援队
查看>>
Gym 101510C-Computer Science
查看>>
最大公约数
查看>>
技术选型
查看>>
kubernetes学习:CKA考试题
查看>>
第十四章 我国农村乡镇企业发展
查看>>
postgreSQL执行计划
查看>>
LINUX samba的安装使用
查看>>
多省联测2018
查看>>
你了解继承吗?
查看>>
Codeforces Round #280 (Div. 2) C. Vanya and Exams 贪心
查看>>
Codeforces Beta Round #3 B. Lorry 暴力 二分
查看>>
poj 3657
查看>>
HDU 1026 Ignatius and the Princess I (优先队列+BFS(广度优先搜索))
查看>>
Java内置数据类型
查看>>