HTML5教程

当前位置: HTML5技术网 > HTML5教程 > html5游戏开发-零基础开发RPG游戏-开源讲座(三)-卷轴&对话实现 ... ...

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

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

html5游戏开发-零基础开发RPG游戏-开源讲座(一)

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

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

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

前两篇,RPG的开发已经实现了添加地图和添加游戏人物,本篇来实现地图的卷轴滚动和人物对话的实现,效果如下




本次开发,更新了一下库件至1.3,请点击下面的链接,下载库件1.3版以上版本

http://code.google.com/p/legendforhtml5programming/downloads/list

地图的滚动

关于地图的滚动原理,可以参照下图




按照上图说明,实现地图滚动,只需要先把即将出现的地图(图中黄色部分)画上,然后滚动地图,待地图滚动完毕之后,将屏幕之外的部分(图中绿色部分)移除

首先要添加一个变量来控制地图是否滚动
  1. //地图滚动
  2. var mapmove = false;
复制代码
然后,在人物移动的时候,判断地图是否需要滚动
  1. /**
  2. * 地图是否滚动
  3. **/
  4. Character.prototype.checkMap = function (dir){
  5.         var self = this;
  6.         mapmove = false;
  7.         //如果不是英雄,则地图不需要滚动
  8.         if(!self.isHero)return;
  9.        
  10.         switch (dir){
  11.                 case UP:
  12.                         if(self.y + charaLayer.y> STEP)break;
  13.                         if(mapLayer.y >= 0)break;
  14.                         addMap(0,-1);
  15.                         mapmove = true;
  16.                         break;
  17.                 case LEFT:
  18.                         if(self.x + charaLayer.x > STEP)break;
  19.                         if(mapLayer.x >= 0)break;
  20.                         addMap(-1,0);
  21.                         mapmove = true;
  22.                         break;
  23.                 case RIGHT:
  24.                         if(self.x < 480 - 2*STEP)break;
  25.                         if(480 - mapLayer.x >= map[0].length*STEP)break;
  26.                         addMap(1,0);
  27.                         mapmove = true;
  28.                         break;
  29.                 case DOWN:
  30.                         if(self.y < 288 - 2*STEP)break;
  31.                         if(288 - mapLayer.y >= map.length*STEP)break;
  32.                         addMap(0,1);
  33.                         mapmove = true;
  34.                         break;
  35.         }
  36. };
复制代码
在移动过程中,判断地图是否处于滚动状态,如果地图处于滚动,则滚动地图,否则移动人物
  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(mapmove)delMap();
  46.                 self.moveIndex = 0;
  47.                 //如果已经松开移动键,或者前方为障碍物,则停止移动,否则继续移动
  48.                 if(!isKeyDown || !self.checkRoad()){
  49.                         self.move = false;
  50.                         return;
  51.                 }else if(self.direction != self.direction_next){
  52.                         self.direction = self.direction_next;
  53.                         self.anime.setAction(self.direction);
  54.                 }
  55.                 //地图是否滚动
  56.                 self.checkMap(self.direction);
  57.         }
  58. };
