iOS开发——高级篇——UIDynamic 物理引擎
一、UIDynamic
1、简介
什么是UIDynamic
UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架
可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象
重力、弹性碰撞等现象
物理引擎的价值
广泛用于游戏开发,经典成功案例是“愤怒的小鸟”
让开发人员可以在远离物理学公式的情况下,实现炫酷的物理仿真效果
提高了游戏开发效率,产生更多优秀好玩的物理仿真游戏
知名的2D物理引擎
Box2d
Chipmunk
2、使用步骤
要想使用UIDynamic来实现物理仿真效果,大致的步骤如下
创建一个物理仿真器(顺便设置仿真范围)
创建相应的物理仿真行为(顺便添加物理仿真元素)
将物理仿真行为添加到物理仿真器中 开始仿真
二、三大概念
物理仿真元素(Dynamic Item)
谁要进行物理仿真?
物理仿真行为(Dynamic Behavior)
执行怎样的物理仿真效果?怎样的动画效果?
物理仿真器(Dynamic Animator)
让物理仿真元素执行具体的物理仿真行为
1、物理仿真元素
注意
不是任何对象都能做物理仿真元素
不是任何对象都能进行物理仿真
哪些对象才能做物理仿真元素
任何遵守了UIDynamicItem协议的对象
UIView默认已经遵守了UIDynamicItem协议,因此任何UI控件都能做物理仿真
UICollectionViewLayoutAttributes类默认也遵守UIDynamicItem协议
2、物理仿真行为
UIDynamic提供了以下几种物理仿真行为
UIGravityBehavior:重力行为
UICollisionBehavior:碰撞行为
UISnapBehavior:捕捉行为
UIPushBehavior:推动行为
UIAttachmentBehavior:附着行为
UIDynamicItemBehavior:动力元素行为
物理仿真行为须知
上述所有物理仿真行为都继承自UIDynamicBehavior
所有的UIDynamicBehavior都可以独立进行
组合使用多种行为时,可以实现一些比较复杂的效果
3、物理仿真器
物理仿真器须知
它可以让物理仿真元素执行物理仿真行为
它是UIDynamicAnimator类型的对象
1)UIDynamicAnimator的初始化
- (instancetype)initWithReferenceView:(UIView *)view;
view参数:是一个参照视图,表示物理仿真的范围
2)UIDynamicAnimator的常见方法
- (void)addBehavior:(UIDynamicBehavior *)behavior;
添加1个物理仿真行为
- (void)removeBehavior:(UIDynamicBehavior *)behavior;
移除1个物理仿真行为
- (void)removeAllBehaviors;
移除之前添加过的所有物理仿真行为
3)UIDynamicAnimator的常见属性
@property (nonatomic, readonly) UIView* referenceView;
参照视图
@property (nonatomic, readonly, copy) NSArray* behaviors;
添加到物理仿真器中的所有物理仿真行为
@property (nonatomic, readonly, getter = isRunning) BOOL running;
是否正在进行物理仿真
@property (nonatomic, assign) id <UIDynamicAnimatorDelegate> delegate;
代理对象(能监听物理仿真器的仿真过程,比如开始和结束)
三、重力行为(UIGravityBehavior)
1、简介
给定重力方向、加速度,让物体朝着重力方向掉落
UIGravityBehavior的初始化
- (instancetype)initWithItems:(NSArray *)items;
item参数 :里面存放着物理仿真元素
UIGravityBehavior常见方法
- (void)addItem:(id <UIDynamicItem>)item;
添加1个物理仿真元素
- (void)removeItem:(id <UIDynamicItem>)item;
移除1个物理仿真元素
2、UIGravityBehavior常见属性
@property (nonatomic, readonly, copy) NSArray* items;
添加到重力行为中的所有物理仿真元素
@property (readwrite, nonatomic) CGVector gravityDirection;
重力方向(是一个二维向量)
@property (readwrite, nonatomic) CGFloat angle;
重力方向(是一个角度,以x轴正方向为0°,顺时针正数,逆时针负数)
@property (readwrite, nonatomic) CGFloat magnitude;
量级(用来控制加速度,1.0代表加速度是1000 points /second²)
3、实战演练
- /** 物理仿真器 */
- @property (nonatomic, strong) UIDynamicAnimator *animator;
- @property (weak, nonatomic) IBOutlet UIView *blueView;
- - (UIDynamicAnimator *)animator
- {
- if (!_animator) {
- // 创建物理仿真器(ReferenceView, 参照视图, 其实就是设置仿真范围)
- _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
- }
- return _animator;
- }
- // 1.创建物理仿真行为 - 重力行为
- UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
- [gravity addItem:self.blueView];
- // 重力方向
- // gravity.gravityDirection = CGVectorMake(100, 100);
- // 重力加速度()
- gravity.magnitude = ;
- // 100 point/s²
- // 移动的距离 = 1/2 * magnitude * 时间²
- // 2.添加 物理仿真行为 到 物理仿真器 中, 开始物理仿真
- [self.animator addBehavior:gravity];
四、碰撞行为(UICollisionBehavior)
1、简介
可以让物体之间实现碰撞效果
可以通过添加边界(boundary),让物理碰撞局限在某个空间中
UICollisionBehavior边界相关的方法
- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath*)bezierPath;
- (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2;
- (UIBezierPath*)boundaryWithIdentifier:(id <NSCopying>)identifier;
- (void)removeBoundaryWithIdentifier:(id <NSCopying>)identifier;
@property (nonatomic, readonly, copy) NSArray* boundaryIdentifiers;
- (void)removeAllBoundaries;
2、UICollisionBehavior常见用法
@property (nonatomic, readwrite) BOOL translatesReferenceBoundsIntoBoundary;
是否以参照视图的bounds为边界
- (void)setTranslatesReferenceBoundsIntoBoundaryWithInsets:(UIEdgeInsets)insets;
设置参照视图的bounds为边界,并且设置内边距
@property (nonatomic, readwrite) UICollisionBehaviorMode collisionMode;
碰撞模式(分为3种,元素碰撞、边界碰撞、全体碰撞)
@property (nonatomic, assign, readwrite) id <UICollisionBehaviorDelegate> collisionDelegate;
代理对象(可以监听元素的碰撞过程)
3、碰撞实战演练
- @property (weak, nonatomic) IBOutlet UISegmentedControl *segmentControl;
- /** 物理仿真器 */
- @property (nonatomic, strong) UIDynamicAnimator *animator;
- @property (weak, nonatomic) IBOutlet UIView *blueView;
- - (UIDynamicAnimator *)animator
- {
- if (!_animator) {
- // 创建物理仿真器(ReferenceView, 参照视图, 其实就是设置仿真范围)
- _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
- }
- return _animator;
- }
- // 1.创建 碰撞行为
- UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
- // 让参照视图的bounds变为碰撞检测的边框
- collision.translatesReferenceBoundsIntoBoundary = YES;
- [collision addItem:self.blueView];
- [collision addItem:self.segmentControl];
- // 2.创建物理仿真行为 - 重力行为
- UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
- gravity.magnitude = ;
- [gravity addItem:self.blueView];
- // 3.添加行为
- [self.animator addBehavior:collision];
- [self.animator addBehavior:gravity];
4、碰撞演练——添加边界
- // 1.创建 碰撞行为
- UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
- [collision addItem:self.blueView];
- // [collision addItem:self.segmentControl];
- // 添加边界
- // CGFloat startX = 0;
- // CGFloat startY = self.view.frame.size.height * 0.5;
- // CGFloat endX = self.view.frame.size.width;
- // CGFloat endY = self.view.frame.size.height;
- // [collision addBoundaryWithIdentifier:@"line1" fromPoint:CGPointMake(startX, startY) toPoint:CGPointMake(endX, endY)];
- // [collision addBoundaryWithIdentifier:@"line2" fromPoint:CGPointMake(endX, 0) toPoint:CGPointMake(endX, endY)];
- CGFloat width = self.view.frame.size.width;
- UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(, , width, width)];
- [collision addBoundaryWithIdentifier:@"circle" forPath:path];
- // 2.创建物理仿真行为 - 重力行为
- UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
- gravity.magnitude = ;
- [gravity addItem:self.blueView];
- // 3.添加行为
- [self.animator addBehavior:collision];
- [self.animator addBehavior:gravity];
斜线边界
圆弧为边界
五、捕捉行为(UISnapBehavior)
1、简介
可以让物体迅速冲到某个位置(捕捉位置),捕捉到位置之后会带有一定的震动
UISnapBehavior的初始化
- (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point;
UISnapBehavior常见属性
@property (nonatomic, assign) CGFloat damping;
用于减幅、减震(取值范围是0.0 ~ 1.0,值越大,震动幅度越小)
UISnapBehavior使用注意
如果要进行连续的捕捉行为,需要先把前面的捕捉行为从物理仿真器中移除
2、捕捉实战演练
- // 获得触摸点
- UITouch *touch = [touches anyObject];
- CGPoint point = [touch locationInView:self.view];
- // 创建吸附\捕捉行为
- UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.blueView snapToPoint:point];
- // 防抖系数(值越小, 越抖)
- snap.damping = 1.0;
- // 移除所有行为
- [self.animator removeAllBehaviors];
- // 添加行为
- [self.animator addBehavior:snap];
其他的仿真行为就不一一演示了
iOS开发——高级篇——UIDynamic 物理引擎的更多相关文章
- iOS开发拓展篇—UIDynamic(简单介绍)
iOS开发拓展篇—UIDynamic(简单介绍) 一.简单介绍 1.什么是UIDynamic UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟 ...
- iOS开发拓展篇—UIDynamic(重力行为+碰撞检测)
iOS开发拓展篇—UIDynamic(重力行为+碰撞检测) 一.重力行为 说明:给定重力方向.加速度,让物体朝着重力方向掉落 1.方法 (1)UIGravityBehavior的初始化 - (inst ...
- iOS开发拓展篇—UIDynamic(捕捉行为)
iOS开发拓展篇—UIDynamic(捕捉行为) 一.简介 可以让物体迅速冲到某个位置(捕捉位置),捕捉到位置之后会带有一定的震动 UISnapBehavior的初始化 - (instancetype ...
- 李洪强iOS开发拓展篇—UIDynamic(重力行为+碰撞检测)
iOS开发拓展篇—UIDynamic(重力行为+碰撞检测) 一.重力行为 说明:给定重力方向.加速度,让物体朝着重力方向掉落 1.方法 (1)UIGravityBehavior的初始化 - (inst ...
- iOS开发——高级篇——iOS开发之网络安全密码学
一.非对称加密 - RSA : + 公钥加密,私钥解密: + 私钥加密,公钥解密: + 只能通过因式分解来破解 二.对称加密 - DES - 3DES - AES (高级密码标准,美国国家安全局使用, ...
- iOS开发——高级篇——线程同步、线程依赖、线程组
前言 对于iOS开发中的网络请求模块,AFNet的使用应该是最熟悉不过了,但你是否把握了网络请求正确的完成时机?本篇文章涉及线程同步.线程依赖.线程组等专用名词的含义,若对上述名词认识模糊,可先进行查 ...
- iOS开发——高级篇——iPad开发、iPad开发中的modal
一.iPad简介 1.什么是iPad一款苹果公司于2010年发布的平板电脑定位介于苹果的智能手机iPhone和笔记本电脑产品之间跟iPhone一样,搭载的是iOS操作系统 2.iPhone和iPadi ...
- iOS开发——高级篇——地理定位 CoreLocation
一.CoreLocation 在移动互联网时代,移动app能解决用户的很多生活琐事,比如周边:找餐馆.找KTV.找电影院等等导航:根据用户设定的起点和终点,进行路线规划,并指引用户如何到达 在上述应用 ...
- iOS开发——高级篇——地图 MapKit
一.简介 1.在移动互联网时代,移动app能解决用户的很多生活琐事,比如周边:找餐馆.找KTV.找电影院等等导航:根据用户设定的起点和终点,进行路线规划,并指引用户如何到达 在上述应用中,都用到了定位 ...
随机推荐
- vmware下linux系统的安装过程
虚拟机VMware下CentOS6.6安装教程图文详解 [日期:2016-05-24] 来源:Linux社区 作者:Sungeek [字体:大 中 小] 分享下,虚拟机VMware下CentOS ...
- Objective-C复合
正所谓复合,便是定义的这个类中的成员是另外类的实例方法. 也就是把其他对象作为自身的题部分,以提升自身的功能, 就相当于C语言中的函数嵌套.下面是一段代码(多个文件放在一块了): /***Comput ...
- matlab和C/C++混合编程--Mex
最近的项目需要matlab和C的混合编程,经过一番努力终于完成了项目要解决的问题.现在就将Mex的一些经验总结一下,当然只是刚刚开始,以后随着学习的深入继续添加.首先讲讲写Mex的一些常规规定,然后我 ...
- Excel_replace
有时候我们需要对单元格中的数据需要一些精确的处理,比如将部分以70开的工号升为706,这时简单的查找替换就不能满足我的需求,因为这样会替换掉工号中末尾或者中间位的70,造成工号的错误. 如何实现这种精 ...
- JavaWeb学习笔记——JSTL核心标签库
- JavaScript排序算法——堆排序
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Index/Common目录下文件
1.在Common目录下创建Common.php(系统会自动加载Common.php) 代码: function say(){ echo '; } 在IndecAction.php输出 public ...
- php的if语句单行与多行
//正确: //错误写法 $b = //if前面不能带 等号
- C语言生成服从均匀分布, 瑞利分布, 莱斯分布, 高斯分布的随机数
用c语言 产生服从均匀分布, 瑞利分布,莱斯分布,高斯分布的随机数 一,各个分布对应的基本含义: 1. 均匀分布或称规则分布,顾名思义,均匀的,不偏差的.植物种群的个体是等距分布,或个体之间保持一 ...
- Linux 挂载 NFS
NFS(网络文件系统),这是在 Linux 系统上常用的文件共享方式.也可以做为作为一个远程存储使用,比如:我有个网站,用户可以上传文件,但文件慢慢会越来越多,这个时候我们只能把存放上传文件的目录挂在 ...