管理要在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()
并根据x
和y
进行绘制,并将其乘以32
以在正确的xy
坐标上绘制。
如何进行多个地图切换
在我的游戏中,地图有五个要跟踪的内容: currentID
, leftID
, rightID
, upID
和bottomID
。
- currentID:您所在地图的当前ID。
- leftID:退出当前地图左侧时要加载的当前ID的ID。
- rightID:退出当前地图右侧时要加载的当前ID的ID。
- downID:退出当前地图底部时要加载的当前ID的ID。
- upID:退出当前地图顶部时要加载的当前ID的ID。
需要注意的事项:如果leftID
, rightID
, upID
或bottomID
不是特定的,则表示它们是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/