HTML 5开发RPG游戏之二(跑起来吧英雄)

开发 前端
要控制游戏的人物,首先,我们要由控制事件,当触发这个事件的时候,就来调用相应的方法,做我们想要的做的处理setCoordinate和getCoordinate是设定和得到人物当前的坐标。

上一篇中,已经详细讲解了,如何添加地图,以及添加了一个游戏人物,现在我们来添加控制事件,让这个小英雄走动起来

0_1323875534sUfb (1).gif

我们已经给游戏人物建立了一个Character类,

现在先来在类里加入

  1. Character.prototype.changeDir = function (dir){  
  2. };  
  3. /**  
  4.  * 设定人物坐标  
  5.  * @param x方向坐标,y方向坐标   
  6.  **/  
  7. Character.prototype.setCoordinate = function (sx,sy){  
  8. };  
  9. /**  
  10.  * 获取人物坐标  
  11.  **/  
  12. Character.prototype.getCoordinate = function (){  
  13. }; 

changeDir 这个方法用来从外部控制人物方向和移动

要控制游戏的人物,首先,我们要由控制事件,当触发这个事件的时候,就来调用相应的方法,做我们想要的做的处理setCoordinate和getCoordinate是设定和得到人物当前的坐标

首先,为了适应智能手机,我们暂时不用键盘事件,而是用点击事件,所以我们先来添加两个控制按钮,在Main.js的gameInit方法的最下方,添加如下代码

  1. //添加控制按钮  
  2.     bitmapdata = new LBitmapData(imglist["e1"]);  
  3.     bitmap = new LBitmap(bitmapdata);  
  4.     bitmap.x = 0;  
  5.     bitmap.y = 0;  
  6.     ctrlLayer.addChild(bitmap);  
  7.     bitmapdata = new LBitmapData(imglist["e2"]);  
  8.     bitmap = new LBitmap(bitmapdata);  
  9.     bitmap.x = 280;  
  10.     bitmap.y = 30;  
  11.     ctrlLayer.addChild(bitmap);  
  12.     ctrlLayer.x = 40;  
  13.     ctrlLayer.y = 180

运行代码,得到预览如下

0_1323996441iWWB.gif

在添加控制事件之前,为了实现控制方便,我们先来添加几个变量

  1. //方向变量  
  2. var DOWN = 0;  
  3. var LEFT = 1;  
  4. var RIGHT = 2;  
  5. var UP = 3;  
  6. var STEP = 32;  
  7. //点击状态  
  8. var isKeyDown = false

STEP代表移动步长,因为地图是有32*32的小图片来组成的,所以我们设定人物移动的步长为32

方向变量的0,1,2,3分别对应下面图片中的第1,2,3,4行的方向

0_1323998361U1vb.gif

