tes*_*est 22 javascript jquery html5 canvas
所以,我正在制作一个HTML5 RPG,只是为了好玩.地图是<canvas>(512px宽,352px高| 16个瓷砖,11个瓷砖从上到下).我想知道是否有更有效的方式来绘制<canvas>.
这就是我现在的方式:
地图由瓷砖(32x32)使用该Image()块绘制.图像文件通过一个简单的for循环加载并放入一个名为tiles[]PAINTED on 的数组中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);
}
Run Code Online (Sandbox Code Playgroud)
当然,当玩家开始游戏时,它会加载他们最后离开的地图.但是在这里,它是一张全草地图.
现在,地图使用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]];
Run Code Online (Sandbox Code Playgroud)
我使用简单的if结构获得不同的地图.一旦上面的2d数组return,每个数组中的相应数字将根据Image()存储的内部进行绘制tile[].然后drawImage()会发生,并根据油漆x和y和时间它通过32画上正确的x-y坐标.
随着我的游戏,地图有五件事情来跟踪:currentID,leftID,rightID,upID,和bottomID.
currentID退出当前地图左侧时要加载的ID
.currentID退出当前地图右侧时要加载的ID .currentID退出当前地图底部时要加载的ID .currentID退出当前地图顶部时要加载的ID .一些需要注意的:如果有一个leftID,rightID,upID,或bottomID不特定的,这意味着他们是一个0.这意味着他们不能离开地图的那一边.它只是一种无形的封锁.
因此,一旦一个人离开地图的一侧,取决于他们退出的地方...例如,如果他们退出底部,那么bottomID将map加载的数量,从而在地图上绘制.
这是一个代表性的.GIF,可以帮助您更好地可视化:

正如你所看到的,迟早会有许多地图,我会处理很多 ID.这可能会让人感到困惑和忙乱.
显而易见的优点是它一次加载176个图块,刷新一个小的512x352画布,并且一次处理一个图.可以理解的是,MAP ids在处理许多地图时,有时可能会感到困惑.
我正在思考一张巨大的地图.地图大小很大,它只是一个2D数组.但是,视口仍然是512x352像素.
这是另一个.gif我(为这个问题)帮助可视化:

对不起,如果你不懂我的英语.请问任何你无法理解的事情.希望我说得很清楚.谢谢.
Sim*_*ris 16
那么这里有一些东西,所以我会按顺序回复它们.

用一个.只有一个.也许六,上衣.考虑一下,你是否让每个客户做500个GET请求只是为了获得游戏的瓷砖?那是疯子.
几乎每个主要站点都使用精灵映射来减少请求.例如,Youtube将这一个图像用于其所有按钮:

你也应该这样做.
从性能角度来看,将画布用作视口的概念是正确的.绝对不要让它变得比它需要的更大!
至于你的地图性能问题,巨型阵列应该可以开始.这是处理它的好方法,除非你的话非常非常大,否则我不会费心去探索其他选项.如果它是巨大的,你可以拥有400x400(左右)的世界"块",当你来到第400行时,你开始使用下一个数组的第0行.当然,当你的英雄位于旧的四角位置时,任何时候"使用中"的阵列都将是四个.
球员的位置并不难.如果他在瓦片822,20那将意味着他在(2, 0)(由我们开始(0, 0))的大块中.具体来说,他将在第22块,第20块中.没有复杂的数学,没有ID.没有必要跟踪ID.您甚至不必跟踪哪个块是最后一个块.你可以知道总地图大小是(例如)1200x1200,如果他试图移动到(1201,50),你甚至不必看是否(4, 0)存在块.你知道他不能移动那里,地图只有1200瓦宽!
在你不得不担心这个特定阵列之前,性能应该是正常的,并且在很大程度上依赖于大量的其他东西.我的建议是担心在担心性能之前制作游戏.一旦游戏变慢,重新访问性能.
一旦你达到性能,我会首先担心除了这个问题之外的所有事情.在帆布游戏中,它不太可能成为瓶颈.从数组中读取很快.已经在内存中的大型阵列应该很快.这里不应该是一个问题,我不会花时间预测一个直到它实际上提出了自己.
编辑:与播放器一起移动的视口示例:http://jsfiddle.net/kmHZt/10/