• 技术文章 >web前端 >H5教程

    零基础开发RPG游戏开源讲座(四)-游戏脚本化&地图跳转

    2016-05-17 09:09:01原创931
    了解上三篇的内容请点击:

    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. map = stage.map;
    15. mapdata = stage.mapdata;
    16. //对话数据获取
    17. talkScriptList = stage.talk;

    18. //添加地图
    19. addMap(0,0);
    20. delMap();
    21. //添加人物
    22. addChara();
    23. }
    复制代码

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

    修改一下addChara方法,如下
    1. //添加人物
    2. function addChara(){
    3. var charaList = stage.add;
    4. var chara,charaObj;
    5. for(var i=0;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
    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核实处理。
    上一篇:HTML5技术之图像处理:一个滑动的拼图游戏 下一篇:HTML5每日一练之Canvas标签的应用
    PHP编程就业班

    相关文章推荐

    • html5离线存储有哪些• 深入解析asp.net中mvc4自定义404页面(分享)• h5新增标签audio与video的使用• 在今天,利用 HTML5 开发和发布大型跨平台网游,可行性如何?要解决哪些问题?• 避免常见的六种HTML5错误用法 (5-6)

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网