You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 12:07:29