zoukankan      html  css  js  c++  java
  • 如何实现一个HTML5 RPG游戏引擎——第一章,实现地图类

    一,话说天下大事

    前不久看到lufy的博客上,有一位朋友想要一个RPG游戏引擎,出于兴趣准备动手做一做。因为我研究lufylegend有一段时间了,对它有一定的依赖性,因此就准备将这个引擎基于lufylegend。临时命名为lufylegendRPG。毕竟基于lufylegend,假设名称中不加上lufylegend这几个字的话,有点说不通啊。。。近期公布了0.1.0版,可是不理想,连一惯都是鼓舞和欣赏我的lufy老先生都是出于真心的表示不惬意。想了解0.1.0版的朋友能够看看这里(事实上最好别看,因为1.0在使用方法上做了非常大的调整):

    http://blog.csdn.net/yorhomwang/article/details/8738733

    于是我不得不又一次来开发它。首先想到了地图类,今天就来实现一下。

    我们的地图不应该是一张大地图,而是用小地图拼接而成,这样方便我们改动地图。

    这种话我们须要很多地图块的图片,通常我们把它们放在一张上。我们就用lufy老先生blog上一张图片作为样例,给大家看看这种装满小地图的大图是什么样的:

    我们要完成的效果是什么样的呢?我把它放在这里,完成后看看实现度究竟有多少:

    二,怎样实现

     

    准备工作:

    首先你须要下载lufylegend,最新版本号是1.7.5,用1.7.3都行。

    下载地址:http://lufylegend.com/lufylegend

    上面有它的API和论坛,能够看看。

    另外推荐一本相关图书,lufy写的,叫《HTML5 Canvas游戏开发实战》。用于学习基础和了解开发技巧还是不错的。当中另一些非常不错的js技术指导。值得一看。

    书籍介绍:http://lufylegend.com/book/view/1

    開始编写

    因为lufylegend做的比較完美,那么我们封装起来就比較简单了。看看LTileMap完整构造器:

    [javascript] view plaincopy
     
    1. function LTileMap(data,img,width,height){  
    2.     var s = this;  
    3.     base(s,LSprite,[]);  
    4.     s.x = 0;  
    5.     s.y = 0;  
    6.     s.mapData = data;  
    7.     s.imgData = img;  
    8.     if(!width){  
    9.         var wbitmap = new LBitmapData(s.imgData);  
    10.         s.partWidth = wbitmap.image.width;  
    11.     }else{  
    12.         s.partWidth = width;  
    13.     }  
    14.     if(!height){  
    15.         var hbitmap = new LBitmapData(s.imgData);  
    16.         s.partHeight = hbitmap.image.height;  
    17.     }else{  
    18.         s.partHeight = height;  
    19.     }  
    20.     s.onshow();  
    21. }  

    首先为了降低引擎的大小,我们把变量s和this等起来,下面用到this的地方就都能用s来实现了。

    ※lufy大神近期提示我:“把变量s和this等起来是为了防止this的指向发生变化,并不是单一降低引擎的大小。因为this的指向不一定一直指向当前函数的。”在此再次感谢lufy的支持。

    首先我们让它继承LSprite,这样假设我们改变x和y属性后就能够直接变换位置了。再追加两个属性:mapData和imgData。

    mapData是通过data參数赋值的,data的赋值应该是一个二维数组,格式例如以下:

    [javascript] view plaincopy
     
    1. [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18],    
    2. [18,18,18,17,17,17,17,17,17,17,17,17,55,55,18],    
    3. [18,18,17,17,17,17,18,18,17,17,17,17,55,55,18],    
    4. [18,17,17,17,18,18,18,18,18,17,17,55,55,17,18],    
    5. [18,17,17,18,22,23,23,23,24,18,17,55,55,17,18],    
    6. [18,17,17,18,25,28,26,79,27,18,55,55,17,17,18],    
    7. [18,17,17,17,17,10,11,12,18,18,55,55,17,17,18],    
    8. [18,18,17,17,10,16,16,16,11,55,55,17,17,17,18],    
    9. [18,18,17,17,77,16,16,16,16,21,21,17,17,17,18],    
    10. [18,18,18,18,18,18,18,18,18,55,55,18,18,18,18]  

    它装载着地图块的样式,18相应的图块和55相应的图块是不一样的。后面我们会细讲。

    imgData顾名思义,它是一个装图片的容器。

    还有两个參数,它们是用来表示地图快的高度和宽度的。比如每张地图块是32*42的,那么就要将width设为32,height设为42。这种话就会将装满地图块的图片分成小地图。比如我们把上面那张图片分成每一个小地图块是32*32的,也就是说width设为32,height也设为32,那么就呈现现下面的形式:

    (以上图片我直接用了lufy博客里的图片)这时你能够看看18和55所相应的是什么。18是一棵树,而55相应的是水,因此我们就做到了让每张地图块显示得不同。

    接下来是onshow方法:

    [javascript] view plaincopy
     
    1. LTileMap.prototype.onshow = function(){  
    2.     var s = this;  
    3.     var mapdata = s.mapData;  
    4.     var partWidth = s.partWidth;  
    5.     var partHeight = s.partHeight;  
    6.       
    7.     var i,j;  
    8.     var index,indexY,indexX;  
    9.     var bitmapdata,bitmap;  
    10.   
    11.     for(i=0;i<mapdata.length;i++){  
    12.         for(j=0;j<mapdata[0].length;j++){  
    13.             index = mapdata[i][j];  
    14.             indexY = Math.floor(index/mapdata.length);  
    15.             indexX = index - indexY*mapdata.length;  
    16.    
    17.             bitmapdata = new LBitmapData(s.imgData,indexX*partWidth,indexY*partHeight,partWidth,partHeight);  
    18.             bitmap = new LBitmap(bitmapdata);  
    19.             bitmap.x = j*partWidth + s.x;    
    20.             bitmap.y = i*partHeight + s.y;  
    21.   
    22.             s.addChild(bitmap);  
    23.             }  
    24.     }  
    25. }  

    它的功能非常easy,就是画出地图。当中的逻辑都非常easy。主要是这里:

    [javascript] view plaincopy
     
    1. for(i=0;i<mapdata.length;i++){  
    2.     for(j=0;j<mapdata[0].length;j++){  
    3.         index = mapdata[i][j];  
    4.         indexY = Math.floor(index/mapdata.length);  
    5.         indexX = index - indexY*mapdata.length;  
    6.   
    7.         bitmapdata = new LBitmapData(s.imgData,indexX*partWidth,indexY*partHeight,partWidth,partHeight);  
    8.         bitmap = new LBitmap(bitmapdata);  
    9.         bitmap.x = j*partWidth + s.x;    
    10.         bitmap.y = i*partHeight + s.y;  
    11.   
    12.         s.addChild(bitmap);  
    13.     }  
    14. }  

    这一段代码是画出地图的核心,首先它遍历了地图数组,然后每遍历一个就画一张,然后加到自身中。因为自身是继承自LSprite,所当地图被加到自身中时,再将自身加究竟层或者其它Sprite中时,整个截面就会显示。

    over,非常easy是不是?实现后我们怎么用它呢?看下面代码:

    [html] view plaincopy
     
    1. <!DOCTYPE html>  
    2. <html lang="en">  
    3.     <head>  
    4.     <meta charset="utf-8" />  
    5.     <title>LTileMap</title>  
    6.     <script type="text/javascript" src="../lufylegend-1.7.3.min.js"></script>  
    7.     <script type="text/javascript" src="../lufylegendrpg-1.0.0.min.js"></script>   
    8.     <script>  
    9.     init(30,"legend",480,320,main);  
    10.     LGlobal.setDebug(true);  
    11.     var backLayer,loadingLayer;  
    12.     var map;  
    13.     var loadData = [  
    14.         {name:"map",path:"./map.jpg"}  
    15.     ];  
    16.     var imglist = [];  
    17.     var mapData = [    
    18.         [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18],    
    19.         [18,18,18,17,17,17,17,17,17,17,17,17,55,55,18],    
    20.         [18,18,17,17,17,17,18,18,17,17,17,17,55,55,18],    
    21.         [18,17,17,17,18,18,18,18,18,17,17,55,55,17,18],    
    22.         [18,17,17,18,22,23,23,23,24,18,17,55,55,17,18],    
    23.         [18,17,17,18,25,28,26,79,27,18,55,55,17,17,18],    
    24.         [18,17,17,17,17,10,11,12,18,18,55,55,17,17,18],    
    25.         [18,18,17,17,10,16,16,16,11,55,55,17,17,17,18],    
    26.         [18,18,17,17,77,16,16,16,16,21,21,17,17,17,18],    
    27.         [18,18,18,18,18,18,18,18,18,55,55,18,18,18,18]  
    28.     ];  
    29.     function main(){  
    30.         //添加进度条  
    31.         loadingLayer = new LoadingSample1();   
    32.         addChild(loadingLayer);   
    33.         //载入图片并显示运行进度  
    34.         LLoadManage.load(  
    35.             loadData,  
    36.             function(progress){  
    37.                 loadingLayer.setProgress(progress);  
    38.             },  
    39.             gameInit  
    40.         );   
    41.     }  
    42.     function gameInit(result){  
    43.         removeChild(loadingLayer);  
    44.         imglist = result;  
    45.         //初始化层  
    46.         backLayer = new LSprite();  
    47.         addChild(backLayer);  
    48.         //添加地图  
    49.         addMap();  
    50.     }  
    51.     function addMap(){  
    52.         map = new LTileMap(mapData,imglist["map"],32,32);  
    53.         backLayer.addChild(map);  
    54.     }  
    55.     </script>  
    56.     </head>  
    57.     <body>  
    58.             <div id="legend"></div>  
    59.     </body>  
    60. </html>  

    执行代码得到例如以下效果:

    为了防止大家以为我ps图片,那我就不仿把測试链接给出,大家自己看吧。

    測试地址:http://www.cnblogs.com/yorhom/articles/3063759.html

    代码非常少,能够自己复制粘贴下来看看。哈!

    近期做了一个留言板,欢迎大家发表自己的意见

    留言板地址:http://www.cnblogs.com/yorhom/archive/2013/04/20/3033235.html

    ----------------------------------------------------------------

    欢迎大家转载我的文章。

    转载请注明:转自Yorhom's Game Box

    欢迎继续关注我的博客

  • 相关阅读:
    nodeJs-querystring 模块
    nodeJs-process对象
    nodejs-Path模块
    nodejs-os模块
    nodejs-CommonJS规范
    nodejs-Events模块
    nodejs-Http模块
    nodejs-Cluster模块
    转:AOP与JAVA动态代理
    转:jdk动态代理实现
  • 原文地址:https://www.cnblogs.com/mfryf/p/3138664.html
Copyright © 2011-2022 走看看