IOS practice: complete the roller coaster through core animation

And finally, today to the last one, is drunk, get two or three months. From the very beginning, I plan to write only three articles, but I am not sure of it. A little bit added to what I am today. Because the increase in content is too much, but also almost become eunuch text, but fortunately did not give up on their own. So if you please, look good, just like a point, a small reward. It’s about me hair hair, eyes red. Wah Wah Wah Wah!

What to write next is not really good. Now the feeling is that a big stone in the chest, no, to go to enjoy the skin!!!!

I saw a HTML5/SVG implementation of the rollercoaster animation on a web site, and here we are looking at the web page. I think it’s great. Let’s think that iOS can be fully implemented, as well as a full review of what we’ve shared before about the iOS intermediate animation series. But today’s content is a little bit more, and I’m trying to say only the most important part, all of which is drawn from code.

Results after implementation: (this is to capture the book by Jane, don’t know why now if it is GIF, not as the thumbnail of a book.
)

IOS practice: complete the roller coaster through core animation
Paste_Image.png

Dynamic graph after completion:

IOS practice: complete the roller coaster through core animation
roller coaster.Gif

1. ideas and the content used

1.1 mind mapping

IOS practice: complete the roller coaster through core animation
roller coaster mind map.Png

1.2 the knowledge used

Here we use it:

  • CALayer, CAShapeLayer, CAGradientLayer, three kinds of layer.
  • The use of UIBeizerPath includes the two Bessel curve and the three Bessel curve, using the BeizerPath drawing circle.
  • Application of CAKeyframeAnimation. Before
    all the contents of the above articles have been written carefully how to use Da, if not clear buddies can read the previous article. Almost all of the content is in the iOS animation series.

1.3 the most time-consuming place

Especially want to come out and talk about this most time-consuming stuff. Do not think, of course, the train track is more trouble. But this is not the longest time for me. The longest time spent is actually the two snow capped mountains. In order to draw the two snow capped mountains, as well as the snow above the mountain, it is the old nose. So train tracks, snow mountains, I’ll take two separate bars to talk about this headache.

2. the creation of auxiliary elements (background, color, lawn, earth, trees, clouds)

After the completion of the auxiliary element, the effect diagram is:

IOS practice: complete the roller coaster through core animation
Paste_Image.png

2.1 gradual sky background

Using CAGradientLayer for setting is one of the most basic applications to transform at 45 degrees.
limited by space, I do not paste the code, in the source code inside to see it. Notes written in more detail, the sense of self. Ha ha ~
CAGradientLayer basic part, you can see this article, Ninth articles: iOS animation series nine: achieve point like animation and play the ups and downs indicator.

2.2 lawn

Mainly using two two Bessel curves.

[leftLawnPath moveToPoint:leftStartPoint]; [leftLawnPath addLineToPoint:CGPointMake (0, k_SIZE.height - 100)]; / / draw a two Bessel curve of [leftLawnPath addQuadCurveToPoint:CGPointMake (k_SIZE.width / 3, k_LAND_BEGIN_HEIGHT) controlPoint:CGPointMake (k_SIZE.width / 5, k_SIZE.height - 100)]; leftLawn.path = leftLawnPath.CGPath; leftLawn.fillColor = [UIColor colorWithDisplayP3Red:82.0 / 255 green:177.0 / 255 blue:52.0 / 255 alpha:1.0].CGColor / self.view.layer addSublayer:leftLawn]; CAShapeLayer; *rightLawn = [[CAShapeLayer alloc] init]; UIBezierPath *rightLawnPath = [[UIBezierPath alloc] init];

quadratic Bezier curve

- - (void) addQuadCurveToPoint: (CGPoint) endPoint controlPoint: (CGPoint) controlPoint;
IOS practice: complete the roller coaster through core animation
two times Bessel curve.Png

2.3 the realization of cloud animation

The clouds float through CAKeyframeAnimation, allowing them to move along the straight lines of the painting.

