html5遊戲開發-零基礎開發RPG遊戲-開源講座(四)-遊戲指令碼化&地圖跳轉
本文章首發自我的部落格 http://blog.csdn.net/lufy_legend/article/details/7213745
一,什麼是遊戲指令碼
簡單說,遊戲指令碼就是依據一定的格式編寫的可執行檔案,遊戲可以通過指令碼中自定義的語句來執行相應的邏輯。
二,為什麼要將遊戲指令碼化
遊戲指令碼,可以令我們的遊戲動態化,比如當我們開發了一款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
零基礎開發RPG遊戲-開源講座系列文章,結貼了,如有問題歡迎大家指正,也歡迎大家留言一起探討遊戲製作以及改進的方法。
相關文章
- Unity遊戲示例來了,用Unity開源遊戲資源做遊戲,遊戲開發不再難!Unity遊戲開發
- 遊戲開發入門(一)遊戲開發概述遊戲開發
- NFT遊戲系統開發/遊戲開發技術遊戲開發
- 遊戲開發中遊戲效能的最佳化遊戲開發
- 遊戲開發流程遊戲開發
- 零基礎瞭解3D遊戲開發3D遊戲開發
- 遊戲大地圖開發指南:遊戲外部空間設計遊戲地圖
- 阿里開源HTML5小遊戲開發框架Hilo實戰教程阿里HTML遊戲開發框架
- Python遊戲開發工程師的起步,幾款遊戲開發案例Python遊戲開發工程師
- 悠遊世界/遊戲/系統技術開發/悠遊世界養成遊戲開發解析遊戲開發
- pygame開發小遊戲GAM遊戲
- 【IDL】開發遊戲"2048"開發遊戲
- NFT遊戲鏈遊系統開發技術詳細丨NFT遊戲鏈遊DAPP開發原始碼模式遊戲APP原始碼模式
- HTML5遊戲開發(二):使用TypeScript編寫程式碼HTML遊戲開發TypeScript
- 遊戲開發原理——手遊開發團隊與成本遊戲開發
- 雜湊遊戲原始碼開發搭建丨hash雜湊遊戲競猜原始碼搭建丨雜湊遊戲系統開發遊戲原始碼
- HASH雜湊遊戲原始碼丨HASH雜湊遊戲系統開發丨HASH雜湊遊戲開發成品原始碼部署原始碼遊戲開發
- 悠遊世界合成遊戲系統技術開發解析/合成遊戲/小遊戲遊戲
- 【Unity3D開發小遊戲】《戰棋小遊戲》Unity開發教程Unity3D遊戲
- NFT鏈遊遊戲/養成遊戲/農場合成遊戲系統合約開發程式碼示例遊戲
- Gamefi鏈遊系統開發(DAPP遊戲開發)丨Gamefi鏈遊系統開發(開發案例)丨原始碼GAMAPP遊戲開發原始碼
- 遊戲開發商與遊戲發行商如何保持良性關係?遊戲開發
- python可以開發遊戲嗎Python開發遊戲
- 遊戲開發與設計遊戲開發
- 實戰Flash遊戲開發遊戲開發
- 遊戲開發第6天遊戲開發
- DApp遊戲系統開發APP遊戲
- 吃豆人遊戲開發遊戲開發
- 微信小遊戲首度亮相 ChinaJoy,助力開發者玩轉小遊戲遊戲
- Axie Infinity遊戲系統開發(詳情介紹)丨Axie Infinity遊戲開發(原始碼功能)遊戲開發原始碼
- 雜湊遊戲系統丨雜湊遊戲系統開發(演示版)丨雜湊遊戲開發原始碼及案例遊戲開發原始碼
- 盲盒遊戲開發(功能)丨盲盒遊戲系統開發(規則及詳細)丨盲盒遊戲原始碼部署遊戲開發原始碼
- Dapp智慧合約遊戲鏈遊開發丨智慧合約遊戲鏈遊系統開發案例版APP遊戲
- 遊戲地圖發展簡史遊戲地圖
- 旺旺農場遊戲NFT系統開發|NFT農場遊戲開發搭建方案遊戲開發
- NFT遊戲GameFi元宇宙(鏈遊遊戲)系統原始碼開發(詳情方案)遊戲GAM元宇宙原始碼
- 雜湊競猜遊戲系統開發原理丨雜湊遊戲系統開發技術方案丨雜湊競猜遊戲開發原始碼搭建遊戲開發原始碼
- 遊戲開發效能優化之物件池遊戲開發優化物件
- Hash雜湊遊戲原始碼丨雜湊競猜遊戲系統技術開發丨Hash雜湊遊戲講解遊戲原始碼