博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UIDynamic(物理仿真)
阅读量:4326 次
发布时间:2019-06-06

本文共 5598 字,大约阅读时间需要 18 分钟。

简介

  1. 什么是UIDynamic
    • UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架
    • 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象
    • 如: 重力、弹性碰撞等现象
  2. 物理引擎的价值
    • 广泛用于游戏开发,经典成功案例是“愤怒的小鸟”
    • 让开发人员可以在远离物理学公式的情况下,实现炫酷的物理仿真效果
    • 提高了游戏开发效率,产生更多优秀好玩的物理仿真游戏
  3. 知名的2D物理引擎
    • Box2d
    • Chipmunk

三大概念

  1. 三大概念

    1. 物理仿真元素(Dynamic Item)
      • 谁要进行物理仿真?
    2. 物理仿真行为(Dynamic Behavior) 
      • 执行怎样的物理仿真效果?怎样的动画效果
    3. 物理仿真器(Dynamic Animator) 
      • 让物理仿真元素执行具体的物理仿真行为
  2. 物理仿真元素

    1. 注意
      1. 不是任何对象都能做物理仿真元素
      2. 不是任何对象都能进行物理仿真
        1. 哪些对象才能做物理仿真元素
      3. 任何遵守了UIDynamicItem协议的对象
      4. UIView默认已经遵守了UIDynamicItem协议,因此任何UI控件都能做物理仿真
      5. UICollectionViewLayoutAttributes类默认也遵守UIDynamicItem协议
  3. 物理仿真行为

    1. UIDynamic提供了以下几种物理仿真行为
      UIGravityBehavior:重力行为 UICollisionBehavior:碰撞行为 UISnapBehavior:捕捉行为 UIPushBehavior:推动行为 UIAttachmentBehavior:附着行为 UIDynamicItemBehavior:动力元素行为
    2. 物理仿真行为须知
      1. 上述所有物理仿真行为都继承自UIDynamicBehavior
      2. 所有的UIDynamicBehavior都可以独立进行
      3. 组合使用多种行为时,可以实现一些比较复杂的效果
  4. 物理仿真器

    1. 物理仿真器须知

      • 它可以让物理仿真元素执行物理仿真行为
      • 它是UIDynamicAnimator类型的对象
    2. UIDynamicAnimator的初始化

      • - (instancetype)initWithReferenceView:(UIView )view;
      • view参数:是一个参照视图,表示物理仿真的范围
    3. UIDynamicAnimator的常见方法

      - (void)addBehavior:(UIDynamicBehavior *)behavior;     添加1个物理仿真行为     - (void)removeBehavior:(UIDynamicBehavior *)behavior;     移除1个物理仿真行为     - (void)removeAllBehaviors; 移除之前添加过的所有物理仿真行为
    4. UIDynamicAnimator的常见属性

      @property (nonatomic, readonly) UIView* referenceView;     参照视图     @property (nonatomic, readonly, copy) NSArray* behaviors; 添加到物理仿真器中的所有物理仿真行为 @property (nonatomic, readonly, getter = isRunning) BOOL running; 是否正在进行物理仿真 @property (nonatomic, assign) id 
      delegate; 代理对象(能监听物理仿真器的仿真过程,比如开始和结束)
    5. 使用步骤

      1. 创建一个物理仿真器(顺便设置仿真范围)

      2. 创建相应的物理仿真行为(顺便添加物理仿真元素)

      3. 将物理仿真行为添加到物理仿真器中 -> 开始仿真

       

      Demo

      1. 环境准备
        1. 创建项目
        2. 设置不使用autolayout(这里仅仅是为了简单,物理仿真支持autolayout,在愤怒的小鸟中演示)
        3. 设置屏幕的尺寸为5.5 因为Xcode7 默认使用是iPhone6 s Plus
        4. 拖入一个View,颜色设置蓝色,大小设置为100,100
        5. 连线到控制器中,属性为blueView
      2. 让蓝色View执行仿真重力仿真行为,代码如下:

        - (void) touchesBegan:(NSSet
        *)touches withEvent:(UIEvent *)event { // 创建一个物理仿真器,并指定参照系为控制器的View UIDynamicAnimator *dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; // 创建重力仿真行为并指定仿真元素为蓝色的view UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.blueView]]; // 把仿真行为添加到仿真器中 [dynamicAnimator addBehavior:gravity]; }

        点击控制器的View,没有任何反应,这是因为还要没有执行动画物理仿真器就销毁,所以我们需要对物理仿真器有一个强引用 懒加载物理仿真器

        1. 定义物理仿真器属性

          @property (nonatomic, strong) UIDynamicAnimator *dynamicAnimator;
        2. 懒加载物理仿真器器

          - (UIDynamicAnimator *)dynamicAnimator     {         if (_dynamicAnimator == nil) {             //  创建一个物理仿真器,并指定参照系为控制器的View             _dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view]; } return _dynamicAnimator; }
          1. 修改touchesBegan方法

            - (void) touchesBegan:(NSSet
            *)touches withEvent:(UIEvent *)event{// 创建重力仿真行为并指定仿真元素为蓝色的view UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.blueView]]; // 把仿真行为添加到仿真器中 [self.dynamicAnimator addBehavior:gravity]; }
          2. 运行,点击控制器View,蓝色View向下运动,然后从下面出去了
      3. 如果想让blueView到底部停止还需要添加一个碰撞行为

        - (void) touchesBegan:(NSSet
        *)touches withEvent:(UIEvent *)event { // 创建重力仿真行为并指定仿真元素为blueView UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.blueView]]; // 创建一个碰撞的仿真行为并指定仿真元素为blueView UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.blueView]]; // 设置仿真边界为碰撞边界 collision.translatesReferenceBoundsIntoBoundary = YES; // 添加碰撞行为到仿真器中 [self.dynamicAnimator addBehavior:collision]; // 把仿真行为添加到仿真器中 [self.dynamicAnimator addBehavior:gravity]; }
      4. 在storyboard上添加一个添加一个红色View,在蓝色的View下方,运行程序蓝色的View会从红色的View上方飘过,这是因为此时红色的View并没有添加到仿真器中,如果你希望蓝色的View撞到红色的View那么就需要把红色的View添加到碰撞的仿真行为中 1.红色View的拖线到控制器中,属性名称为redView 2.把红色View添加到碰撞仿真行为中

        UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.blueView,self.redView]];
        1. 运行程序,点击屏幕,红色的View被推下去了;把红色的View放到蓝色View能砸到其角上的一个位置,测试,会有惊喜发现哦!
      5. 添加碰撞边界

        1. 添加直线边界

          - (void) touchesBegan:(NSSet
          *)touches withEvent:(UIEvent *)event { // 创建重力仿真行为并指定仿真元素为blueView UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.blueView]]; // 创建一个碰撞的仿真行为并指定仿真元素为blueView UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:@[self.blueView]]; // 设置仿真边界为碰撞边界 collision.translatesReferenceBoundsIntoBoundary = YES; // 添加直线碰撞边界 [collision addBoundaryWithIdentifier:@"line" fromPoint:CGPointMake(0, self.view.frame.size.height * 0.5) toPoint:CGPointMake(self.view.frame.size.width, self.view.frame.size.height)]; // 添加碰撞行为到仿真器中 [self.dynamicAnimator addBehavior:collision]; // 把仿真行为添加到仿真器中 [self.dynamicAnimator addBehavior:gravity]; }
        2. 添加一个贝塞尔曲线碰撞边界,把添加直线碰撞边界的代码修改如下代码

          //  添加贝塞尔曲线碰撞边界     UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.width)]; [collision addBoundaryWithIdentifier:@"bezier" forPath:bezierPath];
      6. 重力行为的常见属性

        设置重力的角度,默认为M_PI_2(向下),0为右,M_PI向左 //    gravity.angle = 0;   设置重力的大小,默认是1 //    gravity.magnitude = 2; // 设置重力向量,(0,0) -> (1,1) 之间的连线,大小为:根号2 gravity.gravityDirection = CGVectorMake(1, 1);
      7. 捕获行为

        //  相同类型仿真行为只能添加到仿真器一次,所以在添加仿真行为之前,移除之前添加仿真行为     [self.dynamicAnimator removeAllBehaviors]; //  获取描述用户点击的对象     UITouch *touch = [touches anyObject]; // 获取用户点击的位置 CGPoint loc = [touch locationInView:self.view]; // 创建一个捕获行为 UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.blueView snapToPoint:loc]; // 设置减震效果,取值范围为 0.0 to 1.0. 0表示最小减震效果,也就是振幅最大 snap.damping = 0; // 把捕获行为添加到仿真器中 [self.dynamicAnimator addBehavior:snap];
      8. Demo2  愤怒的小鸟
          1. 视图

转载于:https://www.cnblogs.com/YRFios/p/4963221.html

你可能感兴趣的文章
我的第一篇CBBLOGS博客
查看>>
【MyBean调试笔记】接口的使用和清理
查看>>
07 js自定义函数
查看>>
jQueru中数据交换格式XML和JSON对比
查看>>
form表单序列化后的数据转json对象
查看>>
[PYTHON]一个简单的单元測试框架
查看>>
iOS开发网络篇—XML数据的解析
查看>>
[BZOJ4303]数列
查看>>
一般处理程序在VS2012中打开问题
查看>>
C语言中的++和--
查看>>
thinkphp3.2.3入口文件详解
查看>>
POJ 1141 Brackets Sequence
查看>>
Ubuntu 18.04 root 使用ssh密钥远程登陆
查看>>
Servlet和JSP的异同。
查看>>
虚拟机centOs Linux与Windows之间的文件传输
查看>>
ethereum(以太坊)(二)--合约中属性和行为的访问权限
查看>>
IOS内存管理
查看>>
middle
查看>>
[Bzoj1009][HNOI2008]GT考试(动态规划)
查看>>
Blob(二进制)、byte[]、long、date之间的类型转换
查看>>