0

I am new programmer developing an iOS game and would like to program an animated line to guide the user to drag an object from point A to point B. So I'd like the line to start (with length = 0) at point A and animate itself (to say length = 100 pixels) to point B.

I am using SKShapeNode, and currently to 'animate' it, I am really recreating the line each frame through the "update" method with a variable that depends on currentTime for the line to be slightly longer and longer length until it reaches the desired length using the following code (note that the line is dashed):

However I'm running into several performance issues that when I fix, cascade into more. I need to step away from having the object's length a function of the time that has elapsed from "-(void)update:(CFTimeInterval)currentTime". Instead I want to have one method that can be called to animate this line - I was reading and feel like this might be achievable through CoreAnimations (like CABasicAnimation here Ios drawing lines animated) but I'm not sure exactly how to accomplish this. Any help or guidance in the right direction would be much appreciated - thanks. Let me know if I can provide any additional information or explanation on anything!

-(void)drawLine : (CGFloat)ratio 
{


    CGPoint StartPoint = CGPointMake(0,0)
    CGPoint FinishPoint = CGPointMake(100,50);
    CGPoint AnimatedPoint = CGPointMake(FinishPoint.x*ratio +StartPoint.x*(1-ratio)+1, FinishPoint.y*ratio+StartPoint.y*(1-ratio)+1);

    CGFloat pattern[2];
    pattern[0] = self.size.height/30; //length of first pattern
    pattern[1] = self.size.height/30; //length of second pattern

    UIBezierPath *bezierPath=[UIBezierPath bezierPath];
    [bezierPath moveToPoint:StartPoint];
    [bezierPath addLineToPoint:AnimatedPoint];

    CGPathRef dashed =
    CGPathCreateCopyByDashingPath([bezierPath CGPath],
                                  NULL,
                                  0,
                                  pattern,
                                  2);
    lineDrawn.path = dashed; //this is of type SKShapeNode
    CGPathRelease(dashed);
}
Community
  • 1
  • 1
user3797886
  • 339
  • 1
  • 3
  • 16
  • Would you consider animating the line with sprites? For example have 20 sprites of the line growing, then animate using those sprites? Since you're using spritekit that probably be the most efficient way. Depends on if it fit your needs. – Joaquin Llaneza Mar 22 '15 at 08:45
  • If you are just drawing a straight line you might want to consider using one SKTexture with a center rect and changing it's xScale. You could even use an SKAction. See Resizing a Sprite https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Sprites/Sprites.html You would want to change the anchor of the sprite and would need to change the rotation to match the start and end point, but it might be another option and give you the performance you need. – Skyler Lauren Mar 22 '15 at 12:51
  • possible duplicate of [Is it possible to draw a line with SpriteKit animated?](http://stackoverflow.com/questions/19717570/is-it-possible-to-draw-a-line-with-spritekit-animated) – sangony Mar 22 '15 at 13:29

1 Answers1

4

Yes, you can (and probably should) use Core Animation instead of trying to draw your lines in a loop.

What you would do would be to create a CAShapeLayer. You'd install the CGPath from your UIBezierPath as the path in your shape layer, and add the shape layer as a sublayer of some view's layer in your view hierarchy.

You'd then create a CABasicAnimation that would animate the strokeEnd property of the shape layer from 0 (end = beginning: no line drawn) to 1.0 (line drawn fully from beginning to end.

This is a pretty common technique. You should be able to do a google search on "CAShapeLayer CABasicAnimation strokeEnd" and find examples that do more or less what you need to do. If You can't find any let me know and I'll point you in the right direction.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Yes. Short version: provide the full bezier path to CAShapeLayer and then animate on (either) the strokeStart, or strokeEnd properties. – Bobjt Aug 21 '16 at 21:15