创建大型地图时如何快速保持画布?

时间:2013-03-12 22:54:05

标签: html5 performance canvas kineticjs

我正在尝试使用HTML5和画布创建游戏。目前我正在使用KineticJS库。

到目前为止我工作的东西是放大和缩小,从舞台中的一个图层拖动,以及从一些对象拖动。这一切都很好,也很快。

然而,游戏还需要一个景观,人们可以在那里建造房屋,粮田等。还需要一些树木和其他细节。这一切都使画布非常饱满。

因此,为了测试,我制作了一个10000 x 10000像素的画布层,并将其制成100 x 100 x 100 x 100的图块。只是这花费了很多时间甚至没有加载。

所以我用更少的瓷砖(25 x 25)尝试了它并且这确实加载了,但是当我尝试缩放,拖动舞台或拖动一个对象时,它非常非常慢并且它都需要包含更多的对象

所以主要的问题是:任何人都可以咨询我哪种方法可以用于上述故事?画布是正确的选项,还是有其他(和更好的)选项?

2 个答案:

答案 0 :(得分:2)

一张10,000 x 10,000像素的地图可能会变大。

从概念上讲,这很好。诀窍不在于记忆/画出整个东西!也就是说,即使你的地图那么大,你也只会在你的角色.

周围绘制/更新500 x 500px的瓷砖/对象,或任何你的视口。

请参阅this post和Simon的答案以实现这一目标。

以下是与答案相关的example jsFiddle (完全归功于Simon Sarris)

答案 1 :(得分:2)

我找到了一个完美的解决方案!

我要将canvas与一些像div一样的常规HTML结合起来。 我做了这个,它在这个div中创建了一个15000x15000像素的字段,我制作了225个新的div,它们将包含画布对象。每个画布对象的大小都是100x100像素。

总加载时间约为4秒,我将使用一些javascript和div来构建缩放,拖动。

<!DOCTYPE HTML>
<html>
<head>

    <style>
        body,html {
            margin: 0px;
            padding: 0px;
        }
        #container{
            width: 15000px;
            height: 15000px;
        }
        .canvas{
            float: left;
            margin: 0px;
            padding: 0px;
            height: 1000px;
            width: 1000px;
        }
    </style>

    <script src="/js/jquery.js"></script>
    <script src="/js/kinetic.js"></script>

</head>
<body>
<div id="zoomer" style="position: absolute;"></div>
<div id="container">
    <?php for ($x = 1;$x<=15;$x++){?>
        <?php for ($y = 1;$y<=15;$y++){?>
            <div class="canvas" id="blok<?php echo $x;?>-<?php echo $y;?>"></div>
        <?php } ?>
    <?php } ?>
</div>
<script>
    var bk = {};
    $.each($(".canvas"),function(){

        var id = this.id;
        bk[id] = new Kinetic.Stage({
            container: this.id,
            width: 1000,
            height: 1000
        });

        var ly = new Kinetic.Layer();

        for(x = 0;x<10;x++){
            for(y = 0;y<10;y++){
                var r = Math.random();
                var g = Math.random();
                var b = Math.random();

                var tile = new Kinetic.Rect({
                    width: 100,
                    height: 100,
                    x: x * 100,
                    y: y * 100,
                    fill: "rgb("+ parseInt(255*r) +","+ parseInt(255*g) +","+ parseInt(255*b) +")"
                });
                ly.add(tile);
            }

        }
        ly.draw();

        bk[id].add(ly);

    });

</script>
</body>
</html>

无论如何,谢谢你的努力!