常见行为:仿真&重力&碰撞&捕捉

时间:2022-09-06 11:35:11

一、UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架。可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象,重力、弹性碰撞等,游戏开发中很常见,例如愤怒的小鸟。

二、UIDynamic实现物理仿真效果步骤:

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

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

  (3)将物理仿真行为添加到物理仿真器中 开始仿真

     //物理仿真器:让物理仿真元素执行具体的物理仿真行为

     //物理仿真行为:执行怎样的物理仿真效果?怎样的动画效果?

     //物理仿真元素(Dynamic Item):谁要进行物理仿真

三、属性,方法等

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;代理对象(能监听物理仿真器的仿真过程,比如开始和结束)

 (1)能做物理仿真元素的对象:

   1.任何遵守了UIDynamicItem协议的对象

   2.UIView默认已经遵守了UIDynamicItem协议,因此任何UI控件都能做物理仿真

   3.UICollectionViewLayoutAttributes类默认也遵守UIDynamicItem协议

 (2)UIDynamic提供了以下几种物理仿真行为,所有物理仿真行为都继承自UIDynamicBehavior。都可以独立进行

   1.UIGravityBehavior:重力行为

   2.UICollisionBehavior:碰撞行为

   3.UISnapBehavior:捕捉行为    

     4.UIPushBehavior:推动行为

   5.UIAttachmentBehavior:附着行为

   6.UIDynamicItemBehavior:动力元素行为

(4)UIDynamicAnimator的初始化:- (instancetype)initWithReferenceView:(UIView *)view;

    view参数:是一个参照视图,表示物理仿真的范围

 (5)添加1个物理仿真行为:- (void)addBehavior:(UIDynamicBehavior *)behavior;

 (6)移除1个物理仿真行为:- (void)removeBehavior:(UIDynamicBehavior *)behavior;

 (7)移除之前添加过的所有物理仿真行为:- (void)removeAllBehaviors;

注:由于以下行为与上用法相似,就不一一介绍

四、UIGravityBehavior重力行为:

UIGravityBehavior常见属性
@property (nonatomic, readonly, copy) NSArray* items;添加到重力行为中的所有物理仿真元素 @property (readwrite, nonatomic) CGVector gravityDirection;重力方向(是一个二维向量) @property (readwrite, nonatomic) CGFloat angle;重力方向(是一个角度,以x轴正方向为0°,顺时针正数,逆时针负数) @property (readwrite, nonatomic) CGFloat magnitude;量级(用来控制加速度,.0代表加速度是1000 points /second²)
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;

