SpriteKit样条路径虚线逐段动画:如何修复直线段间隙?
问题
创建了SKShapeNode子类DashedSplinePath,将样条曲线实例化后调用.animateDottedPath()方法,期望虚线在5秒内沿原路径完成动画。动画可正常运行,但截图显示直线段出现缺失间隙。怀疑是通过fromSplinePath.copy(dashingWithPhase: 100.0, lengths: [10])复制的路径,在_animatePath动作中调用self.dottedPathCopy.addPath(self.dottedPathComponents[self.dashIndex])时出现转换问题,希望了解可变路径出现大间隙的原因。
间隙产生的核心原因
- 虚线路径拆分逻辑错误:通过
componentsSeparated()拆分虚线路径时,得到的dottedPathComponents是原虚线路径拆分出的独立子路径,而这些子路径本身仍保留虚线样式属性,并非组成虚线的实心线段。逐个添加这些子路径到dottedPathCopy时,每个子路径会重新应用自身的虚线规则,导致子路径衔接处出现重复计算的间隙。 - 路径样式与路径本体绑定:
copy(dashingWithPhase:lengths:)生成的虚线路径,其虚线样式是和路径本身绑定的,并非将原路径切割为实心小段。拆分后的每个子路径都自带虚线属性,叠加时会在衔接位置产生额外的空白间隙,表现为视觉上的大缺失。 - 时间索引计算存在误差:
currentPathComponentIndex的计算方式(Int(Float(self.dottedPathComponents.count) * Float(timeEl / self.drawDuration) - 1))可能导致索引跳跃或遗漏,使得部分子路径未被及时添加,或重复添加,进一步放大间隙问题。
相关代码
import SpriteKit /// 首先用 node = SKShapeNode(splinePoints: &points, count: points.count) 初始化样条曲线 // 然后用 DashedSplinePath(fromSplinePath: node.path!) 创建用于动画的虚线路径 // 动画通过依次添加原样条副本的虚线路径段实现 class DashedSplinePath: SKShapeNode { var dottedPathCopy: CGMutablePath! var dottedPathComponents: [CGPath] = [] var drawDuration: TimeInterval = 5 var dashIndex = 0 private var _animatePath: SKAction { return SKAction.customAction(withDuration: drawDuration, actionBlock: { (node, timeEl) in let currentPathComponentIndex = Int( Float(self.dottedPathComponents.count) * Float(timeEl / self.drawDuration) - 1 ) if(self.dashIndex < currentPathComponentIndex) { self.dottedPathCopy.addPath(self.dottedPathComponents[self.dashIndex]) print(self.dottedPathComponents[self.dashIndex]) self.path = self.dottedPathCopy self.dashIndex += 1 print(self.dashIndex) } }) } func animateDottedPath() { self.dashIndex = 0 self.dottedPathComponents = self.path!.componentsSeparated() self.dottedPathCopy = dottedPathComponents.first!.mutableCopy() self.alpha = 1.0 self.zPosition = 0.0 self.run(_animatePath) } init(fromSplinePath: CGPath) { super.init() self.path = fromSplinePath.copy(dashingWithPhase: 100.0, lengths: [10]) self.zPosition = -1 self.glowWidth = 0 self.strokeColor = NSColor(red: 1.0, green: 0.3, blue: 0.3, alpha: 1.0) self.lineWidth = 10 self.alpha = 1.0 } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
内容的提问来源于Stack Exchange,提问作者KleinerWarden
相关产品推荐
相关产品推荐