之所以添加点击状态,是因为,当我们按下移动按钮没有抬起的时候,人物应该始终处于移动状态,所以用这个变量来区分,我们是否按下或者抬起好了,做好了准备工作,现在就开始添加移动事件

  1. //添加点击控制事件  
  2.     backLayer.addEventListener(LMouseEvent.MOUSE_DOWN,ondown);  
  3.     backLayer.addEventListener(LMouseEvent.MOUSE_UP,onup);  
  4.  
  5. function ondown(event){  
  6.     //根据点击位置,判断移动方向  
  7.     if(event.offsetX >= ctrlLayer.x + 40 && event.offsetX <= ctrlLayer.x+80){  
  8.         if(event.offsetY >= ctrlLayer.y && event.offsetY <= ctrlLayer.y+40){  
  9.             player.changeDir(UP);  
  10.         }else if(event.offsetY >= ctrlLayer.y+80 && event.offsetY <= ctrlLayer.y+120){  
  11.             player.changeDir(DOWN);  
  12.         }  
  13.     }else if(event.offsetX >= ctrlLayer.x && event.offsetX <= ctrlLayer.x+40){  
  14.         if(event.offsetY >= ctrlLayer.y +40 && event.offsetY <= ctrlLayer.y+80){  
  15.             player.changeDir(LEFT);  
  16.         }  
  17.     }else if(event.offsetX >= ctrlLayer.x+80 && event.offsetX <= ctrlLayer.x+120){  
  18.         if(event.offsetY >= ctrlLayer.y +40 && event.offsetY <= ctrlLayer.y+80){  
  19.             player.changeDir(RIGHT);  
  20.         }  
  21.     }  
  22.     isKeyDown = true;  
  23. }  
  24. function onup(event){  
  25.     isKeyDown = false;  

这里需要知道的是,在智能手机里,其实点击事件是TOUCH_START,TOUCH_MOVE,TOUCH_END事件

使用legendForHtml5Programming库件的时候,只需要添加MOUSE_DOWN,MOUSE_MOVE,MOUSE_UP事件,然后库件会自动判断是加载TOUCH事件还是MOUSE事件

在ondown方法中,我们将isKeyDown的状态变为true,表示我们正处于按下状态

然后,根据我们点击的位置,来调用Character类的changeDir方法,并且传入点击的方向

有了控制事件,现在的关键就在于changeDir方法,只要根据传进来的值,来实现移动就可以了

我们试想,如果每次移动一个步长的话,那么人物就会由一个小方格跳到令一个方格,而我们需要的是,让它缓慢的移动到下一个方格,有一个移动的过程

为了实现这个过程,我们在移动的时候不是让人物的坐标马上就改变,而是改变人物的状态,由静止到移动,然后处于移动状态的时候,再让人物一小步一小步的移动到目标点

修改Character类的构造器,如下

  1. function Character(data,row,col,speed){  
  2.     base(this,LSprite,[]);  
  3.     var self = this;  
  4.     //设定人物动作速度  
  5.     self.speed = speed==null?3:speed;  
  6.     self.speedIndex = 0;  
  7.     //设定人物大小  
  8.     data.setProperties(0,0,data.image.width/col,data.image.height/row);  
  9.     //得到人物图片拆分数组  
  10.     var list = LGlobal.divideCoordinate(data.image.width,data.image.height,row,col);  
  11.     //设定人物动画  
  12.     self.anime = new LAnimation(this,data,list);  
  13.     //调整人物位置  
  14.     self.anime.y -= 16;  
  15.     //设定不移动  
  16.     self.move = false;  
  17.     //在一个移动步长中的移动次数设定  
  18.     self.moveIndex = 0;  
  19. }; 

调整人物位置是因为,人物的图片分割后,每个动作的大小为32*48,而地图每个小格的大小是32*32,然后设定人物状态为不移动,然后修改changeDir 方法

  1. /**  
  2.  * 改变人物方向  
  3.  **/ 
  4. Character.prototype.changeDir = function (dir){  
  5.     var self = this;  
  6.     //如果正在移动,则无效  
  7.     if(!self.move){  
  8.         //设定人物方向  
  9.         self.direction = dir;  
  10.         //设定图片动画  
  11.         self.anime.setAction(dir);  
  12.         //开始移动  
  13.         self.move = true;  
  14.         self.moveIndex = 0;  
  15.     }  
  16. }; 

这里要简单说明一下LAnimation类的setAction方法,setAction(rowindex,colindex)方法有两个参数,LAnimation里传进来的图片数组是一个二维数组,这两个参数分别可以改变目前显示的图片的动作,当然,也可以只传其中一个参数

我这次是将4*4的人物动作图片分割为4*4的二维数组传给了LAnimation类,所以现在每一行图片代表一个方向

人物状态设置为移动后,就应该在循环事件里开始一步步的移动了

  1. /**  
  2.  * 循环事件   
  3.  **/ 
  4. Character.prototype.onframe = function (){  
  5.     var self = this;  
  6.     //人物动作速度控制  
  7.     if(self.speedIndex++ < self.speed)return;  
  8.     self.speedIndex = 0;  
  9.     //当人物可移动,则开始移动  
  10.     if(self.move)self.onmove();  
  11.     //人物动画播放  
  12.     self.anime.onframe();  
  13. };  
  14. /**  
  15.  * 开始移动   
  16.  **/ 
  17. Character.prototype.onmove = function (){  
  18.     var self = this;  
  19.     //设定一个移动步长中的移动次数  
  20.     var ml_cnt = 4;  
  21.     //计算一次移动的长度  
  22.     var ml = STEP/ml_cnt;  
  23.     //根据移动方向,开始移动  
  24.     switch (self.direction){  
  25.         case UP:  
  26.             self.y -= ml;  
  27.             break;  
  28.         case LEFT:  
  29.             self.x -= ml;  
  30.             break;  
  31.         case RIGHT:  
  32.             self.x += ml;  
  33.             break;  
  34.         case DOWN:  
  35.             self.y += ml;  
  36.             break;  
  37.     }  
  38.     self.moveIndex++;  
  39.     //当移动次数等于设定的次数,开始判断是否继续移动  
  40.     if(self.moveIndex >= ml_cnt){  
  41.         self.moveIndex = 0;  
  42.         //如果已经松开移动键,则停止移动,否则继续移动  
  43.         if(!isKeyDown){  
  44.             self.move = false;  
  45.             return;  
  46.         }  
  47.     }  
  48. }; 

这里,我选择了让人物每个步长分四次进行移动,这样就实现了缓慢移动的效果,运行程序,点击画面中的方向键,看到了把,人物已经可以开始移动了,而且是缓慢的移动

1010.gif

#p#

但是,光这样还是不行,我们发现,人物是可以移动了,但是他现在是超人,飞檐走壁无所不入,移动的畅通无阻

这就需要我们在移动过程中,加入移动判断,看看是否可以移动,

为了实现这个判断,我们必须要知道地图什么地方可以移动,什么地方不可以移动

所以,我们需要一个地图的地形,如下

  1. //地图地形数组  
  2. var mapdata = [  
  3. [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],  
  4. [1,1,1,0,0,0,0,0,0,0,0,0,1,1,1],  
  5. [1,1,0,0,0,0,1,1,0,0,0,0,1,1,1],  
  6. [1,0,0,0,1,1,1,1,1,0,0,1,1,0,1],  
  7. [1,0,0,1,1,1,1,1,1,1,0,1,1,0,1],  
  8. [1,0,0,1,1,1,0,1,1,1,1,1,0,0,1],  
  9. [1,0,0,0,0,0,0,0,1,1,1,1,0,0,1],  
  10. [1,1,0,0,0,0,0,0,0,1,1,0,0,0,1],  
  11. [1,1,0,0,0,0,0,0,0,0,0,0,0,0,1],  
  12. [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]  
  13. ]; 

地形数组中,0代表可以移动,1代表障碍物,是不可移动的,接下来,给Character类添加判断方法

  1. /**  
  2.  * 障碍物判断  
  3.  * @param 判断方向   
  4.  **/ 
  5. Character.prototype.checkRoad = function (dir){  
  6.     var self = this;  
  7.     var tox,toy,myCoordinate;  
  8.     //当判断方向为空的时候,默认当前方向  
  9.     if(dir==null)dir=self.direction;  
  10.     //获取人物坐标  
  11.     myCoordinate = self.getCoordinate();  
  12.     //开始计算移动目的地的坐标  
  13.     switch (dir){  
  14.         case UP:  
  15.             tox = myCoordinate.x;  
  16.             toy = myCoordinate.y - 1;  
  17.             break;  
  18.         case LEFT:  
  19.             tox = myCoordinate.x - 1;  
  20.             toy = myCoordinate.y ;  
  21.             break;  
  22.         case RIGHT:  
  23.             tox = myCoordinate.x + 1;  
  24.             toy = myCoordinate.y;  
  25.             break;  
  26.         case DOWN:  
  27.             tox = myCoordinate.x;  
  28.             toy = myCoordinate.y + 1;  
  29.             break;  
  30.     }  
  31.     //如果移动的范围超过地图的范围,则不可移动  
  32.     if(tox <= 0 || toy <= 0)return false;  
  33.     if(toy >= mapdata.length || tox >= mapdata[0].length)return false;  
  34.     //如果目的地为障碍,则不可移动  
  35.     if(mapdata[toy][tox] == 1)return false;  
  36.     return true;  
  37. }; 

然后,在changeDir方法,和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.             self.y -= ml;  
  14.             break;  
  15.         case LEFT:  
  16.             self.x -= ml;  
  17.             break;  
  18.         case RIGHT:  
  19.             self.x += ml;  
  20.             break;  
  21.         case DOWN:  
  22.             self.y += ml;  
  23.             break;  
  24.     }  
  25.     self.moveIndex++;  
  26.     //当移动次数等于设定的次数,开始判断是否继续移动  
  27.     if(self.moveIndex >= ml_cnt){  
  28.         self.moveIndex = 0;  
  29.         //如果已经松开移动键,或者前方为障碍物,则停止移动,否则继续移动  
  30.         if(!isKeyDown || !self.checkRoad()){  
  31.             self.move = false;  
  32.             return;  
  33.         }  
  34.     }  
  35. };  
  36. /**  
  37.  * 改变人物方向,并判断是否可移动  
  38.  **/ 
  39. Character.prototype.changeDir = function (dir){  
  40.     var self = this;  
  41.     //如果正在移动,则无效  
  42.     if(!self.move){  
  43.         //设定人物方向  
  44.         self.direction = dir;  
  45.         //设定图片动画  
  46.         self.anime.setAction(dir);  
  47.         //判断是否可移动  
  48.         if(!self.checkRoad(dir))return;  
  49.         //如果可以移动,则开始移动  
  50.         self.move = true;  
  51.         self.moveIndex = 0;  
  52.     }  
  53. }; 

