2017-01-23 77 views
2

当用户沿着一条线迹线时,一条SKShapeNode路径由线段(来自底层的“贴图”)构建。为什么SKShapeNode撕裂?

var activatedPointPath: UIBezierPath { 
    let activatedPointPath = UIBezierPath() 

    // self.state.activatedPoints contains the end point 
    // of each full line segment the user has traced through 
    if let firstActivatedPoint = self.state.activatedPoints.first { 
     activatedPointPath.move(to: firstActivatedPoint) 
     for activatedPoint in self.state.activatedPoints { 
      activatedPointPath.addLine(to: activatedPoint) 
     } 
     // self.state.endOfLine contains the last point the user 
     // has touched, which may or may not be at the end of a line 
     // segment 
     if let lastPoint = self.state.endOfLine { 
      activatedPointPath.addLine(to: lastPoint) 
     } 
    } 

    return activatedPointPath 
} 

然后这被分配到:实际的路径是通过线锁定用户以前已经拖了过来,并找到在最接近线上的最近点到最新触碰点,然后建立一个路径,像这样建所述SKShapeNode为:

self.lineNode.path = self.activatedPointPath.cgPath 

然而,当用户正在跟踪线,先前的段闪烁与同时被绘制到屏幕上,像这样的三角形丢失:

  solid line高于210个line with tear     line with tear

的图像是从一个简单的3×3块网格允许用户跟踪一个简单的直线:

wireframe of tiles

下面是一个更复杂的例子,其中该行开始上左下方和右上方结束:

more complex example with corners

什么引起这些神器?

编辑,而我已经找到一个解决这个问题,我还是欢迎的原因,原来的代码没有工作,新的代码做任何解释。

+1

SKShapeNode是CAShapeLayer(我认为),它是一个执行力差,半成品,WIP,包装难以克服,不可变,不灵活,无生命,不值得花费时间的包装。用拉伸和倾斜的SKSpriteNodes绘制这些线段。动画时也会获得更好的效果。 SKShapeNode的最初目的是将其用作物理调试绘图工具,仅用于物理形状...。只有在iOS 10中,他们才能够以高性能的方式绘制轮廓,如果它没有改变并且像纹理一样对待。它可能在iOS 16中完成。 – Confused

回答

1

我对此问题的解决方法是更改​​activatedPointPath计算的变量,以便将线段组合在一起,而不是一次绘制线条。

新的代码看起来是这样的:

var previousPoint = firstActivatedPoint 
for activatedPoint in self.state.activatedPoints { 
    let newSegment = UIBezierPath() 
    newSegment.move(to: previousPoint) 
    newSegment.addLine(to: activatedPoint) 

    activatedPointPath.append(newSegment) 

    previousPoint = activatedPoint 
} 
if let lastPoint = self.state.endOfLine { 
    let newSegment = UIBezierPath() 
    newSegment.move(to: previousPoint) 
    newSegment.addLine(to: lastPoint) 
    activatedPointPath.append(newSegment) 
} else { 
    print("No last point") 
} 

现在产生线条流畅。

+0

...虽然它的工作原理,但效率非常低下。最后,我采用了Confused的建议,并将一些CALayer的形状代替成了纹理。这具有原始的长时间绘制的副作用,能够正确渲染。 – ReactiveRaven