简体   繁体   English

HTML5 Canvas平滑滚动tilemap

[英]HTML5 Canvas smooth scroll tilemap

I've tried to build a scrollable tilemap with the canvas object which automatically calculates it's size relative to the screen resolution and renders the tiles relative to a position on a (bigger) map. 我试图用canvas对象构建一个可滚动的tilemap,它自动计算它相对于屏幕分辨率的大小,并相对于(更大)地图上的位置呈现tile。

I planned to move the generated tiles and only draw the tiles that need to be drawn new. 我计划移动生成的图块,只绘制需要绘制新图块的图块。

So that means I scroll the map, draw the new tiles at the top (for example on moving upwards) and deleting the last tiles on the botton which are now out of the visible canvas. 这意味着我滚动地图,在顶部绘制新的图块(例如向上移动)并删除现在在可见画布外的最后一块图块。

My problem is: 我的问题是:

I don't think that it's very good for the performance to change the position of every tile in the canvas, I think this could be solved using getImageData() and putImageData() but there is still one problem left: 我不认为改变画布中每个图块的位置对性能非常有利,我认为这可以使用getImageData()putImageData()来解决,但仍然存在一个问题:

If i just move these tiles and draw new tiles it will always "hop" for 30px (1 tile = 30x30), so is there a simple / performance technically good way to make this with a smooth, linear scroll effect? 如果我只是移动这些瓷砖并绘制新的瓷砖,它将始终“跳”30px(1瓷砖= 30x30),那么是否有一种简单/性能技术上很好的方法来实现平滑,线性滚动效果?

Just fill the board wither using drawImage or pattern (the latter require you to use translate to get the tiles in the right position). 只需使用drawImage或pattern填充棋盘(后者需要使用translate来将棋盘放在正确的位置)。

drawImage takes new destination size as argument so you can zoom the tiles too. drawImage将新的目标大小作为参数,因此您也可以缩放切片。

Here is a pattern implementation I made for some other question, but I assume you should be able to see what goes on in the code: 这是我为其他一些问题做的模式实现,但我假设您应该能够看到代码中发生了什么:

function fillPattern(img, w, h) {

    //draw the tile once
    ctx.drawImage(img, 0, 0, w, h);

    /// draw horizontal line by cloning
    /// already drawn tiles before it
    while (w < canvas.width) {
        ctx.drawImage(canvas, w, 0);
        w *= 2;
    }

    /// clone vertically, double steps each time
    while (h < canvas.height) {
        ctx.drawImage(canvas, 0, h);
        h *= 2;
    }
}

The performance is good as you can see in the implementation this was used for (video wall with live scaling and tiling). 性能很好,正如您在实现中所看到的那样(带有实时缩放和平铺的视频墙)。

To project this more to what you have - instead of drawing each tile as above you can simply draw the canvas to a new position and fill in the new "gap": 要将更多内容投射到您拥有的内容 - 而不是像上面那样绘制每个图块,您只需将画布绘制到新位置并填写新的“间隙”:

ctx.drawImage(myCanvas, offsetX, offseY);
fillGap();

You could have used clipping with drawImage but the canvas will clip this for new internally so there is no gain in clipping the image in JavaScript as you move part of it outside the canvas. 您可以使用drawImage进行剪切,但画布会在内部对此进行剪辑,因此当您将部分图像移到画布外时,无法在JavaScript中剪切图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM