《游戏脚本的设计与开发》-(RPG部分)3.4 地图跳转

原创 2014年03月16日 12:40:33

注意:本系列教程为长篇连载无底洞,半路杀进来的朋友,如果看不懂的话,请从第一章开始看起,文章目录请点击下面链接。

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


一眨眼,离上次更新已经两个月了,中间有几个朋友咨询地图跳转和任务系统具体怎么做,为了证明该系列文章会继续写下去,这一次先来实现一下地图跳转。

先看一下效果预览:


地图跳转,顾名思义,就是从一张地图跳转到另一张地图(这不是废话嘛),体现在游戏程序中,就是当人物走到了某一个坐标区域,或者在游戏中触发了某事件之后,游戏程序将当前地图和地图上的所有东西清除,简单说就是清空画面,然后再加载另一张地图并显示。

我们把游戏中事件的触发归类到任务系统中,本次来实现人物移动到某个坐标区域后的地图跳转,要实现这一过程,大约是下面的四个步骤:

1,地图跳转的坐标区域的设置

2,人物移动时,与地图上所设置的坐标区域的判定

3,画面清空

4,新地图加载

画面清空和地图加载两个功能在前面的章节已经实现完毕,所以这一次我们重点来看前面的两步。

首先,来看一下接下来要实现的脚本。

//RPG地图中各函数初始化开始
function.start;
function mapR02();
	//地图跳转
endfunction;
function.end;
//RPG地图中实时判定部分
loop.start;
//添加地图坐标区域判定,参数(人物序号,起始坐标x,起始坐标y,终了坐标x,终了坐标y,触发函数名称)
RPGCharacter.atCoordinate(1,43,27,45,29,mapR02);
loop.end;
其中的mapR02是创建函数脚本,不了解的朋友可以看一下第一章的内容。

loop.start;和loop.end;中间的脚本用来处理游戏中需要实时判定的内容,比如这次的地图跳转,每次人物移动都需要判断一次地图是否应该发生跳转。

atCoordinate这个脚本函数是设定地图跳转区域,几个参数都在上面做了注释,不多说了,下面看一下具体实现。

LRPGMapScript.loop=function(){
	var script = LGlobal.script;
	var lineValue = LMath.trim(script.lineList.shift());
	if(lineValue.length == 0){
		LRPGMapScript.loop();
		return;
	}
	trace("LRPGMapScript loop lineValue = " + lineValue);
	if(lineValue == "loop.end"){
		LRPGMapScript.analysis();
		return;
	}
	var params,i;
	var start = lineValue.indexOf("(");
	var end = lineValue.indexOf(")");
	switch(lineValue.substr(0,start)){
		case "RPGCharacter.atCoordinate":
			params = lineValue.substring(start+1,end).split(",");
			LRPGObject.RPGMap.addCoordinateCheck.apply(LRPGObject.RPGMap,params);
			LRPGMapScript.loop();
			break;
		default:
			LRPGMapScript.loop();
	}
};

直接贴了全部代码,是不是太敷衍了?哈哈,其实这些代码都是依葫芦画瓢,跟前面介绍过的一样,就是解析一下函数名和参数,重点是解析之后,调用了

LRPGObject.RPGMap.addCoordinateCheck.apply(LRPGObject.RPGMap,params);

LRPGObject.RPGMap是之前设定好的MapController的实例,

MapController.prototype.addCoordinateCheck=function(index,startX,startY,endX,endY,funName){
	this.model.addCoordinateCheck(index,startX,startY,endX,endY,funName);
};
在这个控制器里面调用了模型的同名函数。

MapModel.prototype.addCoordinateCheck=function(index,startX,startY,endX,endY,funName){
	var self = this;
	var child = {
		"index":index,
		"rect":new LRectangle(
			parseInt(startX),
			parseInt(startY),
			parseInt(endX)-parseInt(startX),
			parseInt(endY)-parseInt(startY)
		),
		"fun":funName
	};
	self.atRect.push(child);
};

把相应的参数,保存到控制器的atRect数组中,然后在人物移动的时候,和这个数组中的信息做判定就可以了。

因为人物移动是在Character类中实现的,所以修改Character类,在人物移动完一个坐标之后,与地图模型的atRect做一下判断,判断部分如下。

