Javascript 管理要在HTML5画布上绘制的二维数组中的文本映射

Javascript 管理要在HTML5画布上绘制的二维数组中的文本映射,javascript,jquery,html,canvas,Javascript,Jquery,Html,Canvas,所以,我制作HTML5 RPG只是为了好玩。地图是一个(512px宽,352px高| 16个瓷砖宽,11个瓷砖从上到下)。我想知道是否有更有效的方法来绘制 以下是我现在的情况: 如何在地图上加载和绘制瓷砖 正在使用Image()块用瓷砖(32x32)绘制地图。图像文件通过一个简单的for循环加载,并放入一个名为tiles[]的数组中,使用drawImage()进行绘制 首先,我们加载瓷砖 这是如何做到的: // SET UP THE & DRAW THE MAP TILES tiles

所以,我制作HTML5 RPG只是为了好玩。地图是一个
(512px宽,352px高| 16个瓷砖宽,11个瓷砖从上到下)。我想知道是否有更有效的方法来绘制

以下是我现在的情况:

如何在地图上加载和绘制瓷砖 正在使用
Image()
块用瓷砖(32x32)绘制地图。图像文件通过一个简单的
for
循环加载,并放入一个名为
tiles[]
的数组中,使用
drawImage()
进行绘制

首先,我们加载瓷砖

这是如何做到的:

// SET UP THE & DRAW THE MAP TILES
tiles = [];
var loadedImagesCount = 0;
for (x = 0; x <= NUM_OF_TILES; x++) {
  var imageObj = new Image(); // new instance for each image
  imageObj.src = "js/tiles/t" + x + ".png";
  imageObj.onload = function () {
    console.log("Added tile ... " + loadedImagesCount);
    loadedImagesCount++;
    if (loadedImagesCount == NUM_OF_TILES) {
      // Onces all tiles are loaded ...
      // We paint the map
      for (y = 0; y <= 15; y++) {
        for (x = 0; x <= 10; x++) {
          theX = x * 32;
          theY = y * 32;
          context.drawImage(tiles[5], theY, theX, 32, 32);
        }
      }
    }
  };
  tiles.push(imageObj);
}
我使用一个简单的
if
结构得到不同的地图。一旦上面的2d数组返回,每个数组中的相应数字将根据
Image()
存储在
tile[]
中进行绘制。然后将出现
drawImage()
,并根据
x
y
进行绘制,并将其乘以
32
以在正确的
x-y
坐标上绘制

多地图切换是如何发生的 在我的游戏中,地图有五件事需要跟踪:
currentID
leftID
rightID
upID
、和
bottomID

  • 当前ID:您所在地图的当前ID
  • leftID:什么ID的
    currentID
    在当前地图左侧退出时加载
  • rightID:当您从右侧退出时,要加载的
    currentID
    的哪个ID 当前地图
  • downID:退出时要加载的
    currentID
    的哪个ID 当前地图的底部
  • upID:何时加载
    currentID
    的哪个ID 您将在当前地图的顶部退出
需要注意的是:如果
leftID
righid
upID
bottomID
都不是特定的,则表示它们是
0
。这意味着他们不能离开地图的那一边。这只是一种无形的封锁

所以,一旦一个人离开地图的某一侧,取决于他们离开的地方。。。例如,如果它们在底部退出,
bottomID
将显示要加载的
map
的编号,从而在地图上绘制

下面是一个representational.GIF,可帮助您更好地可视化:

正如你所看到的,迟早会有很多地图,我会处理很多ID。这可能会让人有点困惑和紧张

明显的优点是,它一次加载176个瓷砖,刷新一个小的512x352画布,一次处理一个地图。缺点是,在处理许多地图时,地图ID有时可能会变得混乱

我的问题
  • 这是存储地图的有效方法(考虑到分幅的使用),还是有更好的方法来处理地图
我在沿着一张巨大的地图思考。地图的大小很大,而且都是一个2D阵列。然而,视口仍然是512x352像素

下面是我为这个问题制作的另一个.gif文件,它有助于可视化:


对不起,如果你不能理解我的英语。请问任何你难以理解的问题。希望我能说清楚。谢谢。

这里有几件事,我会依次回复


…521个单独的PNG文件?

使用一个。就一个。最多六个。想想看,你让每个客户都有500个请求只是为了得到游戏的瓷砖?真是疯了

几乎每个主要站点都使用spritemaps来减少请求。例如,Youtube的所有按钮都使用这一图像:

你也应该这样做


从性能角度来看,将画布用作视口的概念是正确的。绝对不要让它变得比需要的更大


至于你的地图性能问题,巨型阵列应该刚刚好开始。这是一个很好的处理方法,除非你的字数非常非常大,否则我不会去探索其他的选择。如果它是巨大的,您可能会有400x400(或更多)的世界“块”,当您到达第400行时,您将开始使用下一个数组的第0行。当然,当你的英雄在一个很好的老位置时,任何时候“使用中”最多的阵列将是四个

玩家定位并不难。如果他在tile 822,20,那就意味着他在
(2,0)
(如果我们从
(0,0)
开始)所代表的区块中。具体来说,他会在那块地砖的第22、20块。没有复杂的数学,没有身份证。没有必要跟踪ID。您甚至不必跟踪哪一块是最后一块。您只需知道总贴图大小是(比如)1200x1200,如果他尝试移动到(1201,50),您甚至不必查看chunk
(4,0)
是否存在。你知道他不能马上搬到那里去,地图只有1200块宽

无论哪种方式,性能都应该是良好的,在您不得不担心这个特定阵列之前,性能实际上取决于大量其他因素。我的建议是在担心性能之前先考虑游戏的制作。一旦游戏变慢,重新审视性能

一旦你开始表现,我会首先担心除了这个问题以外的一切。在画布游戏中,它不太可能成为瓶颈。从数组读取数据很快。内存中已经存在的大型阵列应该很快。不应该有问题,我不会花时间去预测,直到它真正出现


编辑:使用播放器移动视口的示例:

AFAIK存储“巨型”平铺贴图是处理它的经典方法,但如果内存是您关心的问题,您可以以二进制屏蔽方式存储平铺索引,因此地图中的一个条目将包含多个平铺索引(尽管请记住javascript没有整数,一切都有)
[[4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 1, 1, 1, 1], 
[1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 13, 13, 13, 1, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 13, 13, 11, 11, 11, 13, 13, 13, 13, 13, 13, 13, 1], 
[13, 13, 13, 1, 1, 1, 1, 1, 1, 1, 13, 13, 13, 13, 13, 1], 
[1, 1, 1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1]];