Мне нужно нарисовать линию между двумя спринтодами, когда рука указывает от одного узла к другому с помощью рендеринга или анимации.Рисование линий работает для меня, так как я перехожу по этой ссылке, ответ Бобджта Animate Path Drawing in SpriteKit .Здесь я использовал концепцию фрагментного шейдера и вершинного шейдера ..
Я добавил файл animatestroke.fsh и применил следующий код. Но анимация в ручном режиме и скорость рисования линий иногда не совпадают.рендеринг моей линии, я дал приращение на
strokeLengthFloat += 0.01
А продолжительность хэндплеера составляет 1,5:
let moveTosecondObject = SKAction.move(to: handmovepoint, duration: 1.5 )
Вот мой код реализации:
объявление переменной
var handplayer = SKSpriteNode()
var firstObject = SKSpriteNode()
var secondObject = SKSpriteNode()
var startTrigger: Bool = false
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) {
handplayer = SKSpriteNode(imageNamed: "HandImage.png")
handplayer.size.width = handplayer.size.width * 0.5
handplayer.size.height = handplayer.size.height * 0.5
handplayer.position.x = firstObject.position
self.addChild(handplayer)
UpdatePosition()
}
func UpdatePosition(){
//Line drawing part
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
let lineStartPosition = CGPoint(x:firstObject.frame.origin.x+firstObject.size.width/2,y:firstObject.frame.origin.y-firstObject.size.height*0.2)
let lineEndPosition = CGPoint(x:secondObject.frame.origin.x+secondObject.size.width/2,y:secondObject.frame.origin.y+secondObject.size.height*1.2)
let path = CGMutablePath()
path.move(to: CGPoint(x: lineStartPosition.x, y: lineStartPosition.y))
path.addLine(to: CGPoint(x: : lineEndPosition.x, y: lineEndPosition.y), transform: CGAffineTransform.identity)
let strokeWidth = 1.0 * strokeSizeFactor
let shapeNode = SKShapeNode( path: path )
shapeNode.lineWidth = strokeWidth
shapeNode.lineCap = .square
shapeNode.addChild( cameraNode )
shapeNode.strokeShader = strokeShader
shapeNode.calculateAccumulatedFrame()
self.addChild( shapeNode )
}
// center the camera
cameraNode.position = CGPoint( x: self.frame.size.width/2.0, y: self.frame.size.height/2.0 )
**Handplayer Rendering part**
let handmovepoint = CGPoint(x: secondObject.position.x , y: secondObject.position.y + handplayer.size.height*0.1 )
let moveTosecondObject = SKAction.move(to: handmovepoint, duration: 1.5 )
let delay = SKAction.wait(forDuration: 1)
handplayer.run(SKAction.sequence([ delay ]), completion: {() -> Void in
self.startTrigger = true
self.handplayer.run(SKAction.sequence([ moveTosecondObject ]), completion: {() -> Void in
//self.handplayer.alpha = 0.0
})
}
//line rendering part
override func update(_ currentTime: TimeInterval) {
if(startTrigger){
strokeLengthFloat += 0.01
}
if startTrigger == true{
if strokeLengthFloat > 1.0 {
//once line drawing completed
self.startTrigger = false
print("Line drawing ended")
self.handplayer.alpha = 0.0
self.handplayer.removeFromParent()
}
}
}
animatestroke.fsh class
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
}
}
Как я могу это исправить?Или, если у кого-то есть другая идея для реализации этого сценария, поделитесь своей идеей.