• html5的canvas绘制迷宫地图


    canvas标签一直是html5的亮点,用它可以实现很多东西。我想用它来绘画像迷宫那样的地图。借助到的工具有瓦片地图编辑器tiled(点击跳转到下载链接)。

    如图:如果你想要画像这样的迷宫地图,如果不用canvas,可以通过dom操作拼接一个一个div,以达成这个效果。那样是不是很不合理?首先,页面上会存在大量的div,并且通过dom操作生成很耗性能,如果地图大了,会非常不流畅,非常卡。如果用canvas,性能就会大大提高。方法也很简单,代码量也非常少。

    简单介绍完了之后开始进入正题。上面提到的那个软件装了之后,打开它进行绘图。说明一下:这只是一个绘图软件,绘图完后会生成数据(保留为js格式或json格式),拿到里面的数据,再通过canvas进行绘画。实践操作一下。

    ①:打开后界面:

    ②:新建文件

    每一块宽高是40px,总宽高是480px*240px,可以自己设置

    ③:完了之后创建新图块。就是通过图块来画图。点击浏览随便拿一张图片即可

                

    ④:然后随便拎一块右边的图块就可以在左边灰色区域画图了。我随便画了这样的图

         

    ⑤:保存js文件----文件另存为。这就是我得到的js文件。

    (function(name,data){
     if(typeof onTileMapLoaded === 'undefined') {
      if(typeof TileMaps === 'undefined') TileMaps = {};
      TileMaps[name] = data;
     } else {
      onTileMapLoaded(name,data);
     }})("map1",
    { "height":6,
     "layers":[
            {
             "data":[0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,0, 1, 1, 1, 1, 1, 1, 0],
             "height":6,
             "name":"u5757u5c42 1",
             "opacity":1,
             "type":"tilelayer",
             "visible":true,
             "width":12,
             "x":0,
             "y":0
            }],
     "nextobjectid":1,
     "orientation":"orthogonal",
     "properties":
        {
    
        },
     "renderorder":"right-down",
     "tileheight":40,
     "tilesets":[
            {
             "firstgid":1,
             "image":"../../../Public/Pictures/Sample Pictures/Penguins.jpg",
             "imageheight":768,
             "imagewidth":1024,
             "margin":0,
             "name":"Penguins",
             "properties":
                {
    
                },
             "spacing":0,
             "tilecount":475,
             "tileheight":40,
             "tilewidth":40
            }],
     "tilewidth":40,
     "version":1,
     "width":12
    });

    对于以上代码,其实只有红色文字代码对我们这个画图时有帮助的,data里面的数据,0表示没有地图块,非0表示地图块。可以通过遍历,将非0画出来,获取宽高只要是用来换行之类的。这就是瓦片地图编辑器的作用。

    下面就开始代码了,代码简单易懂,就直接贴了:

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>canvas绘制地图</title>
    </head> <body> <canvas id="canvas1" width="480" height="240"></canvas> <!--注意canvas的大小,要联系地图大小设置--> <script>

         //瓦片地图编辑器获取到的数据 var map={ "data":[0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0], "height":6, "width":12 } var canvas = document.getElementById("canvas1"); var ctx = canvas.getContext("2d"); var W = 40; //每一块地图块的宽 var H = 40; //每一块地图块的高 var l = 0; var t = 0; for (var i=0; i<map.data.length; i++){ l = i%map.width*W; //绘画每一块地图块的X坐标 if (i%map.width==0&&i!=0){ //当达到一行是换行,注意第一行是0%0=0;所以应去除第一行换行的情况 t+=H; //绘画地图块的Y坐标 } if (map.data[i]>0){ //当地图块的数据不为0时绘画地图块 ctx.fillRect(l, t, W, H); } } </script> </body> </html>

    效果如下:

    跟上面的是一模一样的,简简单单十几行JS代码就可以实现了,哪怕地图再大,也只是data数据多而已,对性能要求并不高。

    另外,如果想要实现将原图片贴上去的话,也是很简单的,只是涉及到位置的计算。

    canvas可以切割图片:ctx.drawImage(this, imgL, imgT, W, H, this.l, this.t, W, H);用这段代码就可以了。

    自己的一个练习。

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <canvas id="canvas1" width="240" height="240"></canvas>
    </body>
    <script type="text/javascript">
    var map =  {
             "data":[0, 1, 0, 0, 0, 73, 0, 1, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 62, 62, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
             "height":6,
             "width":6,
             "imgWidth":14
            };
    var canvas = document.getElementById("canvas1");
    var ctx = canvas.getContext("2d");
    var W = 40;
    var H = 40;
    var l = 0;
    var t = 0;
    for (var i=0; i<map.data.length; i++){
    
        l = i%map.width*W;
        if (i%map.width==0&&i!=0){
            t+=H;
        }
        if (map.data[i]>0){
            var imgObj = new Image();
            imgObj.src = "pic.jpg";
            imgObj.index = i;
            imgObj.l = l;
            imgObj.t = t;
            imgObj.onload = function (){    
                var imgL = (map.data[this.index]-1)%map.imgWidth*W;
                var imgT = Math.floor(map.data[this.index]/map.imgWidth)*H;
                ctx.drawImage(this, imgL, imgT, W, H, this.l, this.t, W, H);
            }
        }    
    }
    </script>
    </html>

    效果:

    思路就是这样子,就不在=再多说了。原创不容易,如需转载,请写明出处吧,谢谢。

     

  • 相关阅读:
    关于链表的一个小程序
    位操作
    结构和其他数据形式
    存储类、链接、内存管理
    文件输入/输出
    为什么返回IEnumerbale而不是List
    EncType
    script标签不能闭合
    jqueryUI AutoCompelete
    ChangeType
  • 原文地址:https://www.cnblogs.com/wuzhiquan/p/4849833.html
Copyright © 2020-2023  润新知