• 如何制作一款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完整构造器:

    function LTileMap(data,img,width,height){
        var s = this;
        base(s,LSprite,[]);
        s.x = 0;
        s.y = 0;
        s.mapData = data;
        s.imgData = img;
        if(!width){
            var wbitmap = new LBitmapData(s.imgData);
            s.partWidth = wbitmap.image.width;
        }else{
            s.partWidth = width;
        }
        if(!height){
            var hbitmap = new LBitmapData(s.imgData);
            s.partHeight = hbitmap.image.height;
        }else{
            s.partHeight = height;
        }
        s.onshow();
    }

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

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

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

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

    [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18],  
    [18,18,18,17,17,17,17,17,17,17,17,17,55,55,18],  
    [18,18,17,17,17,17,18,18,17,17,17,17,55,55,18],  
    [18,17,17,17,18,18,18,18,18,17,17,55,55,17,18],  
    [18,17,17,18,22,23,23,23,24,18,17,55,55,17,18],  
    [18,17,17,18,25,28,26,79,27,18,55,55,17,17,18],  
    [18,17,17,17,17,10,11,12,18,18,55,55,17,17,18],  
    [18,18,17,17,10,16,16,16,11,55,55,17,17,17,18],  
    [18,18,17,17,77,16,16,16,16,21,21,17,17,17,18],  
    [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方法:

    LTileMap.prototype.onshow = function(){
        var s = this;
        var mapdata = s.mapData;
        var partWidth = s.partWidth;
        var partHeight = s.partHeight;
        
        var i,j;
        var index,indexY,indexX;
        var bitmapdata,bitmap;
    
        for(i=0;i<mapdata.length;i++){
            for(j=0;j<mapdata[0].length;j++){
                index = mapdata[i][j];
                indexY = Math.floor(index/mapdata.length);
                indexX = index - indexY*mapdata.length;
     
                bitmapdata = new LBitmapData(s.imgData,indexX*partWidth,indexY*partHeight,partWidth,partHeight);
                bitmap = new LBitmap(bitmapdata);
                bitmap.x = j*partWidth + s.x;  
                bitmap.y = i*partHeight + s.y;
    
                s.addChild(bitmap);
                }
        }
    }

    它的功能很简单,就是画出地图。其中的逻辑都很简单。主要是这里:

    for(i=0;i<mapdata.length;i++){
        for(j=0;j<mapdata[0].length;j++){
            index = mapdata[i][j];
            indexY = Math.floor(index/mapdata.length);
            indexX = index - indexY*mapdata.length;
    
            bitmapdata = new LBitmapData(s.imgData,indexX*partWidth,indexY*partHeight,partWidth,partHeight);
            bitmap = new LBitmap(bitmapdata);
            bitmap.x = j*partWidth + s.x;  
            bitmap.y = i*partHeight + s.y;
    
            s.addChild(bitmap);
        }
    }

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

    over,很简单是不是?实现后我们怎么用它呢?看以下代码:

    <!DOCTYPE html>
    <html lang="en">
        <head>
        <meta charset="utf-8" />
        <title>LTileMap</title>
        <script type="text/javascript" src="../lufylegend-1.7.3.min.js"></script>
        <script type="text/javascript" src="../lufylegendrpg-1.0.0.min.js"></script> 
        <script>
        init(30,"legend",480,320,main);
        LGlobal.setDebug(true);
        var backLayer,loadingLayer;
        var map;
        var loadData = [
            {name:"map",path:"./map.jpg"}
        ];
        var imglist = [];
        var mapData = [  
            [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18],  
            [18,18,18,17,17,17,17,17,17,17,17,17,55,55,18],  
            [18,18,17,17,17,17,18,18,17,17,17,17,55,55,18],  
            [18,17,17,17,18,18,18,18,18,17,17,55,55,17,18],  
            [18,17,17,18,22,23,23,23,24,18,17,55,55,17,18],  
            [18,17,17,18,25,28,26,79,27,18,55,55,17,17,18],  
            [18,17,17,17,17,10,11,12,18,18,55,55,17,17,18],  
            [18,18,17,17,10,16,16,16,11,55,55,17,17,17,18],  
            [18,18,17,17,77,16,16,16,16,21,21,17,17,17,18],  
            [18,18,18,18,18,18,18,18,18,55,55,18,18,18,18]
        ];
        function main(){
            //加入进度条
            loadingLayer = new LoadingSample1(); 
            addChild(loadingLayer); 
            //加载图片并显示进度
            LLoadManage.load(
                loadData,
                function(progress){
                    loadingLayer.setProgress(progress);
                },
                gameInit
            ); 
        }
        function gameInit(result){
            removeChild(loadingLayer);
            imglist = result;
            //初始化层
            backLayer = new LSprite();
            addChild(backLayer);
            //加入地图
            addMap();
        }
        function addMap(){
            map = new LTileMap(mapData,imglist["map"],32,32);
            backLayer.addChild(map);
        }
        </script>
        </head>
        <body>
                <div id="legend"></div>
        </body>
    </html>

    运行代码得到如下效果:

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

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

    代码很少,可以自己复制粘贴下来看看。哈!

  • 相关阅读:
    android dumpsys meminfo 详解
    效率思维模式与Zombie Scrum
    Mac中Run快捷键修改
    airtest+pytest实战教程05—登录智学网app
    对select函数的理解
    Appium定位元素
    Hack The Box——ServMon
    Oracle DG常用视图与运维护常用操作
    Oracle EBS订单的流程(Order->AR)
    财经法规与会计职业道德
  • 原文地址:https://www.cnblogs.com/jiangxiaobo/p/6004934.html
Copyright © 2020-2023  润新知