一种从单个图像生成游戏地图的算法

时间:2008-09-20 04:15:30

标签: algorithm

我正在设计一款在浏览器中播放的游戏。

游戏是一个空间主题,我需要生成一个“银河”的地图。

地图的基本思想是:

game map http://www.oglehq.com/map.png

地图是一个网格,每个网格扇区可以包含一个行星/系统,每个都有链接到多个相邻的网格。

为了生成地图,我想我会有一组代表网格元素的图像。因此,在上面的示例的情况下,每个正方形是单独的图形。

要创建新地图,我会将图像“编织”在一起。 地图元素图像将具有行星及其链接已经在它们上面,因此我需要将地图拼接在一起,使得每个图像以其适当的对应物定位=>所以底角的图像必须有左边的图像和左边的图像才能正确连接。

您将如何创建代码以了解放置图像的位置? 有比使用图像更好的方法吗?

目前不应考虑性能和/或负载(如果我需要生成预先配置的地图而不是实时执行,我不介意。)

如果它有所作为,我将使用HTML,CSS和JavaScript,并由Ruby on Rails应用程序提供支持。

7 个答案:

答案 0 :(得分:3)

有两个非常好的基于浏览器的矢量/ javascript可操作图形软件包,它们几乎是通用的:SVG和VML。它们通常会产生低质量的高质量矢量图像。

firefox,opera,safari和chrome支持

SVG - 技术上只支持规范的一部分,但出于实际目的,您应该能够做到所需。 w3schools有a good reference for learning/using svg

VML是微软对SVG的回答,并且(惊讶)IE本身支持,尽管SVG不支持。 Msdn拥有最好的reference for vml

虽然它的功能更多,但您可以为这两种技术编写两个类似/稍微集成的代码库。真正的好处是用户不必安装任何东西来在线玩游戏 - 它只会有99.9%的用户使用。

顺便说一句,你说你要求算法,我正在提供技术(如果这是SVG / VML的正确术语)。如果您可以澄清输入/输出规范以及可能是哪个部分提出了挑战(例如哪些天真的实现不起作用,以及为什么),这将澄清问题并可能提供更有针对性的答案。

附录 The canvas tag正在得到越来越广泛的支持,其中一个明显的例外是IE。这可能是一种在html中嵌入图形元素的更简洁方法。

有用的画布:Opera's canvas tutorial | Mozilla's canvas tutorial | canvas-in-IE partial implementation

答案 1 :(得分:2)

嗯。如果每个框只能链接到其8个邻居,那么您只有2 ^ 8 = 256个图块类型。如果您限制任何一个磁贴的可能链接数量,则会更少。

您可以使用8个char文件名编码图像中存在的链接:

11000010.jpeg

或保存一些字节并将其转换为十进制或十六进制

196.jpg

然后是代码。有很多方法可以选择在内部表示地图。一种方法是为每个行星准备一个物体。行星物体知道它自己在网格中的位置,以及其相关行星的位置。因此,它有足够的信息来选择适当的文件。

或者拥有2D阵列。要确定要为每个数组项显示哪个图像,请查看8个相邻的数组项。如果这样做,您可以避免编码边界,​​方法是使两个轴上的数组更大,并在边缘周围有一个空的“边框”。这可以节省您检查相邻数组项是否不在数组中。

答案 2 :(得分:1)

有两种表示地图的方法。

一种方法是表示它是一个正方形网格,其中每个正方形可以有一个行星/系统。然后,您可以指定如果在八个方向(NW,N,NE,W,E,SW,S,SE)中的任何一个方向上存在一个方形的邻居,则存在与该邻居的连接。但请注意,在示例地图中,中心系统未连接到系统的北/东,因此可能这不是您想要的表示。但它可以用来构建其他表示

第二种方式是将每个方块表示为具有8个比特,定义是否沿着相同的八个方向中的每个方向与邻居建立连接。据推测,如果有一个连接,那么方块内部就有一个系统,否则如果没有连接,它就是空白。

因此,在您的示例3x3网格中,数据将是:

 Tile   Connections
        nw  n ne  w  e sw  s se
 nw      0  0  0  0  0  0  0  0 
 n       0  0  0  0  1  0  1  0
 ne      0  0  0  1  0  0  0  0
 w       0  0  0  0  0  0  0  0
 center  0  1  0  0  0  0  1  1
 e       0  0  0  0  0  0  0  0
 se      0  0  0  0  0  0  0  0
 s       0  1  0  0  1  0  0  0
 sw      1  0  0  1  0  0  0  0