CALayer *cloud = [[CALayer alloc]init]; cloud.contents (__bridge = ID _Nullable ([UIImage) imageNamed:@ "cloud"].CGImage); cloud.frame = CGRectMake (0, 0, 63, 20); [self.view.layer addSublayer:cloud]; UIBezierPath *cloudPath = [[UIBezierPath alloc] init]; [cloudPath moveToPoint:CGPointMake (k_SIZE.width + 63, 50]); [cloudPath addLineToPoint:CGPointMake (-63, 50) CAKeyframeAnimation *ani = [CAKeyframeAnimation; animationWithKeyPath:@ "position"]; ani.path = cloudPath.CGPath; ani.duration = 30; ani.autoreverses = NO; ani.repeatCount = CGFLOAT_MAX; ani.calculationMode = kCAAnimationPaced; [cloud addAnimation:ani forKey:@ "position"];

2.4 the realization of the earth and the small tree

It was the CALayer that created the earth and the tree, and in order to use different methods, the earth, we filled the picture with backgroundColor. Layer of the sapling, we fill the picture by setting contents.

The earth background filled _landLayer.backgroundColor / colorWithPatternImage:[UIImage = [UIColor imageNamed:@ ground]].CGColor; / / tree setting treeLayer.contents = (__bridge ID _Nullable) (tree.CGImage);

In order to place a small tree in an uneven position, several loops were added and several small trees were added to the different Y axis positions.

3. snow capped mountains to achieve

Snow mountain is not particularly difficult to achieve, the main is very cumbersome. I also forgot a small formula for junior high school, which delayed some time in this place.

3.1 snow mountain train of thought

Take a snow mountain for example. At first glance, the snow mountain is divided into two parts: the lower part of the snow mountain and the snow on the top of the mountain. Soon, I gave up the idea. In that case, the middle part of the curve would be killing people. So change the idea: first draw a snow covered mountain, then paint a brown land on it.

That’s what it’s like after completion:

IOS practice: complete the roller coaster through core animation
snow mountain.Png

3.2 steps in snow mountain painting

STEP ONE:

IOS practice: complete the roller coaster through core animation
snow capped snow capped mountains.Png

STEP TWO:

IOS practice: complete the roller coaster through core animation
adds brown mountain to snow mountain.Png

STEP THREE:

IOS practice: complete the roller coaster through core animation
second sits in the snow capped snow mountain.Png

STEP FOUR:

IOS practice: complete the roller coaster through core animation
snow mountain.Png

3.3 points to note

In the process of painting the mountain, the most complex is to find the mountain on the left and right sides of the hillside on the edge of the point of CGPoint.
is at the point where snow begins on the first hill on the left side of the hill. In fact, the coordinates of any point between the foot of the mountain and the top of the mountain are to be calculated. When you know the X axis coordinates, you must calculate the Y axis coordinates.
this is the formula we learned in junior high school, y = KX + B. K is the slope, and B is the intercept. The starting point and the end point have been known, and the slope k can be easily calculated. According to K, calculate the B again. In this way, the Y axis coordinates can be easily computed by giving the X axis coordinates at any point on this line. XY knows, and CGPoint doesn’t know.

- (CGPoint) calculateWithXValue: (CGFloat) xvalue startPoint: (CGPoint) startPoint endpoint: (CGPoint) endpoint{/ / for two segment slope CGFloat k = (endpoint.y - startPoint.y) / (endpoint.x - startPoint.x); CGFloat B = startPoint.y - startPoint.x * k; CGFloat yvalue = k * xvalue + CGPointMake (xvalue, B; return yvalue);}

3.4 take the mountain on the left as an example

On the left / first mountain, is actually a white triangle CAShapeLayer *leftSnowberg = [[CAShapeLayer alloc] init]; UIBezierPath *leftSnowbergPath = [[UIBezierPath alloc] init]; / / the bezierpath starting point moves to the lower left corner of the snow capped mountains [leftSnowbergPath moveToPoint:CGPointMake (0, k_SIZE.height - 120)]; / / draw a line to the top of [leftSnowbergPath addLineToPoint:CGPointMake (100, 100)]; / / draw a line to the lower right corner of the lower left corner of the -> -> [leftSnowbergPath addLineToPoint:CGPointMake; closed (k_SIZE.width / 2, k_LAND_BEGIN_HEIGHT); [leftSnowbergPath addLineToPoint:CGPointMake (0, k_LAND_BEGIN_HEIGHT); [leftSnowbergPath closePath]; leftSnowberg.path = leftSnowbergPath.CGPath; leftSnowberg.fillC Olor = [UIColor whiteColor].CGColor; [self.view.layer addSublayer:leftSnowberg]; / / to draw no snow covered mountain part of the CAShapeLayer *leftSnowbergBody alloc] init] UIBezierPath = [[CAShapeLayer; *leftSnowbergBodyPath = [[UIBezierPath alloc] init]; / / the bezierpath starting point moves to the lower left corner of the snow the same position CGPoint startPoint = CGPointMake (0, k_SIZE.height - 120; endPoint = CGPointMake (CGPoint) 100, 100); CGPoint firstPathPoint = [self calculateWithXValue:20 startPoint: startPoint endpoint:endPoint]; [leftSnowbergBodyPath moveToPoint:startPoint]; [leftSnowbergBodyPath addLineToPoint:firstPathPoint]; [leftSnowbergBodyPath addLineToPoint:CGPointMake (60, firstPathPoint.y) []; LeftSnowbergBodyPath addLineToPoint:CGPointMake (100, firstPathPoint.y + 30); [leftSnowbergBodyPath addLineToPoint:CGPointMake (140, firstPathPoint.y); [leftSnowbergBodyPath addLineToPoint:CGPointMake (180, firstPathPoint.y - 20)]; CGPoint secondPathPoint = [self (calculateWithXValue: / k_SIZE.width 2 - startPoint:endPoint endpoint:CGPointMake (125) k_SIZE.width / 2, k_LAND_BEGIN_HEIGHT); [leftSnowbergBodyPath addLineToPoint:CGPointMake (secondPathPoint.x - 30, firstPathPoint.y)] [leftSnowbergBodyPath; addLineToPoint:secondPathPoint]; [leftSnowbergBodyPath addLineToPoint:CGPointMake (k_SIZE.width / 2, k_LAND_BEGIN_HEIGHT); [leftSnowbergBodyPath addLineToPoint:CGPointMake (0, k_LAND_BEGIN_HEIGHT)]; [leftSnowbe RgBodyPath closePath]; leftSnowbergBody.path = leftSnowbergBodyPath.CGPath; UIColor = *snowColor [UIColor colorWithDisplayP3Red:139.0 /255.0 green:92.0 /255.0 blue:0.0 /255.0 alpha:1.0]; leftSnowbergBody.fillColor = snowColor.CGColor; self.view.layer addSublayer:leftSnowbergBody];

The realization of 4. track

IOS practice: complete the roller coaster through core animation
Paste_Image.png

The main part of the orbit is the two Bessel curve and the three Bessel curve. Let’s share it with the most complicated green, circled orbit. It’s made up of three parts, considering that in the end we’ll roll the roller from the right, go to the left, and we’ll draw from the far right.
has a two Bessel curve on the right, with a circle in the middle, and a three Bessel curve on the left. After the painting, use the picture to fill, completed 90% of the work.
in order to make the orbit look better, hollow the edges of the track and make the inner filling color transparent.

4.1 steps in painting

1, draw the right arc first, and a two Bessel curve.

IOS practice: complete the roller coaster through core animation
Paste_Image.png

2, draw a circle. Notice the radius of the circle and the position of the center of the circle.

IOS practice: complete the roller coaster through core animation
Paste_Image.png

3, draw the curve on the left, a three Bessel curve. In fact, there are two control points of the curve.

IOS practice: complete the roller coaster through core animation
Paste_Image.png

4, close the curve.

IOS practice: complete the roller coaster through core animation
Paste_Image.png

5, fill in the background color of the curve for the small squares you have prepared.

IOS practice: complete the roller coaster through core animation
Paste_Image.png

6, to make the track look more realistic, let the edges of the curves become dashed.

IOS practice: complete the roller coaster through core animation
Paste_Image.png

4.2, three Bessel curve

- - (void) addCurveToPoint: (CGPoint), endPoint, controlPoint1: (CGPoint), controlPoint1, controlPoint2: (CGPoint), controlPoint2;

The starting point is set by the moveToPoint method, endPoint: the end of the Bessel curve; the controlPoint1: control point 1; the controlPoint2: control point 2.

The curve is the curve from the starting point to the control point 1, then to the control point 2 and finally to the finish line.

IOS practice: complete the roller coaster through core animation
Paste_Image.png

4.3 code implementation

The code for the green track rendering section:

From the right side of the train tracks / Green enter, so from the right start painting. Need to draw three curves, right in the middle of a + circle + left a UIBezierPath *path = [[UIBezierPath alloc] init]; [path moveToPoint:CGPointMake (k_SIZE.width + 10, k_LAND_BEGIN_HEIGHT); [path addLineToPoint:CGPointMake (k_SIZE.width + 10, k_SIZE.height - 70); [path addQuadCurveToPoint:CGPointMake (k_SIZE.width / 1.5, k_SIZE.height - 70 (k_SIZE.width - 150) controlPoint:CGPointMake, 200)]; / / circle [path addArcWithCenter:CGPointMake (k_SIZE.width / 1.6, k_SIZE.height - 140) radius:70 startAngle:M_PI_2 endAngle:2.5 * M_PI clockwise:YES] [path; addCurveToPoint:CGPointMake (0, k_SIZE.height - 100) controlPoint1:CGPointMake (k_SIZE.width / 1.8 - 60, k_SIZE.height - 60 controlPoint2:CGPointMake (150, k_SIZE.heig) HT / 2.3)]; [path addLineToPoint:CGPointMake (- 10 k_LAND_BEGIN_HEIGHT)]; _greenTrack.path = path.CGPath; _greenTrack.fillColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@ "green"]].CGColor;

Code for track edge hollowing:

In order to make more attractive / / arc point, need to join the hollow CAShapeLayer *trackLine = [[CAShapeLayer alloc] line init]; trackLine.lineCap = kCALineCapRound; trackLine.strokeColor = [UIColor whiteColor].CGColor; trackLine.lineDashPattern = @[@1.0, @6.0]; trackLine.lineWidth = 2.5; trackLine.fillColor = [UIColor clearColor].CGColor; trackLine.path = path.CGPath; [_greenTrack addSublayer:trackLine];

And finally, if written in
tell me what you think of this article does a harvest, then give me a praise or powder. Further, if you accept this little bit of hard work, and reward some coke money, small willing to give God laugh a ^& ^

OC version of the source code here: http://git.oschina.net/atypical/rollercoaster
, the masses if the voice is relatively high, it is still old practice, and then write the swift version. If no one is interested, I will take you to buy some small silver award in the area to see, lehe.

Gorgeous and dividing line, iOS animation series,
link: one of the first iOS animated series: learning CALayer and perspective principle through the actual combat. A belt when the pointer of the clock animation (on)
second: iOS animation series two: learning CALayer and perspective principle through the actual combat. A belt when the pointer clock animation. Contains OC and Swift two source code (below)
third: iOS animation series three: Core Animation. The common attributes and methods of Core Animation are introduced.
fourth: CABasic Animation. IOS animation series four: translation of basic animation chapter
fifth: CABasic Animation. IOS animation series five: zoom based animation &amp
sixth; rotation: iOS animation series six: using CABasic Animation complete with animation login interface
seventh: iOS seven: the animated series to achieve similar Twitter
boot animation eighth: iOS animation series eight: CAShapeLayer painting figure ninth: dynamic flow
iOS animation series nine: praise animation and broadcast UPS indicator
tenth: Combat series: roller coaster scene rendering