html / jquery 2d基于tile的地图:javascript太慢了,替代方案?

时间:2013-06-04 02:30:57

标签: jquery html map tile

我正在开发一款基于浏览器的网页游戏,其中包含一张非常大的2d基于图块的地图。与部落战争等游戏不同,地形不是从种子或一个大图像文件中随机生成的。

我目前所做的是有一个隐藏的画布元素,其中包含一个bmp贴图,其中每个像素代表一个贴图。绿色像素表示平台,蓝色像素表示水,黑色像素表示地图外部的区域。

目前我的算法将在画布中采用位图的某个矩形段,然后创建一组大小合适的块,这些块适合更大的div。瓷砖从左到右绘制,依靠相对定位和浮动:左侧自行排列。每块瓷砖的尺寸为30px×30px,这相当于1080p显示器上的相当多的瓷砖。

为了移动地图,用户按下一个箭头键,在画布中移动矩形选区,然后将其全部绘制回来。

以下是直接代码:

<script>

$("#WorldMapCanvas").hide();

var canvas = document.getElementById('WorldMapCanvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.src = '../Images/MapTest3.bmp';

var tileSize = 30;
var maxTilesOnX = $("#WorldMap").width() / tileSize;
var maxTilesOnY = $("#WorldMap").height() / tileSize;

var offsetX = 0;
var offsetY = 0;

function draw() {

    $("#WorldMap").html(""); // clear map div

    context.drawImage(imageObj, 0, 0);

    for (var y = 0 + offsetY; y < maxTilesOnY + offsetY; y++) {
        for (var x = 0 + offsetX; x < maxTilesOnX + offsetX; x++) {

            var pixel = context.getImageData(x, y, 1, 1);
            // alert("x: " + x + " y: " + y + " " + pixel.data[0] + "," + pixel.data[1] + "," + pixel.data[2]);

            if ((pixel.data[0] == 0) && (pixel.data[1] == 255) && (pixel.data[2] == 0)) {
                $("#WorldMap").append("<div class = 'grass'></div>");
            }
            else if ((pixel.data[0] == 0) && (pixel.data[1] == 0) && (pixel.data[2] == 255)) {
                $("#WorldMap").append("<div class = 'ocean'></div>");
            }
            else if ((pixel.data[0] == 0) && (pixel.data[1] == 0) && (pixel.data[2] == 0)) {
                $("#WorldMap").append("<div class = 'null'></div>");
            }
        }

    }



    $(".grass").mouseenter(function () {
        $("#WorldMapMessage").html("grass");
    });
    $(".ocean").mouseenter(function () {
        $("#WorldMapMessage").html("ocean");
    });
    $(".null").mouseenter(function () {
        $("#WorldMapMessage").html("empty");
    });
}

imageObj.onload = draw();

// allows player to draw new portions of the map by using arrow keys
clickhandler = document.addEventListener('keydown', function (event) {
    if (event.keyCode == 37) { offsetX -= 5; draw();}
    else if (event.keyCode == 38) { offsetY += 5; draw(); } // up
    else if (event.keyCode == 39) { offsetX += 5; draw(); }
    else if (event.keyCode == 40) { offsetY -= 5; draw(); }
});

然而,单键按下浏览器大约2.5秒来处理和绘制所有数据,而且我有一个相当强大的处理器,这意味着普通用户可能会非常缓慢。

如何提高算法速度?理想情况下,我想滚动实时,以便玩家可以拖动地图,谷歌地图样式。我有一些想法:

  1. 通过jquery为每个图块定义左侧和顶部位置,而不是将它们全部加载并依赖相对定位以使它们对齐。
  2. 将图块合并为画布中的单个图像。但是,我确实需要保持光标悬停信息,以便玩家可以查询地形信息(以及稍后从服务器中提取数据后将在顶部绘制的军队/城市。)
  3. 预加载整个地图。不理想,因为地图将是大约100万平方米的瓷砖......
  4. 使用Flash插件,也不理想,因为我希望尽量减少外部性能要求。
  5. 您是否有任何关于如何改进算法的建议或有关于要考虑的全新想法的建议?

    谢谢!

1 个答案:

答案 0 :(得分:0)

我不是专家,但缓存DOM元素将是我要做的第一件事。 var $WorldMap = $("#WorldMap")

我不确定.append()方法有多快。 这是一个很酷的站点,可以相互测试不同的JS方法。 jsperf.com

或者打印地图如下:
0000111100000
0001111002220
0011100112201

然后简单地用你的元素替换它。