So, I'm making a HTML5 RPG just for fun. The map is a
(512px width, 352px height | 16 tiles across, 11 tiles top to bottom). I want to know if there's a more efficient way to paint the
.
所以,我正在制作一个HTML5 RPG,只是为了好玩。地图是
Here's how I have it right now:
这就是我现在的方式:
How tiles are loaded and painted on map
The map is being painted by tiles (32x32) using the Image()
piece. The image files are loaded through a simple for
loop and put into an array called tiles[]
to be PAINTED on using drawImage()
.
使用Image()片段通过图块(32x32)绘制地图。图像文件通过一个简单的for循环加载,并使用drawImage()放入一个名为tiles []的数组中进行PAINTED。
First, we load the tiles...
首先,我们加载瓷砖......
Naturally, when a player starts a game it loads the map they last left off. But for here, it an all-grass map.
当然,当玩家开始游戏时,它会加载他们最后离开的地图。但是在这里,它是一张全草图。
Right now, the maps use 2D arrays. Here's an example map.
现在,地图使用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]];
I get different maps using a simple if
structure. Once the 2d array above is return
, the corresponding number in each array will be painted according to Image()
stored inside tile[]
. Then drawImage()
will occur and paint according to the x
and y
and times it by 32
to paint on the correct x-y
coordinate.
我使用简单的if结构获得不同的地图。一旦返回上面的2d数组,将根据存储在tile []内的Image()绘制每个数组中的相应数字。然后将发生drawImage()并根据x和y进行绘制,并将其乘以32以在正确的x-y坐标上绘制。
How multiple map switching occurs
With my game, maps have five things to keep track of: currentID
, leftID
, rightID
, upID
, and bottomID
.
在我的游戏中,地图有五个要跟踪的内容:currentID,leftID,rightID,upID和bottomID。
- currentID: The current ID of the map you are on.
- currentID:您所在地图的当前ID。
- leftID: What ID of
currentID
to load when you exit on the left of current map.
- leftID:退出当前地图左侧时要加载的当前ID的ID。
- rightID: What ID of
currentID
to load when you exit on the right of current map.
- rightID:退出当前地图右侧时要加载的当前ID的ID。
- downID: What ID of
currentID
to load when you exit on the bottom of current map.
- downID:退出当前地图底部时要加载的当前ID的ID。
- upID: What ID of
currentID
to load when you exit on the top of current map.
- upID:退出当前地图顶部时要加载的当前ID的ID。
Something to note: If either leftID
, rightID
, upID
, or bottomID
are NOT specific, that means they are a 0
. That means they cannot leave that side of the map. It is merely an invisible blockade.
需要注意的事项:如果leftID,rightID,upID或bottomID不是特定的,那意味着它们是0.这意味着它们不能离开地图的那一侧。它只是一个无形的封锁。
So, once a person exits a side of the map, depending on where they exited... for example if they exited on the bottom, bottomID
will the number of the map
to load and thus be painted on the map.
因此,一旦一个人退出地图的一侧,取决于他们退出的位置...例如,如果他们退出底部,则底部ID将加载地图的编号,从而在地图上绘制。
Here's a representational .GIF to help you better visualize:
这是一个代表性的.GIF,可以帮助您更好地可视化:
这是另一个.gif我(为这个问题)帮助可视化:
Sorry if you cannot understand my English. Please ask anything you have trouble understanding. Hopefully, I made it clear. Thanks.
对不起,如果你不懂我的英语。请问任何你无法理解的事情。希望我说得很清楚。谢谢。
1 个解决方案
16
Well there's a few things here so I'll respond to them in order.
那么这里有一些东西,所以我会按顺序回应它们。
...521 SEPARATE PNG FILES?
Use one. Just one. Maybe six, tops. Think about it, you're making every client do 500 GET requests just to get the tiles for the game? That's bonkers.
使用一个。只有一个。也许六,上衣。考虑一下,你是否让每个客户做500个GET请求只是为了获得游戏的牌?这是疯狂的。
Almost every major site ever uses spritemaps to reduce requests. Youtube, for instance, uses this one image for all of its buttons:
几乎每个主要站点都使用spritemaps来减少请求。例如,Youtube将这一个图像用于其所有按钮:
You should do the same.
你也应该这样做。
Your concept of using the canvas as a viewport is correct from a performance perspective. Definitely don't make it bigger than it needs to be!
从性能角度来看,将画布用作视口的概念是正确的。绝对不要让它变得比它需要的更大!
As to your map performance question, giant arrays ought to be just fine to start. This is a fine way of dealing with it and I wouldn't bother exploring other options unless your word is very, very large. If it is massive, you could have "chunks" of the world that are 400x400 (or so) and when you come to the 400th row you start to use row 0 of the next array. The most arrays "in use" at any time will be four, of course, when your hero would be on a good old four corners sort of location.
至于你的地图性能问题,巨型阵列应该是好的开始。这是一个处理它的好方法,除非你的话非常非常大,否则我不会费心去探索其他选项。如果它是巨大的,你可以拥有400x400(左右)的世界“块”,当你来到第400行时,你开始使用下一个数组的第0行。当然,当你的英雄位于旧的四角位置时,任何时候“使用中”的大多数阵列将是四个。
Player location wouldn't be hard. If he was at tile 822, 20 that would mean he is in the chunk represented by (2, 0)
(if we're starting from (0, 0)
). Specifically, he'd be in tile 22, 20 of that chunk. No complex math, no ID's. There is no need to keep track of ID's. You don't even have to keep track of which chunk is the last chunk. You can just know that the total map size is (say) 1200x1200, and if he tries to move to (1201, 50), you don't even have to see if chunk (4, 0)
exists. You know right away he can't move there, the map is only 1200 tiles wide!
球员的位置并不难。如果他在瓦片822,20那将意味着他在由(2,0)表示的块中(如果我们从(0,0)开始)。具体来说,他将在那块大块的22号,20号。没有复杂的数学,没有ID。没有必要跟踪ID。您甚至不必跟踪哪个块是最后一个块。你可以知道总的地图大小是(例如)1200x1200,如果他试图移动到(1201,50),你甚至不必看是否存在chunk(4,0)。你知道他不能移动那里,地图只有1200瓦宽!
Performance should be fine either way and will really depend on a large number of other things before you have to worry about this particular array. My advice is to worry about making the game before worrying about performance. Revisit performance once the game gets slow.
性能应该是正常的,并且在你不得不担心这个特定的数组之前,它将真正依赖于大量的其他东西。我的建议是担心在担心性能之前制作游戏。一旦游戏变慢,重新访问性能。
Once you get to performance, I would worry about everything except this issue first. In a canvas game its really unlikely to be the bottleneck. Reading from arrays is fast. Large arrays already in memory ought to be fast. There shouldn't be a problem, and I wouldn't spend time anticipating one until it actually presents itself.
一旦你进入表演,我会先担心除了这个问题以外的一切。在帆布游戏中,它不太可能成为瓶颈。从数组中读取很快。已经在内存中的大型阵列应该很快。应该没有问题,我不会花时间预测它,直到它实际出现。
EDIT: Example of viewport moving with player: http://jsfiddle.net/kmHZt/10/
编辑:与播放器一起移动的视口示例:http://jsfiddle.net/kmHZt/10/