Character.prototype.checkCoordinate = function(controller,initFlag){
	var self = this;
	var model=controller.model,i,obj,rect,rects = model.atRect,coor;
	for(i=0;i<rects.length;i++){
		obj = rects[i];
		rect = obj.rect;
		if(obj.index != self.index){
			continue;
		}
		coor = self.getTo();
		if(coor[0] >= rect.x && coor[0] <= rect.right && 
			coor[1] >= rect.y && coor[1] <= rect.bottom){
			if(self.coordinateRects[obj.fun]){
				continue;
			}
			self.coordinateRects[obj.fun] = true;
			if(initFlag){
				continue;
			}
			ScriptFunction.analysis("Call."+obj.fun + "();");
		}else if(self.coordinateRects[obj.fun]){
			self.coordinateRects[obj.fun]= null;
		}
	}
};
人物移动到指定坐标区域后,将该区域的函数信息添加到self.coordinateRects里,离开区域后,将self.coordinateRects中的信息删除。之所以这么做是为了防止2次触发同一事件。另外,initFlag的作用是在地图初始化的时候用的,因为有时候,人物可能一开始就已经站在指定的坐标区域中,而事件的判定是需要人物发生移动走入该区域才触发的,比如人物走进一间屋子,可能地图加载完后人物就站在门口,而人物走到门口的时候应该是走出这间的区域范围,所以,一开始将该地区设置为已判断,等人物离开门口区域,再走回去的时候,就正常判断离开屋子了。这个initFlag就是起到了这个作用,将人物一开始所站的位置设置为已判断。
上面的代码可以看到,当人物走到了指定的区域后,就会调用相应的脚本函数。但是,目前这个脚本函数是这个样子的。

function mapR02();
	//地图跳转
endfunction;
是一个空函数,我们在里面添加点东西,如下。

function mapR02();
	//清空画面
	Layer.clear(-);
	//读取下一地图脚本
	Load.script(script/R02.ls);
endfunction;
看到了吧,先清空画面,然后读取另一个地图脚本文件,就这么两行代码就可以实现地图跳转了。不信看下面的图,已经到了第二张地图了。

稍等了,虽然我们已经可以设定地图跳转的坐标区域了,但是在画面上我们什么也看不到,看下面的图,谁知道走到哪里会发生跳转啊。


那怎么办呢?不用担心,我们来给地图的跳转区域做个记号。

先准备一个Entrance类,放到Libraries下。

function Entrance(){
	var self = this;
	base(self,LSprite,[]);
	loader = new LLoader();
	loader.parent = self;
	loader.addEventListener(LEvent.COMPLETE,self.loadOver);
	loader.load(LMvc.IMG_PATH+"items/entrance.png","bitmapData");
}
Entrance.prototype.loadOver = function(event){
	var self = event.target.parent;
	var bitmapData = new LBitmapData(event.currentTarget,0,0,148,142);
	var list = LGlobal.divideCoordinate(444,142,1,3);
	self.anime = new LAnimationTimeline(bitmapData,list);
	self.anime.speed = 4;
	self.anime.x = -70;
	self.anime.y = -70;
	self.addChild(self.anime);
};

有了记号的类了,怎么添加呢,比如我们设定以下面的脚本来往地图上添加一个元件。

RPGItem.add(entrance,44,28);
这个脚本解析起来也很简单,下面是脚本解析部分。

LRPGItemScript = function(){};
LRPGItemScript.analysis=function(value){
	var start = value.indexOf("(");
	var end = value.indexOf(")");
	switch(value.substr(0,start)){
		case "RPGItem.add":
			LRPGItemScript.add(value,start,end);
			break;
		default:
			LGlobal.script.analysis();
	}
};
LRPGItemScript.add = function (value,start,end){
	var params = value.substring(start+1,end).split(",");
	if(LRPGObject.RPGMap){
		LRPGObject.RPGMap.addItem.apply(LRPGObject.RPGMap,params);
	}
	LGlobal.script.analysis();
};
控制器和视图中的addItem函数如下:

//控制器部分
MapController.prototype.addItem = function(name,x,y){
	this.view.addItem(name,parseInt(x),parseInt(y));	
};
......
//视图部分
MapView.prototype.addItem = function(name,x,y){
	var self = this,item;
	switch(name){
		case "entrance":
			item = new Entrance();
			item.x = x*self.model.stepWidth;
			item.y = y*self.model.stepHeight;
			self.mapLayer.addChild(item);
			break;
	}	
};
看下效果如何:

咦!效果还不错嘛,哈。地图跳转后,也给酒店里加上跳转记号,看效果:


好了,自己来测试下效果吧,URL连接如下:

http://lufylegend.com/demo/test/lsharp/rpg-lshape-04/index.html

最后,给出本次的代码下载:

