如何有效地在网络上存储和显示地图?


9

关于

这实际上是两个问题合二为一。首先,我正在寻找一种有效存储大量切片数据的方法。另一个方面涉及查询数据集和显示图块。让我先给你一些背景。

我们正在使用CraftyJS库制作基于浏览器的多人大亨游戏,以将其渲染到Canvas。在GUI的后台,我们在PHP上运行Yii Framework,并且它们都连接到Python随机地图生成器和游戏引擎。

这是第一个粗糙地图渲染的外观:http : //i.imgur.com/khAXtl.png

存储地图数据

每次游戏开始时,都会随机生成游戏世界。每个玩家的大小为100x100的六角形瓷砖。这意味着对于一个三人游戏,将创建90.000个图块。目前,我只是创建一个JavaScript数组来渲染地图。

这对于渲染来说效果很好,但是对于与地图的任何形式的交互,我们都需要存储哪个玩家拥有该图块,在该图块之上构建什么样的结构,它的当前价格等等。起初,至少对于原型而言,我们想使用MySQL,但是经过一些测试,它的速度并没有我想要的那么快。也许像MongoDB这样的对象存储将更适合于存储切片数据而不是SQL表。也许还有其他东西?

显示地图

我看到的另一个问题是在地图上移动。目前,我正在为每个图块创建Crafty实体,即使它不在视口中也是如此。这很慢,因为即使Crafty仅在视口中渲染那些,它也会存储并可能遍历每个渲染事件上的所有图块。我目前所拥有的是绘制的生成地图,当您四处走动时加载和停顿非常慢,现在我想使其可玩。

我的第一个想法是加载视口中显示的图块子集。但是,当玩家将视口移至空白区域时,我需要查询服务器并等待响应返回,只有这样才能渲染地图。这在本机应用程序中会很好,但在网络游戏中却比较落后。

从地图上获得平滑性能的方法可能是将较大的图块子集预加载到javascript数组中并将其用作缓存。播放器将有几个屏幕“缓存”,当他移动视口时,我将向JS“缓存”加载更多图块。

我朝着正确的方向前进吗?我很想从做过类似事情的人那里获得更多信息。我是游戏开发的新手,但是在过去的几周中,我已经经历了很多研究。


1
我很惊讶您发现MySQL是瓶颈。您测试了什么才能得出结论,它正在减慢速度?
bummzack 2011年

@bummzack如果他每个磁贴都有一行,我几乎看不到事情不会慢下来。
aaaaaaaaaaaa

1
@eBusiness从数据库查询几千行应该不是问题。这仍应在几毫秒的范围内。同样,对于3位玩家来说,它不会是90,000行,而是3万行(每位玩家100x100)。
bummzack 2011年

对于令人困惑的数学感到抱歉,除玩家区域外,玩家之间还存在两倍的空间,以使它们彼此之间的距离相等,这使其达到90k。查询不是问题。选择90k瓦片并构建地图。但这不是一个好方法。当需要详细信息时,我将序列化地图数据并使用查询数据库中的图块。
元素

Answers:


2

游戏性
首先,我想问您,您实际上每个玩家需要10000个图块吗?虽然我不知道您正在制作哪种游戏,但是大型地图通常会制作很长的游戏。《文明5》中最大的地图是10240个图块,这仅是一种排序方式,因为您不需要玩太多图。

数据库
您不应该尝试在数据库之外运行类似的游戏,您需要将数据保留在应用程序内存中。您可以使用数据库来备份游戏。对于完整的备份,请保存游戏数据的序列化,然后可以通过保存给定的顺序来增加序列号,然后在需要使用备份时重新运行这些命令。

JavaScript存储
对于客户端,我想说的是您最好保持整个地图加载,至少如果您坚持使用千篇一律的图块,将它们全部放在一个好的对象树中可能会有点太多,所以您应该保留数据以“半二进制”编码格式。字符串可以很好地解决这种问题,或者,您可以安全地将多达53位的无符号整数存储在64位浮点数中,并且可以将很多这样的整数存储在数组中,我认为您会看到相当小的内存占用。

JavaScript可视化
虽然我不会说您不一定不应该使用画布,但是实际上不需要像这样的东西。将其全部设置为一堆img元素,然后更改src属性以显示地图的不同部分。

专家提示
顺便说一句,有时候共享用于生成种子的种子比共享整个地图要容易得多。


+1,但是遗憾的是,用PHP编写的Web应用程序通常无法将游戏状态保留在内存中。
bummzack 2011年

@bummzack,啊,对,我想我以某种方式略过了PHP一词,只是读了Python。然后可能需要更改后端框架。Node.js可能是一个选择。
aaaaaaaaaaaa

想想OpenTTD,我正在建立一个有竞争力的交通大亨,一张512x512(262k)大小的地图对几个玩家来说并不算大。我意识到这很雄心勃勃,但是如果地图不那么大,那么游戏可能会过早结束。因为是多人游戏,所以我需要将更改同步到玩家之间的地图上。我的第一个直觉是仅使用我在Web开发中了解的概念并使用datbase。它不需要是超级实时的。我要使用JS可视化,因为我想在地图上添加动态内容。

考虑我的回答是一些指导,最后您必须自己制定性能,这是一个严重的问题,您可能必须做出一些妥协。
aaaaaaaaaaaa

我同意,您的回答给了我很多思考的机会。我将尝试找到一种方法,将序列化的地图数据保留在内存中,并将数据库保留为备份。但是接下来,我必须弄清楚如何在玩家之间共享更改。经过一些进一步的测试之后,我会回想一下我的想法。
元素

1

MySQL并不慢。最有可能您正在执行朴素查询或具有次优索引。像MongoDB这样的NoSQL方法可能更快,也许没有。您的访问方式和查询选择才是真正重要的。可以就如何提高性能提供建议,但一定要先看看您已经在做什么。

从地图上获得平滑性能的方法可能是将较大的磁贴子集预加载到javascript数组中并将其用作缓存。

当然是。这里没有太多要添加的内容-客户端从服务器要求瓷砖,因此您只需要确保要求的瓷砖覆盖的面积大于屏幕的面积即可。

附录:

我们在PHP上运行Yii Framework,并且它们都连接到Python随机地图生成器和游戏引擎。

如果您精通Python,那么我建议您放弃PHP中间人。如果您将游戏作为Python进程运行,则可以更轻松地将切片数据保留在内存中,并显着减少MySQL访问。Python也是比PHP更精明的语言,这也有帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.