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":"\u5757\u5c42 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>

 

效果:

思路就是這樣子,就不在=再多說了。原創不容易,如需轉載,請寫明出處吧,謝謝。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM