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

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

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

    了解上一篇内容请看这里

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

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

    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. function ondown(event){
    5. //根据点击位置,判断移动方向
    6. if(event.offsetX >= ctrlLayer.x + 40 && event.offsetX <= ctrlLayer.x+80){
    7. if(event.offsetY >= ctrlLayer.y && event.offsetY <= ctrlLayer.y+40){
    8. player.changeDir(UP);
    9. }else if(event.offsetY >= ctrlLayer.y+80 && event.offsetY <= ctrlLayer.y+120){
    10. player.changeDir(DOWN);
    11. }
    12. }else if(event.offsetX >= ctrlLayer.x && event.offsetX <= ctrlLayer.x+40){
    13. if(event.offsetY >= ctrlLayer.y +40 && event.offsetY <= ctrlLayer.y+80){
    14. player.changeDir(LEFT);
    15. }
    16. }else if(event.offsetX >= ctrlLayer.x+80 && event.offsetX <= ctrlLayer.x+120){
    17. if(event.offsetY >= ctrlLayer.y +40 && event.offsetY <= ctrlLayer.y+80){
    18. player.changeDir(RIGHT);
    19. }
    20. }
    21. isKeyDown = true;
    22. }
    23. function onup(event){
    24. isKeyDown = false;
    25. }
    复制代码

    这里需要知道的是,在智能手机里,其实点击事件是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



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

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

    为了实现这个判断,我们必须要知道地图什么地方可以移动,什么地方不可以移动
    所以,我们需要一个地图的地形,如下
    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://legend-demo.googlecode.com/files/rpg2.zip




    本文转自个人博客:http://blog.csdn.net/lufy_legend
    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    上一篇:html5 canvas (三) 下一篇:HTML5实现的Loading缓冲效果
    PHP编程就业班

    相关文章推荐

    • html5离线存储有哪些• h5新增标签audio与video的使用• 深入解析asp.net中mvc4自定义404页面(分享)• 你值得了解的HTTP缓存机制(代码详解)• 使用HTML5 SVG绘制各种雪花图案

    全部评论我要评论

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

    PHP中文网