太空船精灵的程序生成

时间:2012-07-02 19:47:36

标签: c# graphics procedural-programming

我已经研究了这个主题了几天,并且知道它如何起作用,但我想我会在这里发表其他一些想法。

我想做的是生成要在游戏中使用的太空飞船精灵/图像。外观应与these类似: spaceship sprites http://i50.tinypic.com/10z1hq9.png

基本上,我的想法归结为这样的事情:

  1. 生成形成船舶“核心”的基础形状。形状可包括圆形,椭圆形,菱形,圆角矩形等。

  2. 生成较小的子形状,这些子形状覆盖在核心形状上,或通过简单的管道连接。 (镜像所有子形状以创建对称船。)

  3. 生成更小的子形状(细节形状),将它们覆盖在任何现有形状上。 (这些构成了船舶的“细节”。)

  4. 选择3-5种颜色,随机遮盖每个形状,使覆盖的形状颜色不同。

  5. 将纹理或渐变应用于核心和子形状(非细节形状),使船舶具有三维外观。

  6. 有没有人知道如何实现这样的算法来实现宇宙飞船所需的外观?

3 个答案:

答案 0 :(得分:5)

你是正确的想法,除了真正的艺术家驱动,你应该使用一套一致的层。为每个图层类生成多个图像。

  1. 机身
  2. 驾驶舱
  3. 永装饰
  4. 后置发动机
  5. 等等。

    这些图层中的每一个都是相同尺寸,并由艺术家设计为正确居中。 :)另请注意,这些图层中的任何一个都可以包含任何内容,甚至是空的。现在简单的随机化应该会给你一个漂亮,可信和独特的船。 :)

    您完全有可能在每组“引擎”类图层图像旁边添加像素坐标,您可以将其用作不同位置的喷气发动机火焰的“中心”。

答案 1 :(得分:1)

System.Drawing.Drawing2D.GraphicsPath可能有助于构建矢量路径。然后,您可以填充并向这些路径添加笔划以创建不同的形状。

您可以使用System.Drawing.Drawing2D.LinearGradientBrush作为渐变。

如果你有所作为,我很乐意看到你的代码。这似乎是一个很酷的主意。

为了好玩,我在VB.NET中将它们整合在一起:

Imports System.Drawing.Drawing2D

Public MustInherit Class ShipShape
    Public Layout As New Rectangle(0, 0, 128, 128)
    Public MustOverride Sub Draw(ByVal g As Graphics)

    Public Shared Sub DrawRoundedRectangle(ByVal gp As GraphicsPath, ByVal r As Rectangle, ByVal d As Integer)
        gp.AddArc(r.X, r.Y, d, d, 180, 90)
        gp.AddLine(CInt(r.X + d / 2), r.Y, CInt(r.X + r.Width - d / 2), r.Y)
        gp.AddArc(r.X + r.Width - d, r.Y, d, d, 270, 90)
        gp.AddLine(CInt(r.X + r.Width), CInt(r.Y + d / 2), CInt(r.X + r.Width), CInt(r.Y + r.Height - d / 2))
        gp.AddArc(r.X + r.Width - d, r.Y + r.Height - d, d, d, 0, 90)
        gp.AddLine(CInt(r.X + d / 2), CInt(r.Y + r.Height), CInt(r.X + r.Width - d / 2), CInt(r.Y + r.Height))
        gp.AddArc(r.X, r.Y + r.Height - d, d, d, 90, 90)
        gp.AddLine(r.X, CInt(r.Y + d / 2), r.X, CInt(r.Y + r.Height - d / 2))
    End Sub

    Public Shared Sub main()
        Dim b As New Bitmap(640, 480)
        Dim g As Graphics = Graphics.FromImage(b)
        g.Clear(Color.Magenta)
        Dim Hull As New HullShape
        Hull.Layout = New Rectangle(640 * 0.5 - 128 * 0.5, 480 * 0.5 - 128 * 0.5, 128, 128)
        Hull.Draw(g)
        Dim Wing1 As New HullShape
        Wing1.Layout = New Rectangle(Hull.Layout.X - 32, Hull.Layout.Y - 32, 32, Hull.Layout.Height + 64)
        Wing1.Draw(g)
        Dim Wing2 As New HullShape
        Wing2.Layout = New Rectangle(Hull.Layout.X + Hull.Layout.Width, Hull.Layout.Y - 32, 32, Hull.Layout.Height + 64)
        Wing2.Draw(g)
        b.Save("test.png")
    End Sub

End Class

Public Class HullShape
    Inherits ShipShape
    Public Overrides Sub Draw(ByVal g As System.Drawing.Graphics)
        Dim gp As New GraphicsPath
        ShipShape.DrawRoundedRectangle(gp, Layout, 30)
        Dim MetalBrush As New LinearGradientBrush(Layout, Color.Gainsboro, Color.Gray, 0)
        g.FillPath(MetalBrush, gp)
        g.DrawPath(Pens.Black, gp)
    End Sub
End Class

Output image

答案 2 :(得分:1)

我很久以前就这么做了!我会详细介绍更多细节。我会尝试找一张照片,如果我还有一个躺着,请等一下。我甚至可能有旧代码。我很乐意把它给你。 LMAO,这个旧项目的档案,不能相信我在这个领域工作之前就已经做了所有这些东西......似乎我没有它,但我确实有类似的东西,它甚至可能在这个项目中,让我把它放在Eclipse中并检查出来。不,不是我正在寻找的项目,也不是它的构建,bugger有33个错误。我也丢失了随机行星代码,可能还有其他很多项目。

建议:

我尝试从头开始生成整艘船,这意味着几乎没有限制。它通过一系列随机点工作,然后我会镜像它。我会得到这样的结果:(好吧,它不会让我发布图片,对不起)。

我建议的是限制可能性,并使用各自具有各自类型的各个部分,并能够连接到特定类型的其他部分。就像房子一样,你会做以下事情。墙壁,连接到其他墙壁,一些墙壁有窗口槽。有些墙壁有门槽等。墙可能有窗口槽和水线槽。

在这种宇宙飞船的情况下,上述情况会更有意义。确保每种类型的部件都遵循向下趋势,因此船的底部将是4,它将连接到一个或多个3,每个将连接到一个或多个2,每个将连接到一个或多个1分的。当随机选择一个项目时,我会建议整个项目使用,就像一种类型的激光武器。此外,请务必考虑允许项目按比例缩放,以便您可以更好地重复使用部件。

我认为这是一个了不起的项目,但也是一个非常耗时的做法。我希望你玩得开心,让我知道它是怎么回事!