zoukankan      html  css  js  c++  java
  • ios 动画系列之七------吃豆人动画的实现

    本文参考自:http://blog.csdn.net/totogo2010/article/details/8606089,尊重原创!又做了点自己的加工,最终实现了一个小人追这个豆子跑的动画,可随时暂停、继续。

    效果如下:                

    实现该动画的思路很简单:pacman的开口,闭口,以及pacman的行走路径。至于开口、闭口之间的效果并不需要我么实现,插值计算会自动补全动画的。而动画的暂停、继续我们在ios动画系列三这篇文章中已经讲过了,苹果给的有例子。

    直接附上代码:

     1 //
     2 //  PacmanViewController.h
     3 //  AnimationDemo
     4 //
     5 //  Created by yuqiu on 13-7-23.
     6 //  Copyright (c) 2013年 rongfzh. All rights reserved.
     7 //
     8 
     9 #import <UIKit/UIKit.h>
    10 #import <QuartzCore/QuartzCore.h>
    11 @interface PacmanViewController : UIViewController
    12 {
    13     UIBezierPath *_pacmanOpenPath;
    14     UIBezierPath *_pacmanClosedPath;
    15     CAShapeLayer *_shapeLayer;
    16     CAShapeLayer *_ballLayer;
    17     UIBezierPath *_ballPath;
    18 }
    19 @end
    PacmanViewController.h
      1 //
      2 //  PacmanViewController.m
      3 //  AnimationDemo
      4 //
      5 //  Created by yuqiu on 13-7-23.
      6 //  Copyright (c) 2013年 rongfzh. All rights reserved.
      7 //
      8 
      9 #import "PacmanViewController.h"
     10 #define DEGREES_TO_RADIANS(x) (3.14159265358979323846 * x / 180.0)
     11 
     12 @interface PacmanViewController ()
     13 
     14 @end
     15 
     16 @implementation PacmanViewController
     17 - (void)viewDidLoad
     18 {
     19     [super viewDidLoad];
     20     UIButton *btn = [[UIButton alloc]init];
     21     [btn setTitle:@"暂停" forState:UIControlStateNormal];
     22     btn.frame = CGRectMake(10, 400, 145, 40);
     23     btn.backgroundColor = [UIColor greenColor];
     24     [btn addTarget:self action:@selector(pauseLayer) forControlEvents:UIControlEventTouchUpInside];
     25     [self.view addSubview:btn];
     26     
     27     [super viewDidLoad];
     28     UIButton *btn1 = [[UIButton alloc]init];
     29     [btn1 setTitle:@"继续" forState:UIControlStateNormal];
     30     btn1.frame = CGRectMake(160, 400, 145, 40);
     31     btn1.backgroundColor = [UIColor greenColor];
     32     [btn1 addTarget:self action:@selector(resumeLayer) forControlEvents:UIControlEventTouchUpInside];
     33     [self.view addSubview:btn1];
     34 
     35     
     36     self.view.backgroundColor = [UIColor yellowColor];
     37     
     38     CGFloat radius = 30.0f;//半径
     39     CGFloat diameter = radius * 2;//直径
     40     CGPoint arcCenter = CGPointMake(radius, radius);//中心点坐标
     41     
     42     // Create a UIBezierPath for Pacman's open state
     43     //以某个点为中心画弧线   创建pacman的开口路径
     44     _pacmanOpenPath = [UIBezierPath bezierPathWithArcCenter:arcCenter  //弧线中心点的坐标
     45                                                     radius:radius  //弧线所在圆的半径
     46                                                 startAngle:DEGREES_TO_RADIANS(35) //弧线开始的角度值
     47                                                   endAngle:DEGREES_TO_RADIANS(325) //弧线结束的角度值
     48                                                  clockwise:YES]; //是否顺时针画弧线
     49     
     50     [_pacmanOpenPath addLineToPoint:arcCenter]; 
     51     [_pacmanOpenPath closePath];
     52     
     53     // Create a UIBezierPath for Pacman's close state
     54     // 创建pacman的闭口路径
     55     _pacmanClosedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter
     56                                                       radius:radius
     57                                                   startAngle:DEGREES_TO_RADIANS(0)
     58                                                     endAngle:DEGREES_TO_RADIANS(360)
     59                                                    clockwise:YES];
     60     [_pacmanClosedPath addLineToPoint:arcCenter];
     61     [_pacmanClosedPath closePath];
     62     
     63     // Create a CAShapeLayer for Pacman, fill with yellow
     64     //创建这个Pacman的实体,目前还不知道这是怎么创建的???????
     65     _shapeLayer = [CAShapeLayer layer];
     66     _shapeLayer.path = _pacmanClosedPath.CGPath;//path定义了这个shape渲染的范围
     67     _shapeLayer.fillColor = [UIColor greenColor].CGColor;//整个shape的填充色    
     68     _shapeLayer.strokeColor = [UIColor grayColor].CGColor;//画笔的颜色,即边界线的颜色
     69     _shapeLayer.lineWidth = 1.0f;//layer边界线宽
     70     //_shapeLayer.bounds = CGRectMake(0, 0, diameter, diameter);//layer的边界大小
     71     _shapeLayer.position = CGPointMake(0, 40);//layer在它的superLayer上的位置
     72 //    _shapeLayer.frame = CGRectMake(0, 40, diameter, diameter);
     73     [self.view.layer addSublayer:_shapeLayer];
     74 
     75     //创建一个球球
     76     _ballPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(10,0) radius:10 startAngle:DEGREES_TO_RADIANS(0) endAngle:DEGREES_TO_RADIANS(360) clockwise:YES];
     77     _ballLayer = [CAShapeLayer layer];
     78     _ballLayer.fillColor = [UIColor redColor].CGColor;
     79     _ballLayer.path = _ballPath.CGPath;
     80     _ballLayer.position = CGPointMake(60,70);
     81     [self.view.layer addSublayer:_ballLayer];
     82 
     83     UIGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(startAnimation)];
     84     [self.view addGestureRecognizer:recognizer];   
     85 }
     86 
     87 - (void)startAnimation {
     88     // 创建咬牙动画
     89     CABasicAnimation *chompAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
     90     chompAnimation.duration = 0.25;
     91     chompAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
     92     chompAnimation.repeatCount = HUGE_VALF;//无穷大
     93     chompAnimation.autoreverses = YES;
     94     // Animate between the two path values
     95     chompAnimation.fromValue = (id)_pacmanClosedPath.CGPath;
     96     chompAnimation.toValue = (id)_pacmanOpenPath.CGPath;
     97     [_shapeLayer addAnimation:chompAnimation forKey:@"chompAnimation"];
     98     
     99     // Create digital '2'-shaped path
    100     //创建pacman走的路径
    101     UIBezierPath *path = [UIBezierPath bezierPath];
    102     [path moveToPoint:CGPointMake(30, 40)];
    103     [path addLineToPoint:CGPointMake(280, 40)];
    104     [path addLineToPoint:CGPointMake(280, 180)];
    105     [path addLineToPoint:CGPointMake(60,180)];
    106     [path addLineToPoint:CGPointMake(60, 300)];
    107     [path addLineToPoint:CGPointMake(300, 300)];
    108     
    109     //行走动画    
    110     CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    111     moveAnimation.repeatCount = HUGE_VALF;
    112     moveAnimation.path = path.CGPath;
    113     moveAnimation.duration = 6.0f;
    114     // Setting the rotation mode ensures Pacman's mouth is always forward.  This is a very convenient CA feature.
    115     moveAnimation.rotationMode = kCAAnimationRotateAuto;
    116     [_shapeLayer addAnimation:moveAnimation forKey:@"moveAnimation"];
    117     
    118     //创建ball走的路径å
    119     UIBezierPath *path1 = [UIBezierPath bezierPath];
    120     [path1 moveToPoint:CGPointMake(30, 70)];
    121     [path1 addLineToPoint:CGPointMake(270, 70)];
    122     [path1 addLineToPoint:CGPointMake(270, 170)];
    123     [path1 addLineToPoint:CGPointMake(30,170)];
    124     [path1 addLineToPoint:CGPointMake(30, 330)];
    125     [path1 addLineToPoint:CGPointMake(300, 330)];
    126    
    127     CAKeyframeAnimation *moveAnimation1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    128     moveAnimation1.repeatCount = HUGE_VALF;
    129     moveAnimation1.path = path1.CGPath;
    130     moveAnimation1.duration = 5.5f;
    131     moveAnimation.rotationMode = kCAAnimationRotateAuto;
    132 
    133     [_ballLayer addAnimation:moveAnimation1 forKey:@"moveAnimation"];
    134 }
    135 
    136 //暂停动画
    137 -(void)pauseLayer
    138 {
    139     CFTimeInterval pausedTime = [self.view.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    140     self.view.layer .speed = 0.0;
    141     self.view.layer .timeOffset = pausedTime;
    142 }
    143 
    144 //继续动画
    145 -(void)resumeLayer
    146 {
    147     CFTimeInterval pausedTime = [self.view.layer timeOffset];
    148     self.view.layer.speed = 1.0;
    149     self.view.layer.timeOffset = 0.0;
    150     self.view.layer.beginTime = 0.0;
    151     CFTimeInterval timeSincePause = [self.view.layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    152     self.view.layer.beginTime = timeSincePause;
    153 }
    154 
    155 - (void)didReceiveMemoryWarning
    156 {
    157     [super didReceiveMemoryWarning];
    158     // Dispose of any resources that can be recreated.
    159 }
    160 
    161 @end
    View Code

    代码中的注释非常清楚,就不再解释了。只再说一点:moveAnimation.rotationMode = kCAAnimationRotateAuto;这句话保证了pacman的嘴巴总是我们想要的方向。


    这个动画做的很粗糙,ball的行走路径和pacman的嘴巴有时候都不在一条线上,也不是我预期想要的pacman和ball总是隔固定的大小。这两个没有符合预期的效果,也是我在做这个动画时碰到过的问题。

    1、pacman的行走路径,是以pacman的哪个点来看的?2、pacman和ball走的路径不一样长,怎么保证总是隔固定大小?

    第一个问题:经过试验,我发觉是以pacman圆上的最上面的点为基准的,即使翻转,依然是以那个点为基准。

    第二个问题:利用beginTime,设不同的开始时间,还木有尝试。

    好啦,动画系列就告一段落啦!在下个阶段,我将会学习不同格式图片的压缩、处理效率。

  • 相关阅读:
    poj 1067||hdu 1527 取石子游戏(博弈论,Wythoff Game)
    CGAffineTransform属性
    自定义UITabBarController
    UISwitch用法:
    UIButton常见属性和方法
    xcode添加背景音乐/音效
    使用cocoaPods加载框架的具体步骤:
    UILabel
    NSString -- UILabel中字体有多种颜色,字符串自动计算高度/换行
    xcode 修改类名 变量名
  • 原文地址:https://www.cnblogs.com/wyqfighting/p/3209520.html
Copyright © 2011-2022 走看看