搜尋
首頁web前端H5教程零基础开发RPG游戏开源讲座(四)-游戏脚本化&地图跳转

了解上三篇的内容请点击:

html5[color=rgb(68, 68, 68) !important]游戏
开发-零基础开发RPG游戏-开源讲座(一)

http://www.html5cn.org/article-1737-1.html

html5游戏开发-零基础开发RPG游戏-开源讲座(二)-跑起来吧英雄

http://www.html5cn.org/article-1738-1.html

html5游戏开发-零基础开发RPG游戏-开源讲座(三)-卷轴&对话实现

http://www.html5cn.org/article-1740-1.html


首先,本篇文章是零基础开发RPG游戏-开源讲座系列文章的第四篇,来实现游戏的脚本化,和利用游戏脚本实现地图场景的切换。如下应该是我们先了解的。

一,什么是游戏脚本

简单说,游戏脚本就是依据一定的格式编写的可执行文件,游戏可以通过脚本中自定义的语句来执行相应的逻辑。

二,为什么要将游戏脚本化

游戏脚本,可以令我们的游戏动态化,比如当我们开发了一款rpg游戏,里面的剧情,事件以及地图等,我们如果将这些全部写进程序里,当然是可以的,但是一旦出现问题,哪怕几个错别字,我们需要先将这几个错别字改正,并且将整个程序重新编译发布一遍,这个过程是相当令人反感的,因为如果游戏的程序跟着游戏的内容不断进行修改的话,那只会使你的程序越来越复杂。但是如果我们将这些可重复的数据,都定义到游戏程序之外的文件里面,当游戏引擎开发完毕,我们的游戏通过读取这些外部文件,来执行相应的剧情和事件,那么,像上述当我们的游戏出现了问题,我们只需要改动这些外部文件就可以了,并不需要重新编译整个程序,这样便使得我们的游戏开发,变得便利简洁。

*当然,对于html5来说,不需要重新编译程序,但是对于rpg的游戏来说,脚本还是必不可少的,因为游戏的剧本不可能全都写到程序里。

三,如何来实现游戏的脚本化

好了,接下来,先来考虑以什么形式来制作游戏的脚本,我们有多种选择,可以选择xml,可以选择json,也可以选择纯自定义语法,

这次,我为了省事,选用比较方便处理的json,因为javascript可以很轻松的处理json数据。

目前游戏中实现的内容有,地图场景添加,游戏人物添加,以及人物对话的实现。那么,我在设计游戏脚本的时候,必须包含这些数据,然后才能将这三项功能用脚本来控制。

