管理要在HTML5 Canvas上绘制的2D数组中的文本地图

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

这就是我现在的方式:

如何在地图上加载和绘制图块

使用Image()片段通过图块(32×32)绘制地图。 图像文件通过一个简单的for循环加载for并使用drawImage()放入一个名为tiles[]的数组中进行PAINTED。

首先,我们加载瓷砖……

在此处输入图像描述

以及它是如何完成的:

 // 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); } 

当然,当玩家开始游戏时,它会加载他们最后离开的地图。 但是在这里,它是一张全草图。

现在,地图使用2D数组。 这是一个示例地图。

 [[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]]; 

我使用简单的if结构获得不同的地图。 一旦return上面的2d数组,将根据存储在tile[]内的Image()绘制每个数组中的相应数字。 然后将发生drawImage()并根据xy进行绘制,并将其乘以32以在正确的xy坐标上绘制。

如何进行多个地图切换

在我的游戏中,地图有五个要跟踪的内容: currentIDleftIDrightIDupIDbottomID

  • currentID:所在地图的当前ID。
  • leftID:退出当前地图左侧时要加载的当前ID的ID。
  • rightID:退出当前地图右侧时要加载的当前ID的ID。
  • downID:退出当前地图底部时要加载的当前ID的ID。
  • upID:退出当前地图顶部时要加载的当前ID的ID。

需要注意的事项:如果leftIDrightIDupIDbottomID不是特定的,则表示它们是0 。 这意味着他们不能离开地图的那一边。 它只是一个无形的封锁。

因此,一旦一个人退出地图的一侧,取决于他们退出的位置…例如,如果他们退出底部,则底部bottomID将加载map的编号,从而在地图上绘制。

这是一个代表性的.GIF,可以帮助您更好地可视化:

在此处输入图像描述

正如您所看到的,迟早会有很多地图,我将处理许多 ID。 这可能会让人感到困惑和忙乱。

显而易见的优点是它一次加载176个图块,刷新一个小的512x352canvas,并且一次处理一个图。 可以理解的是,MAP ids在处理许多地图时,有时会让人感到困惑。

我的问题

  • 这是一种存储地图的有效方式(考虑到瓷砖的使用),还是有更好的方法来处理地图?

我在想着一张巨大的地图。 地图大小很大,它只是一个2D数组。 但是,视口仍然是512×352像素。

这是另一个.gif我(为这个问题)帮助可视化:

在此处输入图像描述

对不起,如果你不懂我的英语。 请问任何你无法理解的事情。 希望我说得很清楚。 谢谢。

那么这里有一些东西,所以我会按顺序回应它们。


… 521单独的PNG文件?

在此处输入图像描述

使用一个。 只有一个。 也许 ,上衣。 考虑一下,你是否让每个客户做500个GET请求只是为了获得游戏的 ? 这是疯狂的。

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

在此处输入图像描述

你也应该这样做。


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


至于你的地图性能问题,巨型arrays应该是好的开始。 这是一个处理它的好方法,除非你的话非常非常大,否则我不会费心去探索其他选项。 如果它是巨大的,你可以拥有400×400(左右)的世界“块”,当你来到第400行时,你开始使用下一个数组的第0行。 当然,当你的英雄位于旧的四角位置时,任何时候“使用中”的大多数arrays将是四个。

球员的位置并不难。 如果他在瓦片822,20那将意味着他在由(2, 0)表示的块中(如果我们从(0, 0) )。 具体来说,他将在那块大块的22号,20号。 没有复杂的数学,没有ID。 没有必要跟踪ID。 您甚至不必跟踪哪个块是最后一个块。 你可以知道总的地图大小是(例如)1200×1200,如果他试图移动到(1201,50),你甚至不必看是否存在chunk (4, 0) 4,0 (4, 0) 。 你知道他不能移动那里,地图只有1200瓦宽!

性能应该是正常的,并且在你不得不担心这个特定的数组之前,它将真正依赖于大量的其他东西。 我的建议是担心在担心性能之前制作游戏。 一旦游戏变慢,重新访问性能。

一旦你进入表演,我会先担心除了这个问题以外的一切。 在帆布游戏中,它不太可能成为瓶颈。 从数组中读取很快。 已经在内存中的大型arrays应该很快。 应该没有问题,我不会花时间预测它,直到它实际出现。


编辑:与播放器一起移动的视口示例: http : //jsfiddle.net/kmHZt/10/