好了,大功告成,开始运行吧

测试URL如下:http://fsanguo.comoj.com/html5/rpg/index.html

这次的源代码下载:http://fsanguo.comoj.com/html5/rpg5/rpg5.rar

原文链接:http://www.cnblogs.com/html5cn/articles/2333828.html

【编辑推荐】

  1. HTML 5开发RPG游戏之一(地图人物实现)
  2. HTML 5开发RPG游戏之三(卷轴和对话)
  3. HTML 5开发RPG游戏之四(游戏脚本化)
  4. 开发HTML5跨平台游戏相关经验
  5. HTML 5开发的优秀网页游戏
责任编辑:张伟 来源: HTML5中国的博客
相关推荐

2010-07-13 09:31:08

RubyRuby on Rai

2009-04-29 14:40:17

2012-05-15 13:57:41

HTML5

2023-03-02 23:09:53

Node.jsC++JS

2012-05-15 13:44:00

HTML5中国

2011-05-04 11:26:47

优化

2021-01-22 14:03:34

Flutter系统鸿蒙

2012-05-15 13:10:57

HTML5

2021-01-12 11:12:58

大数据智慧交通

2024-05-27 09:01:22

2022-12-06 09:03:44

代码fork系统

2023-08-03 09:02:32

LangChain开发GLM

2015-08-04 17:46:19

戴尔anycloud云计算

2022-01-10 10:23:07

浏览器Vitenode

2017-11-17 15:25:02

Java线程安全

2021-11-10 10:00:48

鸿蒙HarmonyOS应用

2023-01-31 07:42:29

代码JDKMaven

2014-04-18 17:12:00

乐跑手环

2012-01-06 14:10:13

HTML 5

2012-05-15 10:35:35

HTML5
点赞
收藏

51CTO技术栈公众号