首先看下面的json
  1. var script = {
  2.         stage01:{
  3.                 map:[
  4.                     [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18,18,18],
  5.                         [18,18,18,17,17,17,17,17,17,17,17,17,55,55,17,17,18],
  6.                         [18,18,17,17,17,17,18,18,17,17,17,17,55,55,17,17,18],
  7.                         [18,17,17,17,18,18,18,18,18,17,17,55,55,17,17,17,18],
  8.                         [18,17,17,18,22,23,23,23,24,18,17,55,55,17,17,17,18],
  9.                         [18,17,17,18,25,28,26,79,27,18,55,55,17,17,17,17,18],
  10.                         [18,17,17,17,17,10,11,12,18,18,55,55,17,17,17,17,18],
  11.                         [18,18,17,17,10,16,16,16,11,55,55,17,17,17,17,17,18],
  12.                         [18,18,17,17,77,16,16,16,16,21,21,17,17,17,17,17,18],
  13.                         [18,18,17,17,77,16,16,16,16,55,55,17,17,17,17,17,18],
  14.                         [18,18,18,18,18,18,18,18,18,55,55,18,18,18,18,18,18]],
  15.                 mapdata:[
  16.                         [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
  17.                         [1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,1],
  18.                         [1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1],
  19.                         [1,0,0,0,1,1,1,1,1,0,0,1,1,0,0,0,1],
  20.                         [1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,0,1],
  21.                         [1,0,0,1,1,1,0,1,1,1,1,1,0,0,0,0,1],
  22.                         [1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1],
  23.                         [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1],
  24.                         [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  25.                         [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1],
  26.                         [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]],
  27.                 add:[
  28.                      {chara:"player",img:"mingren",x:5,y:6},
  29.                      {chara:"npc",img:"npc1",x:7,y:6},
  30.                      {chara:"npc",img:"npc1",x:3,y:3}],
  31.                 talk:{
  32.                         talk1:[
  33.                                       {img:"m",name:"鸣人",msg:"我是木叶村的鸣人,你是谁?"},
  34.                                       {img:"n",name:"黑衣忍者甲",msg:"你就是鸣人?九尾还在你身体里吗?"}
  35.                               ],
  36.                     talk2:[
  37.                                   {img:"n",name:"黑衣忍者乙",msg:"鸣人,听说忍者大战就要开始了。"},
  38.                                       {img:"m",name:"鸣人",msg:"真的吗?一定要想想办法啊。"}
  39.                               ]
  40.                 }
  41.         }


  42. };
复制代码

我将脚本定义成了变量,实际游戏制作的时候,脚本应该储存到一个外部文档当中,在这里我只是讲解一下理论,如何完善那是后话了。

可以看到,json中,包含了地图相关的map数组和mapdata数组,添加人物的相关数据,以及对话的数组。这样,我在游戏显示的时候,只需要读入json数据,然后根据这些内容来显示游戏画面就可以了,定义一个initScript函数来进行这些操作。
  1. function initScript(){
  2.         //地图位置初始化
  3.         mapLayer.x = 0;
  4.         mapLayer.y = 0;


  5.         //地图层初始化
  6.         mapLayer.removeAllChild();
  7.         //人物层初始化
  8.         charaLayer.removeAllChild();
  9.         //效果层初始化
  10.         effectLayer.removeAllChild();
  11.         //对话层初始化
  12.         talkLayer.removeAllChild();
  13.         
  14.         //地图数据获取
  15.         map = stage.map;
  16.         mapdata = stage.mapdata;
  17.         //对话数据获取
  18.         talkScriptList = stage.talk;
  19.         
  20.         //添加地图
  21.         addMap(0,0);
  22.         delMap();
  23.         //添加人物
  24.         addChara();
  25. }
复制代码

removeAllChild方法是legendForHtml5Programming引擎独有的方法,可以用来移出LScript显示层上的所有子对象,从而实现本游戏中各个显示层的初始化工作。

修改一下addChara方法,如下
  1. //添加人物
  2. function addChara(){
  3.         var charaList = stage.add;
  4.         var chara,charaObj;
  5.         for(var i=0;i ;i++){
  6.                 charaObj = charaList[i];
  7.                 if(charaObj.chara == "player"){
  8.                         //加入英雄
  9.                         bitmapdata = new LBitmapData(imglist[charaObj.img]);
  10.                         chara = new Character(true,i,bitmapdata,4,4);
  11.                         player = chara;
  12.                 }else{
  13.                         //加入npc
  14.                         bitmapdata = new LBitmapData(imglist[charaObj.img]);
  15.                         chara = new Character(false,i,bitmapdata,4,4);
  16.                 }
  17.                 chara.x = charaObj.x * 32;
  18.                 chara.y = charaObj.y * 32;
  19.                 charaLayer.addChild(chara);
  20.         }
  21. }
复制代码

即,根据json脚本中的add数组,来添加游戏中的人物。

好了,运行一下游戏,可以看到,游戏正常显示了,和之前一模一样,实现了同样的功能。

1122.jpg



四,利用游戏脚本实现地图的切换

为了让大家看到游戏脚本的便利性,现在利用脚本实现游戏中的场景切换。

将json脚本修改如下
  1. var script = {
  2.         stage01:{
  3.                 map:[
  4.                     [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18,18,18],
  5.                         [18,18,18,17,17,17,17,17,17,17,17,17,55,55,17,17,18],
  6.                         [18,18,17,17,17,17,18,18,17,17,17,17,55,55,17,17,18],
  7.                         [18,17,17,17,18,18,18,18,18,17,17,55,55,17,17,17,18],
  8.                         [18,17,17,18,22,23,23,23,24,18,17,55,55,17,17,17,18],
  9.                         [18,17,17,18,25,28,26,79,27,18,55,55,17,17,17,17,18],
  10.                         [18,17,17,17,17,10,11,12,18,18,55,55,17,17,17,17,18],
  11.                         [18,18,17,17,10,16,16,16,11,55,55,17,17,17,17,17,18],
  12.                         [18,18,17,17,77,16,16,16,16,21,21,17,17,17,17,17,18],
  13.                         [18,18,17,17,77,16,16,16,16,55,55,17,17,17,17,17,18],
  14.                         [18,18,18,18,18,18,18,18,18,55,55,18,18,18,18,18,18]],
  15.                 mapdata:[
  16.                         [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
  17.                         [1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,1],
  18.                         [1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1],
  19.                         [1,0,0,0,1,1,1,1,1,0,0,1,1,0,0,0,1],
  20.                         [1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,0,1],
  21.                         [1,0,0,1,1,1,0,1,1,1,1,1,0,0,0,0,1],
  22.                         [1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1],
  23.                         [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1],
  24.                         [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  25.                         [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1],
  26.                         [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]],
  27.                 add:[
  28.                      {chara:"player",img:"mingren",x:5,y:6},
  29.                      {chara:"npc",img:"npc1",x:7,y:6},
  30.                      {chara:"npc",img:"npc1",x:3,y:3}],
  31.                 talk:{
  32.                         talk1:[
  33.                                       {img:"m",name:"鸣人",msg:"我是木叶村的鸣人,你是谁?"},
  34.                                       {img:"n",name:"黑衣忍者甲",msg:"你就是鸣人?九尾还在你身体里吗?"}
  35.                               ],
  36.                     talk2:[
  37.                                   {img:"n",name:"黑衣忍者乙",msg:"鸣人,听说忍者大战就要开始了。"},
  38.                                       {img:"m",name:"鸣人",msg:"真的吗?一定要想想办法啊。"}
  39.                               ]
  40.                 },
  41.                 jump:[
  42.                       {at:{x:6,y:5},to:"stage02"}
  43.                 ]
  44.         },
  45.         stage02:{
  46.                 map:[
  47.                     [0,0,1,2,2,2,2,2,2,2,2,1,0,0,0],
  48.                     [0,0,1,3,5,5,1,5,5,5,5,1,0,0,0],
  49.                     [0,0,1,80,4,4,1,80,4,4,4,1,0,0,0],
  50.                     [0,0,1,80,4,4,1,80,8,7,8,1,0,0,0],
  51.                         [0,0,1,80,4,4,5,81,4,4,4,1,0,0,0],
  52.                         [0,0,1,2,2,2,6,4,4,4,4,1,0,0,0],
  53.                         [0,0,1,3,5,5,81,4,4,4,4,1,0,0,0],
  54.                         [0,0,1,80,4,4,4,4,4,4,9,1,0,0,0],
  55.                         [0,0,1,2,2,2,2,6,2,2,2,1,0,0,0]],
  56.                 mapdata:[
  57.                         [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
  58.                         [1,1,1,0,0,0,1,0,0,0,0,1,1,1,1],
  59.                         [1,1,1,0,0,0,1,0,0,0,0,1,1,1,1],
  60.                         [1,1,1,0,0,0,1,0,0,1,0,1,1,1,1],
  61.                         [1,1,1,0,0,0,0,0,0,0,0,1,1,1,1],
  62.                         [1,1,1,1,1,1,0,0,0,0,0,1,1,1,1],
  63.                         [1,1,1,0,0,0,0,0,0,0,0,1,1,1,1],
  64.                         [1,1,1,0,0,0,0,0,0,0,1,1,1,1,1],
  65.                         [1,1,1,1,1,1,1,0,1,1,1,1,1,1,1]],
  66.                 add:[
  67.                      {chara:"player",img:"mingren",x:7,y:8},
  68.                      {chara:"npc",img:"npc1",x:8,y:3},
  69.                      {chara:"npc",img:"npc1",x:10,y:3}],
  70.                 talk:{
  71.                       talk1:[
  72.                                     {img:"m",name:"鸣人",msg:"你们在干什么啊?"},
  73.                                             {img:"n",name:"黑衣忍者甲",msg:"我们在喝茶。"}
  74.                               ],
  75.                       talk2:[
  76.                                         {img:"n",name:"黑衣忍者乙",msg:"我们在喝茶,你不要打扰我们。"},
  77.                                             {img:"m",name:"鸣人",msg:"....."}
  78.                               ]
  79.                 },
  80.                 jump:[
  81.                       {at:{x:7,y:8},to:"stage01"}
  82.                 ]
  83.         }


  84. };
复制代码

可以看到,我添加了stage02,即第二个场景,并且在脚本里引入了jump节点来控制游戏场景的切换,其中jump中的at表示游戏主人公移动到达的坐标,to表示到达这个坐标后跳转到的画面名称。这里的jump之所以是数组,是因为一个场景也可以跳转到其他多个场景。

上面的脚本实现了stage01和stage02两个场景的互相跳转。

为了读取这个jump,以及实现跳转,我们需要在游戏主人公移动一个步长之后,判断一下是否应该跳转了,修改Character类的onmove方法
  1. /**
  2. * 开始移动
  3. **/
  4. Character.prototype.onmove = function (){
  5.         var self = this;
  6.         //设定一个移动步长中的移动次数
  7.         var ml_cnt = 4;
  8.         //计算一次移动的长度
  9.         var ml = STEP/ml_cnt;
  10.         //根据移动方向,开始移动
  11.         switch (self.direction){
  12.                 case UP:
  13.                         if(mapmove){
  14.                                 mapLayer.y += ml;
  15.                                 charaLayer.y += ml;
  16.                         }
  17.                         self.y -= ml;
  18.                         break;
  19.                 case LEFT:
  20.                         if(mapmove){
  21.                                 mapLayer.x += ml;
  22.                                 charaLayer.x += ml;
  23.                         }
  24.                         self.x -= ml;
  25.                         break;
  26.                 case RIGHT:
  27.                         if(mapmove){
  28.                                 mapLayer.x -= ml;
  29.                                 charaLayer.x -= ml;
  30.                         }
  31.                         self.x += ml;
  32.                         break;
  33.                 case DOWN:
  34.                         if(mapmove){
  35.                                 mapLayer.y -= ml;
  36.                                 charaLayer.y -= ml;
  37.                         }
  38.                         self.y += ml;
  39.                         break;
  40.         }
  41.         self.moveIndex++;
  42.         //当移动次数等于设定的次数,开始判断是否继续移动
  43.         if(self.moveIndex >= ml_cnt){
  44.                 //一个地图步长移动完成后,判断地图是否跳转
  45.                 if(self.isHero && self.moveIndex > 0)checkJump();
  46.                 self.moveIndex = 0;
  47.                 //一个地图步长移动完成后,如果地图处于滚动状态,则移除多余地图块
  48.                 if(mapmove)delMap();
  49.                 //如果已经松开移动键,或者前方为障碍物,则停止移动,否则继续移动
  50.                 if(!isKeyDown || !self.checkRoad()){
  51.                         self.move = false;
  52.                         return;
  53.                 }else if(self.direction != self.direction_next){
  54.                         self.direction = self.direction_next;
  55.                         self.anime.setAction(self.direction);
  56.                 }
  57.                 //地图是否滚动
  58.                 self.checkMap(self.direction);
  59.         }
  60. };
复制代码
我添加了一行
  1. if(self.isHero && self.moveIndex > 0)checkJump();
复制代码

表示,移动完后如果该人物是游戏主人公则进行跳转判断

所以,我们需要添加一个checkJump方法
  1. //游戏场景跳转测试
  2. function checkJump(){
  3.         var jump = stage.jump;
  4.         var jumpstage;
  5.         for(var i=0;i ;i++){
  6.                 jumpstage = jump[0];
  7.                 if(player.x == jumpstage.at.x * 32 && player.y == jumpstage.at.y * 32){
  8.                         //获取该场景脚本数据
  9.                         stage = script[jumpstage.to];
  10.                         //开始跳转
  11.                         initScript(stage);
  12.                         return;
  13.                 }
  14.         }
  15. }
复制代码

好了,一切都很简单吧,运行游戏看看效果吧,小鸣人走到地图的小房门的部分是,场景发生跳转

12121.jpg




游戏测试URL:

http://fsanguo.comoj.com/html5/rpg5/index.html

本次更新源代码下载:

http://legend-demo.googlecode.com/files/rpg5.zip



本文转自个人博客:http://blog.csdn.net/lufy_legend
陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
了解HTML音頻和視頻:屬性和可訪問性了解HTML音頻和視頻:屬性和可訪問性May 16, 2025 am 12:05 AM

html5audioandvideoelementsenhanceFunctionality and acctibility and actificatificatifutes.1)'Concontrols'AttributeaddsStandArdPlayBackControls,而'aria-aria-label'improvesscreenReaderAccesctibility.2)

掌握microdata:HTML5的分步指南掌握microdata:HTML5的分步指南May 14, 2025 am 12:07 AM

Microdatainhtml5enhancesseoanduserexperienceByByBybyBystructuredDatatoSearchEngines.1)useIteMscope,itemType,anditempropattributestomarkupcontentlikeSoreRoductSssSssSoRorevents.2)

HTML5表格中有什麼新功能?探索新輸入類型HTML5表格中有什麼新功能?探索新輸入類型May 13, 2025 pm 03:45 PM

html5introducesnewinputtypesthatenhanceSerexperience,簡化開發和iMproveAccessibility.1)自動validatesemailformat.2)優化優化,優化OmportizeSmizesemizesemizesemizesemizesemizeSmobobileWithAnumericKeyPad.3)和Simimplifydateandtimeputientupits,並重新替代了Forcustemolcustemolcustene。