您可以将这些连接表示为八个布尔值的数组,或者更紧凑地表示为八位整数。

然后很容易使用八个布尔值(或八位整数)来形成要为该网格方加载的位图的文件名。例如,使用此方案的中心磁贴可以称为“Bitmap01000011.png”(仅使用布尔值),或者“Bitmap43.png”(使用八位整数的十六进制值表示较短文件名的二进制模式) )。

由于您有256种可能的组合,因此需要256位图。

你还可以将数据减少到每个图块四个布尔/比特,因为例如“北”连接意味着北部的图块具有“南”连接,但这使得选择位图有点困难,但是如果你愿意,你可以解决它。

或者,您可以在每个方块中将零(空)和九(完全连接+系统圆)位图叠加在一起。您只需要使用透明的.png,以便将它们组合在一起。缺点是浏览器可能很慢绘制每个方块(尤其是完全连接的方块)。优势在于您创建的数据较少,而且从您的网站加载的数据较少。

您可以将地图本身表示为一个表格,并根据需要将位图添加为每个单元格的图像链接。

要映射的伪代码是:

draw_map(connection_map):
    For each grid_square in connection_map
        connection_data = connection_map[grid_square]
        filenames = bitmap_filenames_from(connection_data)
        insert_image_references_into_table(grid_square,filenames)

# For each square having one of 256 bitmaps:
bitmap_filenames_from(connection_data):
    filename="Bitmap"
    for each bit in connection_data:
      filename += bit ? "1" : 0
    return [filename,]

# For each square having zero through nine bitmaps:
bitmap_filename_from(connection_data):
    # Special case - square is empty
    if 1 not in connection_data:
        return []
    filenames=[]
    for i in 0..7:
        if connection_data[i]:
            filenames.append("Bitmap"+i)
    filenames.append("BitmapSystem");
    return filenames

答案 3 :(得分:0)

我建议使用图形库来绘制地图。如果你这样做,你将不会遇到上述问题,最终会得到更清晰/更简单的代码。一些选项是SVG,Canvas和flash / flex。

答案 4 :(得分:0)

就个人而言,我只想渲染游戏中的链接,并让单元格图形只提供背景。这为您提供了更大的灵活性,使您可以更轻松地增加单元格相互链接的方式,并且通常更具可扩展性。

否则,您需要考虑细胞可能链接的每种可能方式,即使您考虑旋转和镜像对称性,这也是相当多的。

答案 5 :(得分:0)

哦,你也可以只有少量的瓷砖png文件,它们具有透明度,并使用css-located div重叠这些文件以形成类似于你的例子的图片,如果这就足够了。

上次我检查时,旧版本的IE对图像文件的透明度没有很大的支持。任何人都可以编辑它以提供有关透明度支持的更好信息吗?

答案 6 :(得分:-1)

只要链接的最大长度不会太长,那么每个单元格的可能图像不会太多。你需要对各种图像单元进行排序。例如,一个整数,其中每个位表示图像组件的存在或不存在。

Bit 0 : Has planet
Bit 1 : Has line from planet going north
Bit 2 : Has line from planet going northwest
...
Bit 8 : Has line from planet going northeast

好的,现在创建512张图片。许多语言都有库,可以让您编辑图像并将其写入磁盘。如果你喜欢Ruby,试试这个:http://raa.ruby-lang.org/project/ruby-gd

我不知道您打算如何存储描述行星和链接图的数据结构。使用adjacency matrix可以轻松生成地图,尽管它不是迄今为止最小的代表。然后就像吐出2x2网格一样非常简单:

<table border="0" cellspace="0" cellpadding="0">
<tr>
<td><img src="cell_X.gif"></td>
<td><img src="cell_X.gif"></td>
</tr>
<tr>
<td><img src="cell_X.gif"></td>
<td><img src="cell_X.gif"></td>
</tr>
</table>

当然,用对应于描述单元外观的位组合的适当数字替换每个X.如果您正在使用邻接矩阵,那么将这些位放在一起非常简单 - 只需查看“当前”单元格周围的单元格。