• 热门专题

iOS中的物理引擎

作者:董铂然  发布日期:2015-03-23 21:19:22
Tag标签:物理  引擎  
  • 目前知名的2D物理引擎有 Box2d,和Chipmunk,这些是跨平台的。但苹果本身也封装了一个物理引擎, UIDynamic是从iOS 7开始引入的一种新技术,隶属于UIKit框架。这可以让开发人员可以在远离物理学公式的情况下,实现炫酷的物理仿真效果。在游戏开发中会经常用到。本文主要是玩一些较浅的功能,就不说那些游戏中框架中的高级用法了。毕竟我也入门这个没多久啊只会些简单点的,可以用在普通应用界面中偶尔炫酷一下足矣。

    如果你不是在董铂然博客园看到本文,请点击查看原文

    主要的步骤就三步

    1.创建一个物理仿真器。设置仿真范围

    2.创建相应的物理仿真行为,添加物理仿真元素

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

    懒加载方法创建 物理仿真器

    - (UIDynamicAnimator *)animator
    {
        if (!_animator) {
            // 创建一个物理仿真器
            _animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
        }
        return _animator;
    }
    

    模拟重力行为  UIGravityBehavior

    重力行为有一个属性是重力加速度,设置越大速度增长越快。默认是1

    gravity.magnitude = 100;
    

    添加元素,告诉仿真器哪些元素可以重力行为

        [gravity addItem:self.sxView];
    

    简单演示:

        // 创建重力行为
        UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
        // magnitude越大,速度增长越快
        gravity.magnitude = 100;
        [gravity addItem:self.sxView];
    
        // 添加到仿真器中开始仿真
        [self.animator addBehavior:gravity];
    

     

     可以看到只是从图中掉下,(注意这不是匀速动画,他是模拟物体以重力加速度落下的)

    模拟碰撞行为  UICollisionBehavior

    碰撞行为需要先添加元素,告诉物理仿真器哪些元素允许碰撞。如

    [collision addItem:self.sxView];
    

    其次是设置碰撞的边界,有个参数默认是以屏幕为边界。

    collision.translatesReferenceBoundsIntoBoundary = YES;
    

    把碰撞行为和重力行为结合演示

        // 1.创建重力行为
        UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
        // magnitude越大,速度增长越快
        gravity.magnitude = 2;
        [gravity addItem:self.sxView];
        
        // 2.创建碰撞行为
        UICollisionBehavior *collision = [[UICollisionBehavior alloc] init];
        [collision addItem:self.sxView];
        [collision addItem:self.bigBlock];
        [collision addItem:self.smallBlock];
        // 设置碰撞的边界
        collision.translatesReferenceBoundsIntoBoundary = YES;
        
        // 3.开始仿真
        [self.animator addBehavior:gravity];
        [self.animator addBehavior:collision];
    

     

    (图中之所以那两个控件会往上飘,是因为他们虽然都添加了碰撞行为,但是没有添加重力行为)

    如果觉得屏幕作为边界不好,可以自己设置一条边可以是普通的边

    [collision addBoundaryWithIdentifier:@'line2' fromPoint:
    CGPointMake(self.view.frame.size.width, 0) toPoint:
    CGPointMake(self.view.frame.size.width, 400)];
    

    也可以是个贝塞尔路径。(注意这里的路径是不会显示的,想要能看见得在view中画一个和你设置的边界一样的图形)

        UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:
        CGRectMake(0,150, self.view.frame.size.width, self.view.frame.size.width)];
        [collision addBoundaryWithIdentifier:@'circle' forPath:path];
    

     效果如图

     模拟捕捉行为 UISnapBehavior

    捕捉行为需要在创建时就给与一个点。

    UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.sxView snapToPoint:point];
    

     捕捉行为有一个防震系数属性,设置的越大,振幅就越小

    snap.damping = 1;
    

     因为默认只能移动一次,如果想多次移动,就在模拟仿真前清空之前的仿真器

    [self.animator removeAllBehaviors];
    

    结合演示,鼠标点哪,移动到哪

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        // 1.获得手指对应的触摸对象
        UITouch *touch = [touches anyObject];
        
        // 2.获得触摸点
        CGPoint point = [touch locationInView:self.view];
        
        // 3.创建捕捉行为
        UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:self.sxView snapToPoint:point];
        // 防震系数,damping越大,振幅越小
        snap.damping = 1;
        
        // 4.清空之前的并再次开始
        [self.animator removeAllBehaviors];
        [self.animator addBehavior:snap];
    }
    

     

    还有一些在此就不一一演示了 头文件都很简单能看懂的。

    UIGravityBehavior:重力行为 UICollisionBehavior:碰撞行为 UISnapBehavior:捕捉行为 UIPushBehavior:推动行为 UIAttachmentBehavior:附着行为 UIDynamicItemBehavior:动力元素行为 所有物理仿真行为都继承自UIDynamicBehavior 所有的UIDynamicBehavior都可以独立进行 组合使用多种行为时,可以实现一些比较复杂的效果     如果你不是在董铂然博客园看到本文,请点击查看原文

    比如重力还可以设置重力方向,碰撞还能监听整个碰撞过程,附着动画类似于iOS8的iMessage短信聊天界面(上下拖动)等等,有兴趣的可以自行研究,偶尔在应用中做个“撒红包”“砸金蛋” 等动画啥的可以用这些方法。

    欢迎关注。

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规