理解H5:含義和意義理解H5:含義和意義May 11, 2025 am 12:19 AM

H5是HTML5,是HTML的第五個版本。 HTML5提升了網頁的表現力和交互性,引入了語義化標籤、多媒體支持、離線存儲和Canvas繪圖等新特性,推動了Web技術的發展。

H5:可訪問性和網絡標準合規性H5:可訪問性和網絡標準合規性May 10, 2025 am 12:21 AM

無障礙訪問和網絡標準遵循對網站至關重要。 1)無障礙訪問確保所有用戶都能平等訪問網站,2)網絡標準遵循提高網站的可訪問性和一致性,3)實現無障礙訪問需使用語義化HTML、鍵盤導航、顏色對比度和替代文本,4)遵循這些原則不僅是道德和法律要求,還能擴大用戶群體。

HTML中的H5標籤是什麼?HTML中的H5標籤是什麼?May 09, 2025 am 12:11 AM

HTML中的H5標籤是第五級標題,用於標記較小的標題或子標題。 1)H5標籤幫助細化內容層次,提升可讀性和SEO。 2)結合CSS可定製樣式,增強視覺效果。 3)合理使用H5標籤,避免濫用,確保內容結構邏輯性。

H5代碼:Web結構的初學者指南H5代碼:Web結構的初學者指南May 08, 2025 am 12:15 AM

HTML5構建網站的方法包括:1.使用語義化標籤定義網頁結構,如、、等;2.嵌入多媒體內容,使用和標籤;3.應用表單驗證和本地存儲等高級功能。通過這些步驟,你可以創建一個結構清晰、功能豐富的現代網頁。

H5代碼結構:組織內容以實現可讀性H5代碼結構:組織內容以實現可讀性May 07, 2025 am 12:06 AM

通過合理的H5代碼結構可以讓頁面在眾多內容中脫穎而出。 1)使用語義化標籤如、、等組織內容,使結構清晰。 2)通過CSS佈局如Flexbox或Grid控制頁面在不同設備上的呈現效果。 3)實現響應式設計,確保頁面在不同屏幕尺寸上自適應。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)