五、碰撞行为:

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;代理对象(可以监听元素的碰撞过程

六、捕捉行为:

简介
可以让物体迅速冲到某个位置(捕捉位置),捕捉到位置之后会带有一定的震动 UISnapBehavior的初始化
- (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point; UISnapBehavior常见属性
@property (nonatomic, assign) CGFloat damping;用于减幅、减震(取值范围是0. ~ 1.0,值越大,震动幅度越小) UISnapBehavior使用注意如果要进行连续的捕捉行为,需要先把前面的捕捉行为从物理仿真器中移除

七、Demo:

@interface ViewController ()

// 红色的View
@property (weak, nonatomic) IBOutlet UIView *redView;
// 蓝色的View
@property (weak, nonatomic) IBOutlet UIView *blueView; @property(nonatomic,strong)UIDynamicAnimator *animator; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
} - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// -1.将之前的捕捉行为移除
[self.animator removeAllBehaviors]; // 0.取出用户点击的点
CGPoint point = [[touches anyObject] locationInView:self.view]; // 1.创建捕捉行为
UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.redView snapToPoint:point]; // 1.1.设置捕捉行为的阻力
snap.damping = 0.5; // 2.将仿真行为添加到仿真器中(在同一个仿真器当中,只能存在捕捉行为)
[self.animator addBehavior:snap];
} /**
* 测试重力仿真其他属性
*/
- (void)testGravity
{
// 1.创建仿真行为
NSArray *items = @[self.redView, self.blueView];
// 1.1.创建重力仿真行为,并且指定仿真元素
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]]; // 1.1.1.设置重力角度(默认是M_PI_2)
// gravity.angle = M_PI_2; // 1.1.2.设置重力的大小(默认是1.0)
// gravity.magnitude = 10.0; // 1.1.3.设置向量
gravity.gravityDirection = CGVectorMake(3.0, 1.0); // 1.2.创建碰撞行为,并且指定仿真元素
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:items]; // 1.2.1.将仿真器的bounds作为碰撞的边界
collision.translatesReferenceBoundsIntoBoundary = YES; // 2.将仿真行为添加到仿真器中,开始仿真
[self.animator addBehavior:gravity];
[self.animator addBehavior:collision];
} /**
* 测试碰撞仿真其他属性
*/
- (void)testCollision
{
// 1.创建仿真行为
NSArray *items = @[self.redView];
// 1.1.创建重力仿真行为,并且指定仿真元素
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:items]; // 1.2.创建碰撞行为,并且指定仿真元素
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:items]; // 1.2.1.将仿真器的bounds作为碰撞的边界
collision.translatesReferenceBoundsIntoBoundary = YES; // 1.2.2.添加一个边界(线段)
CGPoint startPoint = CGPointMake(, );
CGPoint endPoint = CGPointMake(self.view.frame.size.width, );
[collision addBoundaryWithIdentifier:@"line" fromPoint:startPoint toPoint:endPoint];
// [collision removeBoundaryWithIdentifier:@"line"]; // 1.2.3.添加一个边界(贝塞尔曲线)
// UIBezierPath *bezierPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 320, 320)];
// [collision addBoundaryWithIdentifier:@"bezierPath" forPath:bezierPath]; // 2.将仿真行为添加到仿真器中,开始仿真
[self.animator addBehavior:gravity];
[self.animator addBehavior:collision];
} /**
* 重力仿真和碰撞仿真
*/
- (void)gravityAndCollision
{
// 1.创建仿真行为
NSArray *items = @[self.redView];
// 1.1.创建重力仿真行为,并且指定仿真元素
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:items]; // 1.2.创建碰撞行为,并且指定仿真元素
UICollisionBehavior *collision = [[UICollisionBehavior alloc] initWithItems:items]; // 1.2.1.将仿真器的bounds作为碰撞的边界
collision.translatesReferenceBoundsIntoBoundary = YES; // 2.将仿真行为添加到仿真器中,开始仿真
[self.animator addBehavior:gravity];
[self.animator addBehavior:collision];
} /**
* 简单重力仿真
*/
- (void)gravity
{
/*
// 1.创建仿真器,并且指定仿真范围
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
*/
// 2.创建重力仿真行为,并且指定仿真元素
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[self.redView]]; // 3.将仿真行为添加到仿真器中,开始仿真
[self.animator addBehavior:gravity];
} #pragma mark - 懒加载
- (UIDynamicAnimator *)animator
{
if (_animator == nil) {
// 创建仿真器,并且指定仿真范围
_animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
}
return _animator;
}

