首先,本篇文章是零基礎開發RPG遊戲-開源講座系列文章的第四篇,來實現遊戲的腳本化,並利用遊戲腳本實現地圖場景的切換,離上次更新貌似很久了,你在看下面的文字之前,需要先了解前三篇在下囉嗦了些什麼東東。
一,什麼是遊戲腳本
簡單說,遊戲腳本就是依據一定的格式編寫的可執行文件,遊戲可以透過腳本中自訂的語句來執行對應的邏輯。
遊戲腳本,可以讓我們的遊戲動態化,例如當我們開發了一款rpg遊戲,裡面的劇情,事件以及地圖等,我們如果將這些全部寫進程式裡,當然是可以的,但是一旦出現問題,哪怕幾個錯字,我們需要先將這幾個錯字改正,並且將整個程式重新編譯發布一遍,這個過程是相當令人反感的,因為如果遊戲的程式跟著遊戲的內容不斷進行修改的話,那隻會使你的程式越來越複雜。但是如果我們將這些可重複的數據,都定義到遊戲程式之外的文件裡面,當遊戲引擎開發完畢,我們的遊戲通過讀取這些外部文件,來執行相應的劇情和事件,那麼,像上述當我們的遊戲出現了問題,我們只需要改動這些外部文件就可以了,並不需要重新編譯整個程序,這樣便使得我們的遊戲開發,變得便利簡潔。
*當然,對於html5來說,不需要重新編譯程序,但是對於rpg的遊戲來說,腳本還是必不可少的,因為遊戲的劇本不可能全都寫到程序裡. ..
好了,接下來,先來考慮以什麼形式來製作遊戲的腳本,我們有多種選擇,可以選擇xml,可以選擇json,也可以選擇純自訂語法,
#如鄙開發的flash遊戲腳本L#http://blog.csdn .net/lufy_legend/article/details/6889424
#這次,我為了省事,選用比較方便處理的json,因為javascript可以很輕鬆的處理json資料。
目前遊戲中實現的內容有,地圖場景添加,遊戲人物添加,以及人物對話的實現。那麼,我在設計遊戲腳本的時候,必須包含這些數據,然後才能將這三個功能用腳本來控制。
首先看下面的json
var script = { stage01:{ map:[ [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18,18,18], [18,18,18,17,17,17,17,17,17,17,17,17,55,55,17,17,18], [18,18,17,17,17,17,18,18,17,17,17,17,55,55,17,17,18], [18,17,17,17,18,18,18,18,18,17,17,55,55,17,17,17,18], [18,17,17,18,22,23,23,23,24,18,17,55,55,17,17,17,18], [18,17,17,18,25,28,26,79,27,18,55,55,17,17,17,17,18], [18,17,17,17,17,10,11,12,18,18,55,55,17,17,17,17,18], [18,18,17,17,10,16,16,16,11,55,55,17,17,17,17,17,18], [18,18,17,17,77,16,16,16,16,21,21,17,17,17,17,17,18], [18,18,17,17,77,16,16,16,16,55,55,17,17,17,17,17,18], [18,18,18,18,18,18,18,18,18,55,55,18,18,18,18,18,18]], mapdata:[ [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,1], [1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1], [1,0,0,0,1,1,1,1,1,0,0,1,1,0,0,0,1], [1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,0,1], [1,0,0,1,1,1,0,1,1,1,1,1,0,0,0,0,1], [1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1], [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1], [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]], add:[ {chara:"player",img:"mingren",x:5,y:6}, {chara:"npc",img:"npc1",x:7,y:6}, {chara:"npc",img:"npc1",x:3,y:3}], talk:{ talk1:[ {img:"m",name:"鸣人",msg:"我是木叶村的鸣人,你是谁?"}, {img:"n",name:"黑衣忍者甲",msg:"你就是鸣人?九尾还在你身体里吗?"} ], talk2:[ {img:"n",name:"黑衣忍者乙",msg:"鸣人,听说忍者大战就要开始了。"}, {img:"m",name:"鸣人",msg:"真的吗?一定要想想办法啊。"} ] } } };
我將腳本定義成了變量,實際遊戲製作的時候,腳本應該儲存到一個外部文檔當中,在這裡我只是講解一下理論,如何完善那是後話了,哈。
可以看到,json中,包含了地圖相關的map數組和mapdata數組,增加人物的相關數據,以及對話的數組。這樣,我在遊戲顯示的時候,只需要讀入json數據,然後根據這些內容來顯示遊戲畫面就可以了,定義一個initScript函數來進行這些操作。
function initScript(){ //地图位置初始化 mapLayer.x = 0; mapLayer.y = 0; //地图层初始化 mapLayer.removeAllChild(); //人物层初始化 charaLayer.removeAllChild(); //效果层初始化 effectLayer.removeAllChild(); //对话层初始化 talkLayer.removeAllChild(); //地图数据获取 map = stage.map; mapdata = stage.mapdata; //对话数据获取 talkScriptList = stage.talk; //添加地图 addMap(0,0); delMap(); //添加人物 addChara(); }
removeAllChild方法是lufylegend引擎獨有的方法,可以用來移出LScript顯示層上的所有子對象,從而實現本遊戲中各個顯示層的初始化工作。
修改一下addChara方法,如下
//添加人物 function addChara(){ var charaList = stage.add; var chara,charaObj; for(var i=0;i<charaList.length;i++){ charaObj = charaList[i]; if(charaObj.chara == "player"){ //加入英雄 bitmapdata = new LBitmapData(imglist[charaObj.img]); chara = new Character(true,i,bitmapdata,4,4); player = chara; }else{ //加入npc bitmapdata = new LBitmapData(imglist[charaObj.img]); chara = new Character(false,i,bitmapdata,4,4); } chara.x = charaObj.x * 32; chara.y = charaObj.y * 32; charaLayer.addChild(chara); } }
即,根據json腳本中的add數組,來新增遊戲中的人物。
好了,運行一下遊戲,可以看到,遊戲正常顯示了,和之前一模一樣,實現了同樣的功能。
為了讓大家看到遊戲腳本的便利性,現在利用腳本實現遊戲中的場景切換。
將json腳本修改如下
var script = { stage01:{ map:[ [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18,18,18], [18,18,18,17,17,17,17,17,17,17,17,17,55,55,17,17,18], [18,18,17,17,17,17,18,18,17,17,17,17,55,55,17,17,18], [18,17,17,17,18,18,18,18,18,17,17,55,55,17,17,17,18], [18,17,17,18,22,23,23,23,24,18,17,55,55,17,17,17,18], [18,17,17,18,25,28,26,79,27,18,55,55,17,17,17,17,18], [18,17,17,17,17,10,11,12,18,18,55,55,17,17,17,17,18], [18,18,17,17,10,16,16,16,11,55,55,17,17,17,17,17,18], [18,18,17,17,77,16,16,16,16,21,21,17,17,17,17,17,18], [18,18,17,17,77,16,16,16,16,55,55,17,17,17,17,17,18], [18,18,18,18,18,18,18,18,18,55,55,18,18,18,18,18,18]], mapdata:[ [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,1], [1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1], [1,0,0,0,1,1,1,1,1,0,0,1,1,0,0,0,1], [1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,0,1], [1,0,0,1,1,1,0,1,1,1,1,1,0,0,0,0,1], [1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1], [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1], [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]], add:[ {chara:"player",img:"mingren",x:5,y:6}, {chara:"npc",img:"npc1",x:7,y:6}, {chara:"npc",img:"npc1",x:3,y:3}], talk:{ talk1:[ {img:"m",name:"鸣人",msg:"我是木叶村的鸣人,你是谁?"}, {img:"n",name:"黑衣忍者甲",msg:"你就是鸣人?九尾还在你身体里吗?"} ], talk2:[ {img:"n",name:"黑衣忍者乙",msg:"鸣人,听说忍者大战就要开始了。"}, {img:"m",name:"鸣人",msg:"真的吗?一定要想想办法啊。"} ] }, jump:[ {at:{x:6,y:5},to:"stage02"} ] }, stage02:{ map:[ [0,0,1,2,2,2,2,2,2,2,2,1,0,0,0], [0,0,1,3,5,5,1,5,5,5,5,1,0,0,0], [0,0,1,80,4,4,1,80,4,4,4,1,0,0,0], [0,0,1,80,4,4,1,80,8,7,8,1,0,0,0], [0,0,1,80,4,4,5,81,4,4,4,1,0,0,0], [0,0,1,2,2,2,6,4,4,4,4,1,0,0,0], [0,0,1,3,5,5,81,4,4,4,4,1,0,0,0], [0,0,1,80,4,4,4,4,4,4,9,1,0,0,0], [0,0,1,2,2,2,2,6,2,2,2,1,0,0,0]], mapdata:[ [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,1,1,0,0,0,1,0,0,0,0,1,1,1,1], [1,1,1,0,0,0,1,0,0,0,0,1,1,1,1], [1,1,1,0,0,0,1,0,0,1,0,1,1,1,1], [1,1,1,0,0,0,0,0,0,0,0,1,1,1,1], [1,1,1,1,1,1,0,0,0,0,0,1,1,1,1], [1,1,1,0,0,0,0,0,0,0,0,1,1,1,1], [1,1,1,0,0,0,0,0,0,0,1,1,1,1,1], [1,1,1,1,1,1,1,0,1,1,1,1,1,1,1]], add:[ {chara:"player",img:"mingren",x:7,y:8}, {chara:"npc",img:"npc1",x:8,y:3}, {chara:"npc",img:"npc1",x:10,y:3}], talk:{ talk1:[ {img:"m",name:"鸣人",msg:"你们在干什么啊?"}, {img:"n",name:"黑衣忍者甲",msg:"我们在喝茶。"} ], talk2:[ {img:"n",name:"黑衣忍者乙",msg:"我们在喝茶,你不要打扰我们。"}, {img:"m",name:"鸣人",msg:"....."} ] }, jump:[ {at:{x:7,y:8},to:"stage01"} ] } };
#可以看到,我加入了stage02,第二個場景,並且在腳本裡引入了jump節點來控制遊戲場景的切換,其中jump中的at表示遊戲主角移動到達的座標,to表示到達這個座標後跳到的畫面名稱。這裡的jump之所以是數組,是因為一個場景也可以跳到其他多個場景。
上面的腳本實現了stage01和stage02兩個場景的互相跳躍。
為了讀取這個jump,以及實現跳轉,我們需要在遊戲主人公移動一個步長之後,判斷一下是否應該跳轉了,修改Character類的onmove方法
/** * 开始移动 **/ Character.prototype.onmove = function (){ var self = this; //设定一个移动步长中的移动次数 var ml_cnt = 4; //计算一次移动的长度 var ml = STEP/ml_cnt; //根据移动方向,开始移动 switch (self.direction){ case UP: if(mapmove){ mapLayer.y += ml; charaLayer.y += ml; } self.y -= ml; break; case LEFT: if(mapmove){ mapLayer.x += ml; charaLayer.x += ml; } self.x -= ml; break; case RIGHT: if(mapmove){ mapLayer.x -= ml; charaLayer.x -= ml; } self.x += ml; break; case DOWN: if(mapmove){ mapLayer.y -= ml; charaLayer.y -= ml; } self.y += ml; break; } self.moveIndex++; //当移动次数等于设定的次数,开始判断是否继续移动 if(self.moveIndex >= ml_cnt){ //一个地图步长移动完成后,判断地图是否跳转 if(self.isHero && self.moveIndex > 0)checkJump(); self.moveIndex = 0; //一个地图步长移动完成后,如果地图处于滚动状态,则移除多余地图块 if(mapmove)delMap(); //如果已经松开移动键,或者前方为障碍物,则停止移动,否则继续移动 if(!isKeyDown || !self.checkRoad()){ self.move = false; return; }else if(self.direction != self.direction_next){ self.direction = self.direction_next; self.anime.setAction(self.direction); } //地图是否滚动 self.checkMap(self.direction); } };
我新增了一行
if(self.isHero && self.moveIndex > 0)checkJump();
表示,移動完後如果該人物是遊戲主角則進行跳躍判斷
所以,我們需要加入一個checkJump方法
//游戏场景跳转测试 function checkJump(){ var jump = stage.jump; var jumpstage; for(var i=0;i<jump.length;i++){ jumpstage = jump[0]; if(player.x == jumpstage.at.x * 32 && player.y == jumpstage.at.y * 32){ //获取该场景脚本数据 stage = script[jumpstage.to]; //开始跳转 initScript(stage); return; } } }
#好了,一切都很簡單吧,運行遊戲看看效果吧,小鳴人走到地圖的小房門的部分是,場景發生跳轉
遊戲測試URL:
http://lufylegend.com/demo/rpg/index.html
lufylegend.js引擎包內包含這個demo,請直接下載lufylegend.js引擎,查看引擎包內源碼
lufylegend.js引擎下載位址
http://lufylegend.com/lufylegend
# 以上就是html5遊戲開發-零基礎開發RPG遊戲-開源講座(四)-遊戲腳本化&地圖跳轉 的內容,更多相關內容請關注PHP中文網(m.sbmmt.com)!