https://github.com/lufylegend/lsharp/archive/3.4.zip


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

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

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

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


《游戏脚本的设计与开发》-(RPG部分)3.8 通过脚本来自由控制游戏(一)

一个RPG游戏中会触发各种各样的剧情,让某个人物的动作改变,或者让某个人移动到另一处,或者让某个人物从战场上消失,或者会播放一段动画,或者会切换游戏场景,等等吧,这些都要通过脚本来动态的控制。 我在序...
  • lufy_Legend
  • lufy_Legend
  • 2014年09月02日 21:31
  • 10784

《游戏脚本的设计与开发》-(RPG部分)3.1 RPG地图到底怎么做?

我之前也写过一个短篇系列《零基础开发RPG游戏开源讲座》,介绍的也比较简单,这次我会更深入也更具体的介绍一下RPG游戏的开发过程。 话说好久没有更新博客了,其实这段时间主要是工作忙,没时间。那又是什么...
  • lufy_Legend
  • lufy_Legend
  • 2013年12月19日 16:30
  • 15145

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

一,话说天下大事 前不久看到lufy的博客上,有一位朋友想要一个RPG游戏引擎,出于兴趣准备动手做一做。由于我研究lufylegend有一段时间了,对它有一定的依赖性,因此就准备将这个引擎基于luf...
  • yorhomwang
  • yorhomwang
  • 2013年05月06日 21:49
  • 21850

《游戏脚本的设计与开发》-(RPG部分)3.6 队员列表和人物属性

队员列表的作用就是保存我方能够参战的人员的信息,简单来说一个数组就可以完成。但是我们需要考虑,这个数组里需要保存哪些信息,对于早期简单的RPG游戏来说,比如《勇者斗恶龙》,《吞食天地》等,每个人的相应...
  • lufy_Legend
  • lufy_Legend
  • 2014年03月31日 13:08
  • 11249

《游戏脚本的设计与开发》-(RPG部分)3.2 地图遮挡和人物行走

上一节中已经介绍了RPG游戏中地图怎么实现,在RPG游戏的地图中通常有各种遮挡,比如人物站在房屋的后面的时候,房子应该遮挡住人物,这就涉及到各种建筑物和人物的排序显示。另外,上一节中我为了测试地图,已...
  • lufy_Legend
  • lufy_Legend
  • 2014年01月02日 05:54
  • 14304

RPG游戏(地图传送)

首先,我们创建三个接口,一个摆放地图,一个加载NPC,一个加载玩家自身。 properties: { bg:cc.Sprite, loadWaitImage:cc.Spri...
  • starh4
  • starh4
  • 2016年08月02日 14:38
  • 140

RPG游戏(一)——环境搭建、地图显示

RPG游戏是rogue类似,例如经典RPG的游戏“口袋妖怪”,我们组选择用Qt开发一个类似的游戏,作为“嵌入式linux开发”这门课的大作业。环境搭建:安装Qt、安装Tiledmap(一款地图编辑器)...
  • jupeizhong
  • jupeizhong
  • 2015年11月17日 16:55
  • 604

人生如梦游戏间,RPG游戏开源开发讲座(JAVA篇)[1]——风云初现

“本鹏”上接前文,继续来进行Java RPG开发讲座,上次我们谈到了JFrame和JPanel合作进行界面开发,这次我们再结合实例继续讲解。        在谈完Java中窗体和面板的使用后,接下...
  • w00w12l
  • w00w12l
  • 2013年06月20日 21:00
  • 1732

《游戏脚本的设计与开发》-(战棋部分)2.4 物理攻击

终于到了攻击部分了,战棋游戏中的攻击,主要分为物理攻击和法术攻击,本章就先从物理攻击讲起。物理攻击又分为普通攻击,连击(双击),以及致命攻击,再复杂一点的还有其他特殊攻击,比如我的《三国记-乱世群雄》...
  • lufy_Legend
  • lufy_Legend
  • 2013年08月12日 10:32
  • 11228

《游戏脚本的设计与开发》-(RPG部分)3.5 游戏背包和任务系统

背包系统在游戏中是必不可少的,在游戏中,所有获得的物品都会储存在背包里面。背包的种类,我一般将它分成两大类,一种是类似于《吞食天地》的“个人背包”,在游戏中每个人物都有一个背包,每个人的背包都互不影响...
  • lufy_Legend
  • lufy_Legend
  • 2014年03月24日 11:29
  • 30894
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《游戏脚本的设计与开发》-(RPG部分)3.4 地图跳转
举报原因:
原因补充:

(最多只允许输入30个字)