代码之家  ›  专栏  ›  技术社区  ›  Toby Hede

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

  •  3
  • Toby Hede  · 技术社区  · 18 年前

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

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

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

    为了创建一张新地图,我将把这些图像“编织”在一起。 地图元素图像上已经有行星和它们的链接,因此,我需要将地图缝合在一起,这样每个图像都会与其相应的对应物一起定位=>因此,在下角的图像必须有图像的左侧和对角线左侧,与它正确连接。

    有没有比使用图像更好的方法?

    如果有什么不同的话,我将使用HTML、CSS和JavaScript,并由RubyonRails应用程序支持。

    7 回复  |  直到 7 年前
        1
  •  3
  •   Tyler    17 年前

    有两个非常好的基于浏览器的vector/javascript可操作图形包,它们一起几乎是通用的:SVG和VML。它们通常以低带宽生成高质量的基于矢量的图像。

    SVG firefox、opera、safari和chrome都支持,技术上只支持部分规范,但出于实际目的,您应该能够做您需要的事情。学校有 a good reference for learning/using svg .

    VML 是微软对SVG的回应,(令人惊讶的是)IE本机支持SVG,尽管SVG不是。Msdn有最好的 reference for vml .

    顺便说一下,您说您需要一个算法,而我提供的是技术(如果这是SVG/VML的正确术语)。如果您可以澄清输入/输出规范,以及可能是哪一部分提出了挑战(例如,哪一个简单的实现不起作用,以及为什么),这将澄清问题,并可能提供更集中的答案。

    The canvas tag 它正得到越来越广泛的支持,IE是一个显著的例外。这可能是一种在html中嵌入图形元素的更干净的方法。

    Opera's canvas tutorial | Mozilla's canvas tutorial | canvas-in-IE partial implementation

        2
  •  2
  •   slim    18 年前

    您可以使用8字符文件名对图像中存在的链接进行编码:

    11000010.jpeg
    

    196.jpg
    

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

    或者有一个二维数组。要计算每个数组项要显示的图像,请查看相邻的8个数组项。如果这样做,可以通过使阵列在两个轴上都变大两个,并在边缘周围有一个空的“边界”,从而避免对边界进行编码。这样就省去了检查相邻阵列项是否脱离阵列的时间。

        3
  •  1
  •   Lloyd    18 年前

    一种方法是将其表示为正方形网格,其中每个正方形中都可以有行星/系统,也可以没有行星/系统。然后,您可以指定,如果在八个方向(NW、N、NE、W、E、SW、S、SE)中的任何一个方向上有一个距离一平方米的邻居,那么就有一个到该邻居的连接。但是请注意,在样例地图中,中心系统未连接到其北部/东部的系统,因此这可能不是您想要的表示形式。但它可以用于构建其他表示

    因此,在您的示例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”(使用表示该二进制模式的八位整数的十六进制值作为较短文件名)。

    您还可以将数据减少到每个磁贴四个布尔/位,因为例如“北”连接意味着磁贴到北有一个“南”连接,但这使得选择位图有点困难,但如果您愿意,您可以解决这个问题。

    或者,您可以在每个正方形中的零(空)和九(完全连接+系统圆)位图之间分层。您只需要使用transparent.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
    
        4
  •  0
  •   airportyh    18 年前

    我建议使用图形库来绘制地图。如果您这样做了,您就不会有上述问题,并且最终会得到更干净/更简单的代码。有些选项是SVG、Canvas和flash/flex。

        5
  •  0
  •   freespace    18 年前

    否则,您将需要考虑单元链接的所有可能方式,即使您考虑旋转对称和镜像对称,这也是相当多的。

        6
  •  0
  •   Tyler    18 年前

    哦,你也可以有一小部分透明的平铺png文件,然后使用css定位的div重叠这些文件,形成一个与你的例子类似的图片,如果这足够的话。

    不过,上次我检查时,IE的旧版本对图像文件的透明度并没有很好的支持。是否有人可以编辑此文件以提供有关透明度支持的更好信息?

        7
  •  -1
  •   George George    18 年前

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

    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 可能会使生成地图变得容易,尽管它不是迄今为止最小的表示形式。然后,非常简单地写出html,如(对于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。如果您使用的是邻接矩阵,那么将位放在一起非常简单——只需查看“当前”单元周围的单元。