简介
这篇主要介绍CAKeyframeAnimation关键帧动画和CATransform3D的简单使用,scenekit实现的飞机游戏在下一篇详细介绍。传送门
先看看实现的动画效果,下面在逐个分析。git项目地址
动画分析和实现
1. 摇钱树
这是我第一个app中的一个动画,看到需求后一头雾水,由于当时才接触ios,简直无从下手,经过各种百度后才找到一些头绪。从监听手机震动,到树干摇晃,最后掉落元宝,逐步理清了各个对象需要执行的行为动作。下面我会贴一些代码,具体的还请去项目中查看,代码注释也写得很详细。
手机摇晃监听
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
NSLog(@"%@",NSStringFromSelector(_cmd));
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
NSLog(@"%@",NSStringFromSelector(_cmd));
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);//系统震动
[self ybAnimation];
[self shakeYQS:yqsImage];
}
摇晃树干
- (void)shakeYQS:(UIImageView *)view
{
//表示以z坐标轴为中心轴旋转
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.values = @[@(0),@(-M_PI_4/2),@(0),@(M_PI_4/2),@(0),
@(-M_PI_4/3),@(0),@(M_PI_4/3),@(0),
@(-M_PI_4/4),@(0),@(M_PI_4/4),@(0),
@(-M_PI_4/5),@(0),@(M_PI_4/6),@(0)];//设置树的摇晃幅度,分母变大表示摇晃幅度越来越小,不断h衰减至0。
animation.repeatCount = 1;
animation.duration = 1;
[view.layer addAnimation:animation forKey:@"shake"];
}
这里要理解keypath的意思,从代码中可以很直观的看出监听的是z轴旋转属性,判断旋转方向可以用握手定则,用手握住坐标轴,大拇指指向坐标轴方向,其余四指为旋转的方向,至于顺逆时针,需要视情况而定。
至于元宝掉落,就是简单的一个平移动画
//元宝掉落
- (void)ybAnimation
{
for (int i = 0; i< ybArray.count; i++) {
UIImageView * yb = ybArray[i];
int x = rand()%215;
int y = rand()%60 + 60;
yb.frame = CGRectMake(x + MinX(yqsImage), y + MinY(yqsImage), yb.frame.size.width, yb.frame.size.height);
yb.hidden = NO;
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position.y"];
animation.delegate = self;
animation.values = @[@(yb.frame.origin.y), @(yb.frame.origin.y+200)];
float startTime = 0;
animation.repeatCount = 1;
float endTime = (float)(arc4random()%100) / 100 + 0.5;
animation.keyTimes = @[@(startTime), @(endTime)];
animation.duration = endTime;
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
[animation setValue:@"ybDrop" forKey:@"ybAnimation"];
[animation setValue:yb forKey:@"animationView"];
[yb.layer addAnimation:animation forKey:@"ybAnimation"];
}
}
其实拿到一个动画需求后,首先要理清的就是整个动画过程中,每个对象执行了哪些行为。分析好后,然后就往基本动画上套就行了,比如,平移,缩放,旋转这些,再复杂点可能会加入路径,3D场景变换等等,当然这些也需要一定的知识积累。下面两个简单动画,我就不贴代码了,只写一些分析思路。
2. 唱片动画
从图中知道,唱针和唱片执行的都是旋转动画,不同在于,唱针只旋转了几十度,而唱片却是旋转的360度,然后一直循环执行。
3. 闪烁动画
这里中间的头像在不断放大缩小,明显头像执行的是缩放动画。然后使用了贝塞尔曲线画了两个圈,一个静止,另一个在执行一个组合动画,即在扩大过程中,颜色逐渐变淡。这里我模仿的是抖音直播时,头像的闪烁动画。
4. 扇形统计图
这个稍微复杂一点,从画出扇形,到动画执行,最后计算每个扇形的点击范围并做出偏移。
首先,使用UIBezierPath和CAShapeLayer,画出扇形。光画出来还是比较简单,然后是动画执行。怎样才会产生上图那种类似扫描的效果?先来看看圆形进度条动画
想象一下,如果把边界的宽度一点点扩大达到圆的半径的长度,是不是就会出现扇形图扫描一样的动画了。
图形画好后,还要判断点击范围,这里采用的数学公式计算。首先判断该点是否在圆内,即点到圆心的距离是否大于半径;然后是触摸点跟圆心连成的直线和起始边形成的夹角是在哪个扇形区域类,都能通过公式计算出来。最后点击扇形执行偏移事件。(具体的计算公式请结合项目中的代码查看理解)
5. 飞机游戏
飞机游戏的实现其实并不如想象中困难,主要基于SceneKit实现的,SceneKit中封装了很多对象,使其从建立模型到执行动画行为,操作起来都简单易懂,感觉比较适合做一些小游戏开发。我会在下一篇文章中写出我的开发思路。传送门
6. 使用View构造一个立方体
这里主要使用了CATransform3D属性,该属性封装了layer层的3D旋转,平移,缩放等操作。这里通过对6个view的平移和旋转实现的立方体显示。
7. 视图的3d旋转
用Pan手势实现的,手指拖动图片时计算出向量坐标,然后通过CATransform3DRotate来实现旋转。主要逻辑代码就几行,详细注释请在项目查看。
完结
感兴趣的可以去项目地址下载下来看看。git项目地址