下面是我制作《幸运的金币碎片脚本凭证》脚本,但是在游戏...

《游戏脚本的设计与开发》- 游戏背包和任务系统
我的图书馆
《游戏脚本的设计与开发》- 游戏背包和任务系统
《游戏脚本的设计与开发》- 游戏背包和任务系统
本节重点来讲一下背包系统,以及简单的先来认识一下任务系统。
先看一下背包系统的效果预览:
背包系统在游戏中是必不可少的,在游戏中,所有获得的物品都会储存在背包里面。背包的种类,我一般将它分成两大类,一种是类似于《吞食天地》的“个
人背包”,在游戏中每个人物都有一个背包,每个人的背包都互不影响,并且每个人只能使用自己背包中的物品。另一种是“集体背包”,游戏中所有己方的人物都
共用一个背包,大多数游戏都采用这种形势。下面我们就来实现一下“集体背包”。
我们先来做一个按钮,用来打开游戏菜单,按钮的添加很简单,界面如下。
根据我制作《三国记》的经验,游戏菜单的UI需要注意的是,按钮要尽量大一些,否则在手机上就很难被点到。先来创建游戏菜单的相关文件。
控制器MenuController,模型MenuModel和视图MenuView。
关于菜单,我们需要有一个下面这样的背景框
并且这个背景框在其他许多地方也都会被用到,所以我们把它做成一个共同的外部类,如下。
这个类的实现原理如下,将一个只有左上角的图片,通过分割,旋转,拉伸等操作,组合成一个背景框
也就是说,我们只需要多准备几张类似于如下的图片,就可以实现不同的背景框了。
游戏菜单中的按钮,由图标和文字两部分组成,为了方便,我们也封装一个外部类。
接下来准备好相应的菜单按钮图标,在菜单的视图中添加如下一系列代码。
[javascript]&
......&&var&backpack&=&new&ButtonText("backpack","背包",true);&&&&&&backpack.x&=&startX&+&xindex*&&&&&&backpack.y&=&startY&+&yindex*&&&&&&self.menuLayer.addChild(backpack);&&&&&&backpack.addEventListener(LMouseEvent.MOUSE_UP,&function(event){&&&&&&&&&<weenLite.to(self.menuLayer,0.3,{x:LGlobal.width,onComplete:function(){&&&&&&&&&&&&&&self.controller.showBackpack();&&&&&&&&&&}});&&&&&&});&&......&&
最后,给画面中的菜单按钮添加打开菜单的点击事件,打开菜单的代码如下。
[javascript]&
MapController.prototype.openmenuClick&=&function(){&&&&&&var&self&=&this;&&&&&&self.loadMvc("Menu",self.openmenuComplete);&&&};&&MapController.prototype.openmenuComplete&=&function(){&&&&&&var&self&=&this;&&&&&&var&menu&=&new&MenuController();&&&&&&menu.baseView&=&self.&&&&&&self.view.parent.addChild(menu.view);&&&&&&//移动端的时候,为了提高效率,将地图隐藏&&&&&&if(LGlobal.canTouch){&&&&&&&&&&self.view.visible&=&false;&&&&&&}&&};&&
下面是菜单效果。为了好看,我临时添加了背包,装备,武将,任务,设置等几个功能按钮,本次只讲一下背包部分的具体实现,其他部分我们后面再慢慢讲。
背包部分我们也为其创建相关的文件。
控制器BackpackController,模型BackpackModel和视图BackpackView。
从文章开头的预览图片中,我们看到恢复用品,武器装备,特殊物品三个按钮其实是tab选项卡,有是否被选中两种状态,所以我们为这个功能封装下面一个类。
其中的GetButton是我另创建的一个辅助函数,功能就是返回一个带文字或者不带文字的按钮,代码如下
在背包的视图中首先添加背景框,然后添加类似于下面一系列代码。
[javascript]&
......&&&&&&var&closeButton&=&GetButton(LMvc.datalist["BtnClose01"],null,0);&&&&&&closeButton.x&=&710;&&&&&&closeButton.y&=&25;&&&&&&self.addChild(closeButton);&&&&&&closeButton.addEventListener(LMouseEvent.MOUSE_UP,&function(){&&&&&&&&&&self.controller.closeBackpack();&&&&&&});&&&&&&&&&&&&var&recoveryButton&=&new&ButtonSelect("BtnSelect01",{label:"恢复用品",width:180,height:48},1);&&&&&&recoveryButton.x&=&550;&&&&&&recoveryButton.y&=&110;&&&&&&self.addChild(recoveryButton);&&&&&&self.recoveryButton&=&recoveryB&&&&&&recoveryButton.addEventListener(LMouseEvent.MOUSE_UP,&function(){&&&&&&&&&&self.controller.recoveryPropsSelect();&&&&&&});&&......&&
效果如下。
按钮选项卡的选中和非选中状态,我们只要像下面这样。
[javascript]&
specialButton.setSelected(true);&&
选项卡是否处于选中状态,我们也可以很轻松的判断。
[javascript]&
if(specialButton.selected)return;&&
好了,接下来为了给背包中添加物品,我们需要先定义物品,在script/initialization文件夹下添加props.json文件,先简单的来定义三个物品。
{&&"props1":{&&&&&&"Index":1,&&&&&&"Name":"包子",&&&&&&"Type":"Recovery",&&&&&&"Max":99,&&&&&&"Icon":1,&&&&&&"Hp":30,&&&&&&"Mp":0,&&&&&&"Force":0,&&&&&&"Intelligence":0,&&&&&&"Command":0,&&&&&&"Agile":0,&&&&&&"Luck":0,&&&&&&"Introduction":"普通的馒头,可以恢复一点HP。"&&&&&&},&&"props2":{&&&&&&"Index":2,&&&&&&"Name":"天书残卷",&&&&&&"Type":"Special",&&&&&&"Max":1,&&&&&&"Icon":2,&&&&&&"Introduction":"特殊物品之天书残卷,暂时没有详细介绍。"&&&&&&},&&"props3":{&&&&&&"Index":3,&&&&&&"Name":"倚天剑",&&&&&&"Type":"Weaponry",&&&&&&"Max":1,&&&&&&"Icon":3,&&&&&&"Introduction":"倚天剑,介绍略。"&&&&&&}&&}&&
几个属性分别代表Index:物品序号,Name:物品名称,Type:物品分类,Max:背包中一个物品位可盛放的最大数量,Icon:图标。这几个属性只是为了能在背包中显示,其他的属性,等用到的时候我再具体说。为了更方便在游戏程序中操作它们,我们为物品的每个种类,分别创建相应的类。
[javascript]&
function&PropsRecovery(data){&&&&&&var&self&=&this;&&&&&&self.index&=&data.I&&&&&&self.name&=&data.N&&&&&&self.type&=&data.T&&&&&&self.icon&=&data.I&&&&&&self.max&=&data.M&&&&&&self.count&=&1;&&&&&&self.data&=&&&}&&
[javascript]&
function&PropsWeaponry(data){&&&&&&var&self&=&this;&&&&&&self.index&=&data.I&&&&&&self.name&=&data.N&&&&&&self.type&=&data.T&&&&&&self.icon&=&data.I&&&&&&self.max&=&data.M&&&&&&self.count&=&1;&&&&&&self.data&=&&&}&&
[javascript]&
function&PropsSpecial(data){&&&&&&var&self&=&this;&&&&&&self.index&=&data.I&&&&&&self.name&=&data.N&&&&&&self.type&=&data.T&&&&&&self.icon&=&data.I&&&&&&self.max&=&data.M&&&&&&self.count&=&1;&&&&&&self.data&=&&&}&&
然后给LRPGObject类添加物品数组,用来盛放所有的物品。
[javascript]&
LRPGObject.propsList&=&[];&&
我们再继续给LRPGObject类添加两个函数,分别是添加物品和删除物品,操作很简单,就是往propsList里添加和删除元素。
[javascript]&
LRPGObject.addProps&=&function(index){&&&&&&var&propsData&=&LMvc.datalist["props"]["props"+index],i,l,&&&&&&if(!propsData)return;&&&&&&for(i=0,l=LRPGObject.propsList.i&l;i++){&&&&&&&&&&props&=&LRPGObject.propsList[i];&&&&&&&&&&if(props.index&==&propsData.Index){&&&&&&&&&&&&&&if(props.count&&&props.max){&&&&&&&&&&&&&&&&&&props.count&=&props.count&+&1;&&&&&&&&&&&&&&&&&&return;&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&&&&&switch(propsData.Type){&&&&&&&&&&case&"Recovery":&&&&&&&&&&&&&&LRPGObject.propsList.push(new&PropsRecovery(propsData));&&&&&&&&&&&&&&break;&&&&&&&&&&case&"Special":&&&&&&&&&&&&&&LRPGObject.propsList.push(new&PropsSpecial(propsData));&&&&&&&&&&&&&&break;&&&&&&&&&&case&"Weaponry":&&&&&&&&&&&&&&LRPGObject.propsList.push(new&PropsWeaponry(propsData));&&&&&&&&&&&&&&break;&&&&&&}&&};&&LRPGObject.removeProps&=&function(index){&&&&&&var&propsData&=&LMvc.datalist["props"]["props"+index],i,l,&&&&&&if(!propsData)return;&&&&&&for(i=LRPGObject.propsList.length&-&1;i&=0;i--){&&&&&&&&&&props&=&LRPGObject.propsList[i];&&&&&&&&&&if(props.index&==&propsData.Index){&&&&&&&&&&&&&&props.count--;&&&&&&&&&&&&&&if(props.count&&=&0){&&&&&&&&&&&&&&&&&&LRPGObject.propsList.splice(i,1);&&&&&&&&&&&&&&&&&&break;&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&}&&};&&
当点击不同的选项卡的时候,我们需要先把LRPGObject.propsList数组中的物品筛选出来,如下
[javascript]&
BackpackModel.prototype.propsSelect=function(propsType){&&&&&&var&self&=&this,i,l,&&&&&&self.data.length&=&0;&&&&&&self.dataIndex&=&0;&&&&&&for(i=0,l=LRPGObject.propsList.i&l;i++){&&&&&&&&&&props&=&LRPGObject.propsList[i];&&&&&&&&&&if(props.type&==&propsType){&&&&&&&&&&&&&&self.data.push(props);&&&&&&&&&&}&&&&&&}&&};&&
然后规定几个物品一组,来分页获取需要显示的物品列表。
[javascript]&
BackpackModel.prototype.getProps=function(){&&&&&&var&self&=&this,i,l,props,list=[];&&&&&&if(self.dataIndex&&&0&||&self.dataIndex&&=&self.data.length){&&&&&&&&&&return&[];&&&&&&}&&&&&&for(i=self.dataIndex,l=self.data.length&i+self.dataMax?i+self.dataMax:self.data.i&l;i++){&&&&&&&&&&props&=&self.data[i];&&&&&&&&&&list.push(props);&&&&&&}&&&&&&return&&&};&&
得到了物品列表之后,将物品添加到背包的视图中就行了。
[javascript]&
BackpackView.prototype.showProps=function(){&&&&&&var&self&=&this,num,l,icon,&&&&&&var&list&=&self.model.getProps();&&&&&&num&=&0;&&&&&&l&=&list.&&&&&&self.propsLayer.die();&&&&&&self.propsLayer.removeAllChild();&&&&&&for(var&i=0;i&3&&&&num&l;i++){&&&&&&&&&&for(var&j=0;j&2&&&&num&l;j++){&&&&&&&&&&&&&&props&=&list[num];&&&&&&&&&&&&&&icon&=&new&PropsIcon(props);&&&&&&&&&&&&&&icon.x&=&self.propsStartX&+&120*i;&&&&&&&&&&&&&&icon.y&=&self.propsStartY&+&135*j;&&&&&&&&&&&&&&self.propsLayer.addChild(icon);&&&&&&&&&&&&&&num++;&&&&&&&&&&}&&&&&&}&&};&&
接下来就是脚本了,我们如何来利用脚本添加或者删除一个物品呢?看下面的脚本。
[javascript]&
//添加一个物品,参数:物品序号&&&&&&RPGProps.add(1);&&&&&&//删除一个物品,参数:物品序号&&&&&&RPGProps.remove(2);&&
下面是脚本解析,很简单不是吗
[javascript]&
/*&*&LRPGPropsScript.js&**/&&LRPGPropsScript&=&function(){};&&LRPGPropsScript.analysis=function(value){&&&&&&var&start&=&value.indexOf("(");&&&&&&var&end&=&value.indexOf(")");&&&&&&switch(value.substr(0,start)){&&&&&&&&&&case&"RPGProps.add":&&&&&&&&&&&&&&LRPGPropsScript.add(value,start,end);&&&&&&&&&&&&&&break;&&&&&&&&&&case&"RPGProps.remove":&&&&&&&&&&&&&&LRPGPropsScript.remove(value,start,end);&&&&&&&&&&&&&&break;&&&&&&&&&&default:&&&&&&&&&&&&&&LGlobal.script.analysis();&&&&&&}&&};&&LRPGPropsScript.add&=&function&(value,start,end){&&&&&&var¶ms&=&value.substring(start+1,end).split(",");&&&&&&LRPGObject.addProps(params[0]);&&&&&&LGlobal.script.analysis();&&};&&LRPGPropsScript.remove&=&function&(value,start,end){&&&&&&var¶ms&=&value.substring(start+1,end).split(",");&&&&&&LRPGObject.removeProps(params[0]);&&&&&&LGlobal.script.analysis();&&};&&
好了,背包系统,基本上就是这样了。
下面我们来介绍另一个非常重要的功能,就是任务系统,任务系统其实是比较复杂的,涉及到任务列表,任务奖励,任务的不同阶段的判定等等,这些我们后面会单独写一篇来详细讲解,本次先来利用现有的变量功能来完成一个简单的任务功能。
我假设关羽借了酒店老板一样东西,自己又懒得去还,想让刘备当个跑腿儿的,去帮忙把书还上,然后刘备拿着这个东西去还给酒店老板,然后老板给了刘备两个包子作为奖励。
在这一过程中,我们首先需要判断是否有任务,任务是否在进行中,任务是否已经结束等。
看下面点击关羽时的脚本
function&characterclick2();&&&&&&if(@task1000==1);&&&&&&&&&&&&RPGTalk.set(2,0,你知道lufy吗,听说那家伙除了做游戏,啥都不会。);&&&&&&&&&&RPGTalk.set(1,0,怪不得啊,哈哈哈。);&&&&&&elseif(@task1001==1);&&&&&&&&&&&&RPGTalk.set(2,0,《天书残卷》交给酒店老板了吗?);&&&&&&&else;&&&&&&&&&&&&RPGTalk.set(2,0,这本《天书残卷》是我前两天从酒店老板那里借来的,你能帮我还回去吗?);&&&&&&&&&&&RPGTalk.set(1,0,好啊,我正想去酒店喝点儿酒呢。);&&&&&&&&&&RPGProps.add(2);&&&&&&&&&&Var.set(task1001,1);&&&&&&&&&&&RPGMessageBox.show(得到了《仙书残卷》。请到酒店把它交给酒店老板吧。);&&&&&&&&&&&
变量task1000=1表示任务已经结束,task1001=1表示任务正在进行中,否则就是任务还没有开始。当任务没有开始的时候,所做的处理是先让刘备接受任务,然后把东西《仙书残卷》交给刘备。然后把变量task1001设置为1,表示任务开启,正在进行。
再看点击酒店老板的脚本。
function&characterclick6();&&&&&&RPGTalk.set(6,0,欢迎光临小店,客官要点儿什么?);&&&&&&if(@task1001==1);&&&&&&&&&&RPGTalk.set(1,0,关羽让我把这本《天书残卷》还给你。);&&&&&&&&&&RPGTalk.set(6,0,哎呀,太谢谢了,我正想去跟他要呢。);&&&&&&&&&&RPGProps.remove(2);&&&&&&&&&&Var.set(task1000,1);&&&&&&&&&&&Var.set(task1001,2);&&&&&&&&&&&RPGProps.add(1);&&&&&&&&&&RPGProps.add(1);&&&&&&&&&&RPGMessageBox.show(获得奖励:两个包子。);&&&&&&else;&&&&&&&&&&RPGTalk.set(1,0,我比较关心那边弹琴的美女是谁。);&&&&&&&&&&RPGTalk.set(6,0,她天下第一美女貂蝉啊。);&&&&&&&&&&
当task1001=1任务正在进行的时候,老板会接收刘备拿来的东西,然后给刘备两个包子作为奖励。最后把变量task1000设置为1,表示任务结束。然后为了防止任务再次出发,把task1001设置为2。好了,上面的脚本的效果如下。眼尖的朋友可以看到,我在脚本里用到了RPGMessageBox.show这个脚本,这个脚本会弹出提示框,如下
MessageBox的代码如下
脚本解析部分
[javascript]&
/*&*&LRPGMessageBoxScript.js&**/&&LRPGMessageBoxScript&=&function(){};&&LRPGMessageBoxScript.analysis=function(value){&&&&&&var&start&=&value.indexOf("(");&&&&&&var&end&=&value.indexOf(")");&&&&&&switch(value.substr(0,start)){&&&&&&&&&&case&"RPGMessageBox.show":&&&&&&&&&&&&&&LRPGMessageBoxScript.show(value,start,end);&&&&&&&&&&&&&&break;&&&&&&&&&&default:&&&&&&&&&&&&&&LGlobal.script.analysis();&&&&&&}&&};&&LRPGMessageBoxScript.show&=&function&(value,start,end){&&&&&&var¶ms&=&value.substring(start+1,end).split(",");&&&&&&MessageBox.show(params[0]);&&};&&
这样,一个简单的任务就完成了,当然这个不是任务系统的全部,这只是我用变量来完成一个任务的简单的小例子,关于任务,我后面再详细说。另外,有朋友反映,图片不好找,好不容易找到了图片,又不能用,所以我修改了一下Character类和Action类,代码如下
这样就可以根据实际的图片,在chara.json里定义相关的参数了
"peo1":{&&&&&&"Index":1,&&&&&&"Name":"刘备",&&&&&&"Face":1,&&&&&&"R":1,&&&&&&"RRect":[140,95,40,90],&&&&&&"Introduction":"刘备即蜀汉昭烈帝,字玄德,汉中山靖王刘胜的后代,三国时期蜀汉开国皇帝。"&&&&&&}&&
RRect表示人物在一个动作图片中的有用范围,
另外默认的每贞动作图片的大小是320x240,如果你的图片大小不一样,那还需要定义一下图片的大小,比如下面这样
"peo8":{&&&&&&"Index":8,&&&&&&"Name":"测试",&&&&&&"Face":3,&&&&&&"R":6,&&&&&&"RRect":[10,6,50,82],&&&&&&"RWidth":70,&&&&&&"RHeight":92,&&&&&&"Introduction":"测试"&&&&&&}&&
要想看看自己定义的大小是不是正确的话,开启debug模式就可以看到效果了,效果如下
好了,还是自己测试一下效果吧。
最后,给出本次的代码下载:
如需更全面地了解编译器优化,请参阅。
发表评论:
馆藏&21260
TA的最新馆藏

参考资料

 

随机推荐