常见行为:仿真&重力&碰撞&捕捉的更多相关文章

  1. UIDynamic-吸附-重力-碰撞-物理仿真动画

    现实生活中: 运动场==物理仿真器 跑步==物理仿真行为 人==仿真元素 创建步骤: 1.创建物理仿真器,并且指定仿真范围 2.创建物理仿真行为,并且指定仿真元素 3.将物理仿真行为添加到仿真器中 D ...

  2. UIDynamic&lpar;物理仿真&rpar;

    简介 什么是UIDynamic UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架 可以认为是一种物理引擎,能模拟和仿真现实生活中的物理现象 如: 重力.弹性碰撞等现象 物理引 ...

  3. Javascript实现重力弹跳拖拽运动效果

    声明: By:GenialX 个人主页:胡旭博客 - www.ihuxu.com QQ:2252065614 演示地址: http://www.ihuxu.com/project/gcdmove/ 调 ...

  4. cocos2dx-3&period;x物理引擎Box2D介绍

    理引擎 Cocos2d-x引擎内置了两种物理引擎,它们分别是Box2D和Chipmunk,都是非常优秀的2D物理引擎,而且x引擎将它们都内置在SDK中.Box2D使用较为广泛,在这里选择Box2D来进 ...

  5. 最全的iOS物理引擎demo

    概述 最全的iOS物理引擎demo,实现重力.碰撞.推力.摆动.碰撞+重力.重力弹跳.仿摩拜单车贴纸效果.防iMessage滚动效果.防百度外卖首页重力感应等效果! 详细 代码下载:http://ww ...

  6. V-rep学习笔记:机器人模型创建3—搭建动力学模型

    接着之前写的V-rep学习笔记:机器人模型创建2—添加关节继续机器人创建流程.如果已经添加好关节,那么就可以进入流程的最后一步:搭建层次结构模型和模型定义(build the model hierar ...

  7. UIDynamicBehavior的简单使用:接球小游戏

    一.概念扩充: 1.在开发中,我们可以使用UIKit中提供的仿真行为,实现与现实生活中类似的物理仿真动画,UIKit动力学最大的特点是将现实世界动力驱动的动画引入了UIKit,比如重力,铰链连接,碰撞 ...

  8. 【Bochs 官方手册翻译】 第一章 Bochs介绍

    Bochs 是一个可以完全模拟 Intel x86 计算机的虚拟机系统.它包含了 Intel x86 CPU 仿真.常见设备仿真.以及定制 BIOS.Bochs 可以虚拟多种不同类型的 x86 CPU ...

  9. Java处理InterruptedException异常小结

    对于InterruptedException,一种常见的处理方式是捕捉它,然后什么也不做(或者记录下它,不过这也好不到哪去).不幸的是,这种方法忽略了这样一个事实:这期间可能发生中断,而中断可能导致应 ...

随机推荐

  1. android自定义控件---添加表情

    android自定义控件---添加表情 一.定义layout文件,图片不提供了 <?xml version="1.0" encoding="utf-8"? ...

  2. PS CC 2014 把一个图层输出为文件的方法

    近期在设计一个Qt控件,须要获得一个圆饼的图片,在用PS绘制后发现保存的时候总是会带着背景,用PNG格式保存之后背景依旧存在.仅仅是变成了透明的.刚才在Google上查到了仅仅保存单一图层而全然没有背 ...

  3. margin&colon;0 auto

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  4. EXchange导出通讯录提取url纯文本

    用outlook链接邮箱 文件-打开和导出--导出到文件--逗号分隔值--选择联系人--保存 保存为一个后缀为csv的文件 打开该文件  选中该列 用替换功能删掉()符号 用vba脚本删掉汉字 Sub ...

  5. Net包管理NuGet&lpar;3&rpar;搭建私服及引用私服的包

    1,打开vs创建项目(ASP.NET WEB空项目)假设命名为MyNuGet 空项目解决方案如图 2,右键引用>管理NuGet程序包>切到浏览搜索NuGet.Server然后安装(3.1. ...

  6. 构建eureka-server异常ClassNotFoundException&colon; org&period;springframework&period;boot&period;context&period;embedded&period;FilterRegistrationBean

    Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.embedded.FilterRegistr ...

  7. windows与linux换行符

    我一次linux上写的脚本,利用vim进行脚本编写,然后下载下来在nodepad++上面打开,在nodepad上面新建了一个文件将原来文件内容复制过去,保存后下载复制文件在linux上面进行运行,发现 ...

  8. RAID在数据库存储上的应用

    随着单块磁盘在数据安全.性能.容量上呈现出的局限,磁盘阵列(Redundant Arrays of Inexpensive/Independent Disks,RAID)出现了,RAID把多块独立的磁 ...

  9. 梯度下降算法(Gradient Descent&rpar;

    近期在搞论文,须要用梯度下降算法求解,所以又一次整理分享在这里. 主要包含梯度介绍.公式求导.学习速率选择.代码实现. 梯度下降的性质: 1.求得的解和选取的初始点有关 2.能够保证找到局部最优解,由 ...

  10. C&sol;C&plus;&plus; -- Gui编程 -- Qt库的使用 -- 使用小写qDebug调试程序

    qDebug作为printf不需要头文件 qDebug()作为cout要使用头文件<QDebug> -----debug.cpp----- -----debug.cpp----- #inc ...