复制代码
最后,将地图的数组和地形扩大为大于屏幕大小
  1. //地图图片数组
  2. var map = [
  3. [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18,18,18],
  4. [18,18,18,17,17,17,17,17,17,17,17,17,55,55,17,17,18],
  5. [18,18,17,17,17,17,18,18,17,17,17,17,55,55,17,17,18],
  6. [18,17,17,17,18,18,18,18,18,17,17,55,55,17,17,17,18],
  7. [18,17,17,18,22,23,23,23,24,18,17,55,55,17,17,17,18],
  8. [18,17,17,18,25,28,26,79,27,18,55,55,17,17,17,17,18],
  9. [18,17,17,17,17,10,11,12,18,18,55,55,17,17,17,17,18],
  10. [18,18,17,17,10,16,16,16,11,55,55,17,17,17,17,17,18],
  11. [18,18,17,17,77,16,16,16,16,21,21,17,17,17,17,17,18],
  12. [18,18,17,17,77,16,16,16,16,55,55,17,17,17,17,17,18],
  13. [18,18,18,18,18,18,18,18,18,55,55,18,18,18,18,18,18]
  14. ];
  15. //地图地形数组
  16. var mapdata = [
  17. [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
  18. [1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,1],
  19. [1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1],
  20. [1,0,0,0,1,1,1,1,1,0,0,1,1,0,0,0,1],
  21. [1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,0,1],
  22. [1,0,0,1,1,1,0,1,1,1,1,1,0,0,0,0,1],
  23. [1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1],
  24. [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1],
  25. [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
  26. [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1],
  27. [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
  28. ];
复制代码
为了实现地图滚动,修改添加地图的方法,根据参数来实现添加上面图片的黄色地图部分
  1. //添加地图
  2. function addMap(cx,cy){
  3.         var i,j,index,indexX,indexY;
  4.         var bitmapdata,bitmap;
  5.         var mapX = mapLayer.x / STEP;
  6.         var mapY = mapLayer.y / STEP;
  7.         var mx = cx<0?-1:0,my = cy<0?-1:0;
  8.         if(imageArray == null){
  9.                 //地图图片数据
  10.                 bitmapdata = new LBitmapData(imglist["map"]);
  11.                 //将地图图片拆分,得到拆分后的各个小图片的坐标数组
  12.                 imageArray = LGlobal.divideCoordinate(bitmapdata.image.width,bitmapdata.image.height,10,10);
  13.         }
  14.         mapLayer.removeAllChild();
  15.         //在地图层上,画出15*10的小图片
  16.         for(i=my;i<9 +Math.abs(cy) && i-mapY < map.length;i++){
  17.                 for(j=mx;j<15 +Math.abs(cx)&& j-mapX < map[0].length;j++){
  18.                         //从地图数组中得到相应位置的图片坐标
  19.                         index = map[i-mapY][j-mapX];
  20.                         //小图片的竖坐标
  21.                         indexY = Math.floor(index /10);
  22.                         //小图片的横坐标
  23.                         indexX = index - indexY*10;
  24.                         //得到小图片
  25.                         bitmapdata = new LBitmapData(imglist["map"],indexX*32,indexY*32,32,32);
  26.                         bitmap = new LBitmap(bitmapdata);
  27.                         //设置小图片的显示位置
  28.                         bitmap.x = j*STEP - mapLayer.x;
  29.                         bitmap.y = i*STEP - mapLayer.y;
  30.                         //将小图片显示到地图层
  31.                         mapLayer.addChild(bitmap);
  32.                 }
  33.         }
  34. }
  35. //移除多余地图块
  36. function delMap(){
  37.         var bitmap,i;
  38.         for(i=0;i
  39.                 bitmap = mapLayer.childList[i];
  40.                 if(bitmap.x + mapLayer.x < 0 || bitmap.x + mapLayer.x >= 480 ||
  41.                                 bitmap.y + mapLayer.y < 0 || bitmap.y + mapLayer.y >= 288){
  42.                         mapLayer.removeChild(bitmap);
  43.                         i--;
  44.                 }
  45.         }
  46. }
复制代码

看一下效果如下




人物的对话

对话的实现,在点击控制按钮的方形按钮时添加,所以,先在鼠标抬起的时候,判断是否点击了方形按钮
  1. function onup(event){
  2.         isKeyDown = false;
  3.         if(event.offsetX >= ctrlLayer.x + 280 && event.offsetX <= ctrlLayer.x+330){
  4.                 if(event.offsetY >= ctrlLayer.y+40 && event.offsetY <= ctrlLayer.y+100){
  5.                         //对话
  6.                         addTalk();
  7.                 }
  8.         }
  9. }
复制代码
在完善addTalk()方法的时候,首先准备好对话的内容
  1. var talkScriptList = {
  2.         "talk1":new Array(
  3.                 {img:"m",name:"鸣人",msg:"我是木叶村的鸣人,你是谁?"},
  4.                 {img:"n",name:"黑衣忍者甲",msg:"你就是鸣人?九尾还在你身体里吗?"}
  5.                 ),
  6.         "talk2":new Array(
  7.                 {img:"n",name:"黑衣忍者乙",msg:"鸣人,听说忍者大战就要开始了。"},
  8.                 {img:"m",name:"鸣人",msg:"真的吗?一定要想想办法啊。"}
  9.                 )
  10. };
复制代码
talk1,talk2中talk后面的数字,代表人物的编号,其中每个对话单位的img为人物的头像,name为人物的名称,msg为对话的内容

添加对话时的做法是,当点击方形按钮后,判断小鸣人前方是否有人,如果有人,则将这个人物的编号取出来,再从上面的数组中获取相应的对话内容,然后,将相应的内容显示到游戏屏幕上,具体实现代码如下
  1. //对话内容
  2. var talkScript;
  3. var talkScriptList = {
  4.         "talk1":new Array(
  5.                 {img:"m",name:"鸣人",msg:"我是木叶村的鸣人,你是谁?"},
  6.                 {img:"n",name:"黑衣忍者甲",msg:"你就是鸣人?九尾还在你身体里吗?"}
  7.                 ),
  8.         "talk2":new Array(
  9.                 {img:"n",name:"黑衣忍者乙",msg:"鸣人,听说忍者大战就要开始了。"},
  10.                 {img:"m",name:"鸣人",msg:"真的吗?一定要想想办法啊。"}
  11.                 )
  12. };
  13. //对话序号
  14. var talkIndex = 0;
  15. //对话中
  16. var talking = false;

  17. /**
  18. * 添加对话
  19. * */
  20. function addTalk(){
  21.         //如果对话内容为空,则开始判断是否可以对话
  22.         if(talkScript == null){
  23.                 var key,tx = player.x,ty = player.y;
  24.                 switch (player.direction){
  25.                 case UP:
  26.                         ty -= STEP;
  27.                         break;
  28.                 case LEFT:
  29.                         tx -= STEP;
  30.                         break;
  31.                 case RIGHT:
  32.                         tx += STEP;
  33.                         break;
  34.                 case DOWN:
  35.                         ty += STEP;
  36.                         break;
  37.                 }
  38.                 for(key in charaLayer.childList){
  39.                         //判断前面又没有npc,有则开始对话
  40.                         if(charaLayer.childList[key].x == tx && charaLayer.childList[key].y == ty){
  41.                                 if(talkScriptList["talk"+charaLayer.childList[key].index]){
  42.                                         talkScript = talkScriptList["talk"+charaLayer.childList[key].index];
  43.                                         talkIndex = 0;
  44.                                 }
  45.                         }
  46.                 }
  47.                 //如果前方没有npc,则返回
  48.                 if(talkScript == null)return;
  49.         }
  50.         //将对话层清空
  51.         talkLayer.removeAllChild();
  52.         //当对话开始,且按照顺序进行对话
  53.         if(talkIndex < talkScript.length){
  54.                 //得到对话内容
  55.                 var talkObject = talkScript[talkIndex];
  56.                 //对话背景
  57.                 bitmapdata = new LBitmapData(imglist["talk"]);
  58.                 bitmap = new LBitmap(bitmapdata);
  59.                 bitmap.width = 330;
  60.                 bitmap.height = 70;
  61.                 bitmap.x = 100;
  62.                 bitmap.y = 20;
  63.                 bitmap.alpha = 0.7;
  64.                 talkLayer.addChild(bitmap);
  65.                 //对话头像
  66.                 bitmapdata = new LBitmapData(imglist[talkObject.img]);
  67.                 bitmap = new LBitmap(bitmapdata);
  68.                 bitmap.x = 0;
  69.                 bitmap.y = 0;
  70.                 talkLayer.addChild(bitmap);
  71.                 //对话人物名称
  72.                 var name = new LTextField();
  73.                 name.x = 110;
  74.                 name.y = 30;
  75.                 name.size = "14";
  76.                 name.color = "#FFFFFF";
  77.                 name.text = "[" + talkObject.name + "]";
  78.                 talkLayer.addChild(name);
  79.                 //对话内容
  80.                 var msg = new LTextField();
  81.                 msg.x = 110;
  82.                 msg.y = 55;
  83.                 msg.color = "#FFFFFF";
  84.                 msg.text = talkObject.msg;
  85.                 talkLayer.addChild(msg);
  86.                 //对话内容逐字显示
  87.                 msg.wind();
  88.                 talkLayer.x = 20;
  89.                 talkLayer.y = 50;
  90.                 talkIndex++;
  91.         }else{
  92.                 //对话结束
  93.                 talkScript = null;
  94.         }
  95. }
复制代码
效果看下图





游戏演示地址

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

之前其他地方也稍微做了修改,具体修改请看源代码,此次更新源代码,下载地址如下

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



本文转自个人博客:http://blog.csdn.net/lufy_legend

【html5游戏开发-零基础开发RPG游戏-开源讲座(三)-卷轴&对话实现 ... ...】相关文章

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

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

3. html5游戏开发-零基础开发RPG游戏-开源讲座(一)

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

5. BrowserQuest:开源的基于HTML5的多人在线RPG游戏

6. rpgjs-demo

7. Wix让你零基础打造HTML5页面

8. HTML5游戏开发工具推荐:IMPACT

9. 游戏开发技术的新革命!丰富多彩的HTML5游戏

10. css3对话框设计

本文来源:https://www.51html5.com/a625.html

点击展开全部

﹝html5游戏开发-零基础开发RPG游戏-开源讲座(三)-卷轴&对话实现 ... ...﹞相关内容

「html5游戏开发-零基础开发RPG游戏-开源讲座(三)-卷轴&对话实现 ... ...」相关专题

其它栏目

也许您还喜欢