【问题标题】:SKAction followPath not working as expected with two circles (Eight Shape)SKAction followPath 无法按预期使用两个圆圈(八形)
【发布时间】:2017-10-29 14:07:32
【问题描述】:

我正在尝试创建一个形状为 8 或无穷大的 CGPath。我确实认为路径创建应该返回所需的结果,但我仍然会在这里发布:

let path = CGMutablePath()

path.addEllipse(in: CGRect(x: -height/4, y: -height/2, width: height/2, height: height/2))
path.addEllipse(in: CGRect(x: -height/4, y: 0.0, width: height/2, height: height/2))

path.closeSubpath()

return path

现在我有另一个节点应该遵循这条路径,我认为它可以像这样使用 SKAction 来工作:

highlighter.run(SKAction.repeatForever(SKAction.follow(shape.path!, asOffset: false, orientToPath: true, duration: 5.0)))

highlighter 是我的节点的名称,shape 是我分配路径的 SKShapeNode 的名称。然而,该节点仅绘制其中一个圆圈,而不是所需的形状。我一直在谷歌搜索这个问题,但找不到任何类似的案例,现在已经坐了一天多,所以我可能看不到明显的东西。任何见解将不胜感激!

【问题讨论】:

    标签: ios swift sprite-kit skaction cgpath


    【解决方案1】:

    如果你绘制你生成的图 8,你会看到你的精灵只跟随底部的圆圈,因为这是你绘制路径的方式。

    您需要从顶部/底部到中间绘制顶部或底部圆圈的一半,然后添加从中间开始和结束的完整的另一个圆圈,最后再将另一半圆圈返回到您开始的位置。

    这是一个例子,它还绘制了边界矩形和要遵循的图 8 路径:

    class GameScene: SKScene {
    
        //    var sprite = SKSpriteNode()
        var figureEightPath = CGMutablePath()
    
        override func didMove(to view: SKView) {
    
            let boundingRect = CGRect(x: -200, y: -400, width: 400, height: 800)
            addChild(drawSKShapeNode(fromRect: rect, withWidth: 2, inColour: SKColor.green, called: "rect"))
    
            figureEightPath = drawFigureEight(in: boundingRect)
            addChild(drawSKShapeNode(fromPath: figureEightPath, withWidth: 2, inColour: SKColor.red, called: "path"))
    
            let sprite = SKSpriteNode(color: SKColor.yellow, size: CGSize(width: 50, height: 50))
            addChild(sprite)
    
            let moveAction = SKAction.follow(figureEightPath, asOffset: false, orientToPath: true, speed: 200)
            sprite.run(SKAction.repeatForever(moveAction))
    
        }
    
        func drawSKShapeNode(fromPath path: CGMutablePath,
                             withWidth width: CGFloat,
                             inColour colour: SKColor,
                             called name: String) -> SKShapeNode {
    
            let shape = SKShapeNode(path: path, centered: true)
            shape.lineWidth = width
            shape.strokeColor = colour
            shape.name = name
            return shape
        }
    
        func drawSKShapeNode(fromRect rect: CGRect,
                             withWidth width: CGFloat,
                             inColour colour: SKColor,
                             called name: String) -> SKShapeNode {
    
            let shape = SKShapeNode(rect: rect)
            shape.lineWidth = width
            shape.strokeColor = colour
            shape.name = name
            return shape
        }
    
        func drawFigureEight(in rect: CGRect) -> CGMutablePath {
            let bottomCentre = CGPoint(x: rect.midX, y: rect.height/4+rect.minY)
            let topCentre = CGPoint(x: rect.midX, y:(rect.height/4)*3+rect.minY)
            let radius = rect.height/4
    
            let bottom = CGPoint(x: rect.midX, y: rect.minY)
    
            let path = CGMutablePath()
            path.move(to: bottom)
    //Draw a semi-circle from the bottom counter-clockwise to the middle
            path.addArc(center: bottomCentre, radius: radius, startAngle: CGFloat(Double.pi*1.5), endAngle: CGFloat(Double.pi/2), clockwise: false)
    //Draw to top circle in a clockwise direction
            path.addArc(center: topCentre, radius: radius, startAngle: CGFloat(Double.pi*1.5), endAngle: CGFloat(-Double.pi/2), clockwise: true)
    //Draw the rest of the bottom circle by drawing a semi-circle from the middle to the bottom counter-clockwise.
            path.addArc(center: bottomCentre, radius: radius, startAngle: CGFloat(Double.pi/2), endAngle: CGFloat(-Double.pi/2), clockwise: false)
    
            return path
        }
    
        override func update(_ currentTime: TimeInterval) {
            // Called before each frame is rendered
        }
    }
    

    有几个辅助函数 - drawSKShapeNode - 您不需要,但它们对调试很有用,因为它们通过根据给定的内容创建 SKShapeNode 来“绘制”CGPath 或 CGRect。

    【讨论】:

    • 这很有意义。我刚刚用您的建议替换了我的代码,效果很好。非常感谢史蒂夫的详细回答!
    • 精灵按照路径绘制的顺序跟随路径。在您的原始示例中,当它到达其中一个圆圈的底部时,它没有到达顶部圆圈的路径,因此它停止了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多