2015-05-08 2 views
0

Я хочу анимировать рисунок закругленной рамки. Я видел ответ, когда парень использовал CGLinePath, чтобы нарисовать форму дома. Я думал, что это было аккуратно, честно.SpriteKit: Как оживить рисунок закругленного прямоугольника

Я знаю очень мало о Core Animation и о том, как его реализовать в SKScene. Я не знаю, что бы вы добавили. Я видел пару разных решений, чтобы получить то, куда я хочу пойти, используя Core Animation, но это не помогает мне нарисовать прямоугольник с закругленными краями в моей сцене как узел.

Я видел это тот, где парень использует Core Animation, чтобы нарисовать круг, и загружает его в UIView: Animate drawing of a circle

Я хочу, чтобы это узел, однако, так что я могу применить некоторые SKAction " с ним.

ответ

2

Использование SKShapeNode с действиями.

Это детали закругленными прямоугольник с skshapenode: SKSpriteNode - create a round corner node?

Теперь просто анимировать изменение с действием.

+0

Я не знал, что вы могли бы назначить путь к «SKShapeNode» до сих пор, и я не знал, что до этого был идентификатор 'CGCreatePathWithRoundedRect'. Спасибо! – DDPWNAGE

0

Добавляем к ответу, так как OP явно запрашивала анимацию длины хода с течением времени, отмечая, что для этого нет SKAction. Вместо этого вы можете анимировать путь SKShapeNode путем предоставления настраиваемого strokeShader, который выводит на основе нескольких из , SKShader и u_path_length. Обратите внимание, что в шейдере, указанном ниже u_current_percentage, мы добавили и ссылаемся на текущую точку в пути, к которому мы хотим погладить. При этом сцена определяет темп анимированного поглаживания. Также обратите внимание, что strokeShader в качестве фрагментарного шейдера выводит RGB на каждом шагу, он позволяет вам управлять цветом по мере продвижения, позволяя, чтобы вы делали цвет градиента, если хотите.

Шейдер добавляется в виде файла в Xcode проекта animateStroke.fsh:

void main() 
{ 
    if (u_path_length == 0.0) { 
     gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); // draw blue // this is an error 
    } else if (v_path_distance/u_path_length <= u_current_percentage) { 
     gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // draw red 
    } else { 
     gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); // draw nothing 
    } 
} 

и образец SKScene подкласса, используя его:

import SpriteKit 
import GameplayKit 


func shaderWithFilename(_ filename: String?, fileExtension: String?, uniforms: [SKUniform]) -> SKShader { 
    let path = Bundle.main.path(forResource: filename, ofType: fileExtension) 
    let source = try! NSString(contentsOfFile: path!, encoding: String.Encoding.utf8.rawValue) 
    let shader = SKShader(source: source as String, uniforms: uniforms) 
    return shader 
} 

class GameScene: SKScene { 

    let strokeSizeFactor = CGFloat(2.0) 
    var strokeShader: SKShader! 
    var strokeLengthUniform: SKUniform! 
    var _strokeLengthFloat: Float = 0.0 
    var strokeLengthKey: String! 
    var strokeLengthFloat: Float { 
     get { 
      return _strokeLengthFloat 
     } 
     set(newStrokeLengthFloat) { 
      _strokeLengthFloat = newStrokeLengthFloat 
      strokeLengthUniform.floatValue = newStrokeLengthFloat 
     } 
    } 

    override func didMove(to view: SKView) { 

     strokeLengthKey = "u_current_percentage" 
     strokeLengthUniform = SKUniform(name: strokeLengthKey, float: 0.0) 
     let uniforms: [SKUniform] = [strokeLengthUniform] 
     strokeShader = shaderWithFilename("animateStroke", fileExtension: "fsh", uniforms: uniforms) 
     strokeLengthFloat = 0.0 

     let cameraNode = SKCameraNode() 
     self.camera = cameraNode 

     // make your rounded rect 
     let path = CGMutablePath() 
     path.addRoundedRect(in: CGRect(x: 0, y: 0, width: 200, height: 150), cornerWidth: 35, cornerHeight: 35, transform: CGAffineTransform.identity) 

     // note that prior to a fix in iOS 10.2, bug #27989113 "SKShader/SKShapeNode: u_path_length is not set unless shouldUseLocalStrokeBuffers() is true" requires that a path be "long" - past a certain number of points - I don't know how many. So if the rounded rect doesn't work for you on iOS 10 - iOS 10.1, try this path instead: 
     // let path1 = CGMutablePath() 
     // path1.move(to: CGPoint.zero) 
     // path1.addLine(to: CGPoint(x: 0, y: strokeHeight)) 
     // for i in 0...15 { 
     // path.addLine(to: CGPoint(x: 0, y: strokeHeight + CGFloat(0.001) * CGFloat(i))) 
     // }    
     // path.closeSubpath()    

     let strokeWidth = 17.0 * strokeSizeFactor 
     let shapeNode = SKShapeNode(path: path) 
     shapeNode.lineWidth = strokeWidth 
     shapeNode.lineCap = .round 
     shapeNode.addChild(cameraNode) 
     shapeNode.strokeShader = strokeShader 
     shapeNode.calculateAccumulatedFrame() 
     addChild(shapeNode) 

     // center the camera 
     cameraNode.position = CGPoint(x: shapeNode.frame.size.width/2.0, y: shapeNode.frame.size.height/2.0) 


    } 

    override func update(_ currentTime: TimeInterval) { 

     // the increment chosen determines how fast the path is stroked. Note this maps to "u_current_percentage" within animateStroke.fsh 
     strokeLengthFloat += 0.01 
     if strokeLengthFloat > 1.0 { 
      strokeLengthFloat = 0.0 
     } 

    } 
} 
+0

У меня это работает, но я не могу за всю жизнь понять, как изменить цвет в GameScene ?? – Adam

+0

Ещё одна вещь, возможно ли изменить ширину линии в то же время, что и длина? так что ширина - это процент от длины и изменений во время анимации? Благодарю. – Adam

Смежные вопросы