【问题标题】:how i can draw mesh topology in sprit kit using swift我如何使用 swift 在 sprit kit 中绘制网格拓扑
【发布时间】:2017-11-16 02:52:47
【问题描述】:

我正在尝试使用 swift 在 sprite kit 中绘制网格拓扑(图形)。 我是精灵套件的新手。请提供任何建议或示例代码。

【问题讨论】:

  • 我正在为您制定一个粗略的答案,但我不知道实际的 drawLines() 算法。我假设您知道在地形中绘制线条的算法吗?我刚做的那个很基础,很不完善。
  • 您好,我的答案+项目解决方案对您有用吗?如果没有,请告诉我,以便我尝试更新。

标签: graph sprite-kit mesh topology


【解决方案1】:

所以正如我在 cmets 中提到的,我不知道如何制作完美的地形算法,但我确实想出了一些可以复制你图片的东西。

基本上你添加一堆图作为 SKNodes,然后使用.position 属性作为用CGPath 绘制的线的起点和终点。从该路径,您可以创建一个SKShapeNode(path: CGPath)

我还在此处添加了一个使用委托的自定义按钮,但它与地形的实际“胆量”完全分开。它只是一个按钮。

// Overly complex way of creating a custom button in SpriteKit:
protocol DrawLinesDelegate: class { func drawLines() }

// Clickable UI element that will draw our lines:
class DrawLinesButton: SKLabelNode {
  
  weak var drawLinesDelegate: DrawLinesDelegate?
  
  init(text: String, drawLinesDelegate: DrawLinesDelegate) {
    super.init(fontNamed: "Chalkduster")
    self.drawLinesDelegate = drawLinesDelegate
    self.text = text
    isUserInteractionEnabled = true
  }
  
  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    print(drawLinesDelegate)
    
    drawLinesDelegate?.drawLines()
  }
  required init?(coder aDecoder: NSCoder) { fatalError("") }
  override init() { super.init() }
};


class GameScene: SKScene, DrawLinesDelegate {
  
  var plots = [SKShapeNode]()
  
  // var lines = [SKShapeNode]()  // This may be useful in a better algorithm.
  
  var nodesDrawnFrom = [SKShapeNode]()
  
  var drawLinesButton: DrawLinesButton?
  
  func drawLine(from p1: CGPoint, to p2: CGPoint) {
    
    let linePath = CGMutablePath()
    linePath.move(to: p1)
    linePath.addLine(to: p2)
    
    let line = SKShapeNode(path: linePath)
    line.strokeColor = .red
    line.lineWidth   = 5
    // lines.append(line) // Again, may be useful in a better algo.
    addChild(line)
  }
  
  func drawLines() {
    
    // Remove all lines: // Again again, may be useful in a better algorithm.
    /*
     for line in lines {
     line.removeFromParent()
     lines = []
     }
     */
    
    // The plot that we will draw from:
    var indexNode = SKShapeNode()
    
    // Find indexNode then draw from it:
    for plot in plots {
      
      // Find a new node to draw from (the indexNode):
      if nodesDrawnFrom.contains(plot) {
        continue
      } else {
        indexNode = plot
      }
      
      // Draw lines to every other node (from the indexNode):
      for plot in plots {
        if plot === indexNode {
          continue
        } else {
          drawLine(from: indexNode.position, to: plot.position)
          nodesDrawnFrom.append(indexNode)
        }
      }
    }
  }
  
  func addNode(at location: CGPoint) {
    let plot = SKShapeNode(circleOfRadius: 50)
    plot.name = String(describing: UUID().uuid)
    plot.zPosition += 1
    plot.position = location
    plot.fillColor = .blue
    
    plots.append(plot)
    addChild(plot)
  }
  
  override func didMove(to view: SKView) {
    drawLinesButton = DrawLinesButton(text: "Draw Lines", drawLinesDelegate: self)
    drawLinesButton!.position.y = frame.minY + (drawLinesButton!.frame.size.height / 2)
    addChild(drawLinesButton!)
  }
  
  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let location = touches.first!.location(in: self)
    addNode(at: location)
  }
}

不完美的算法:

在这里您可以看到,当您有中点时,有多条线从一条线绘制到另一条线(即阻挡一条直线):

您需要在算法中添加另一个完整部分来检查这一点。

另一个需要注意的重要事情是 SKShapeNode() 性能非常差,最好将所有这些都转换为 SpriteNode,或者将整个场景位blit 到静态纹理上。

但是,将它们全部作为 ShapeNode 可以为您提供最大的灵活性,并且在这里最容易解释。

【讨论】:

  • 感谢您的宝贵回复。在您的代码中,当我点击然后屏幕时,只有我可以绘制节点。我正在寻找具有 10 个节点并连接到特定节点的完整通用平均负载拓扑。我仍在寻找解决方案。
猜你喜欢
  • 2012-03-01
  • 2011-01-20
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 2018-06-15
  • 2012-10-30
  • 2012-08-29
  • 2014-10-14
相关资源
最近更新 更多