iOS通过内置重力和陀螺仪实现物理仿真碰撞试验

最近公司用cocos2d开发了一款类似于打砖块的游戏,后来想着用iOS是否能实现相同的原理,毕竟苹果爸爸还是很强大的。

仿真碰撞效果图.gif

1.0 陀螺仪在iOS中的使用

iPhone、iPad、iWatch都有内置的陀螺仪,也都可以让开发者进行调用。同样,用一张图展现一下:

iOS通过内置重力和陀螺仪实现物理仿真碰撞试验_第1张图片

在手机上,仅用加速度计没办法测量或重构出完整的3D动作,测不到转动的动作的,加速计只能检测轴向的线性动作。但陀螺仪则可以对转动、偏转的动作做很好的测量,这样就可以精确分析判断出使用者的实际动作。而后根据动作,可以对手机做相应的操作。

2.仿真物理碰撞试验

仿真物理碰撞试验需要我们实现iOS自带的三种行为,(UIDynamicItemBehavior)物理仿真行为、(UIGravityBehavior)重力行为、(UICollisionBehavior)碰撞行为,下面我们来记录一下各种行为的知识点。

 2.1 iOS UIKit动力学    动力学配置(UIDynamicItemBehavior)

 UIDynamicItemBehavior它的作用像是一个扩展,可以为一个动态元素设置更多较为具体的动力学属性。

属性

2.1.2 弹性系数

用于碰撞行为的动态元素的弹性量。默认值为0,数值越大,碰撞行为越激烈。

@property(readwrite,nonatomic)CGFloatelasticity;

2.1.2 摩擦系数

用于两个发生摩擦的动态元素。默认值为0,当值为1.0时为强烈摩擦。

@property(readwrite,nonatomic)CGFloatfriction;

2.1.3 相对质量密度

用于动态元素相对密度。其连同动态元素大小,决定动态元素的有效质量。其参与的动力学行为包括摩擦、碰撞、推动等...

@property(readwrite,nonatomic)CGFloatdensity;

 2.2  iOS 重力行为(UIGravityBehavior)

2.2.1 重力矢量方向与坐标轴x的夹角,例如垂直向下:π/2;

@property (readwrite, nonatomic) CGFloat angle;

2.2.2重力加速度的倍数

@property (readwrite, nonatomic) CGFloat magnitude;

 2.3  iOS 碰撞行为(UICollisionBehavior)

 2.3.1 边界碰撞

表示是否以当前坐标系边界作为检测碰撞的边界。此时_dynamicItem1View运动到self.view的边界时就会发生碰撞。

@property(nonatomic,readwrite)BOOLtranslatesReferenceBoundsIntoBoundary;

2.3.2碰撞类型

UICollisionBehaviorModeItems// 边界碰撞

UICollisionBehaviorModeBoundaries// 边界碰撞

// 碰撞所有UICollisionBehaviorModeEverything// 碰撞所有

@property(nonatomic,readwrite)UICollisionBehaviorModecollisionMode;

综合以上三种物理行为,我们就能实现仿真物理碰撞试验,一下为部分重要代码:


//创建现实动画 设定动画模拟区间

    _dynamicAnimator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];


//创建物理仿真行为

    _dynamicItemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[]];

    _dynamicItemBehavior.elasticity = 0.5;

    _dynamicItemBehavior.friction = 0;

    _dynamicItemBehavior.density = 1;

//重力行为

    _gravityBehavior = [[UIGravityBehavior alloc] initWithItems:@[]];

//初始化全局管理对象

    CMMotionManager *manager = [[CMMotionManager alloc] init];

    self.motionManager= manager;

    //判断传感器是否可用

    if ([self.motionManager isDeviceMotionAvailable]) {

        ///设备 运动 更新 间隔

        manager.deviceMotionUpdateInterval = 0.01;

        ///启动设备运动更新队列

 [self.motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue]

                                                withHandler:^(CMDeviceMotion*_Nullablemotion,NSError*_Nullableerror) {

                                                    doublegravityX = motion.gravity.x;

                                                    doublegravityY = motion.gravity.y;

                                                    //计算手机倾斜角度

                                                    doublexy =atan2(gravityX, gravityY);

                                                    // 计算相对于y轴的重力方向

                                                    _gravityBehavior.angle= xy-M_PI_2;

                                                }];

    }


 //碰撞行为

    _collisionBehavior = [[UICollisionBehavior alloc]initWithItems:@[]];

    _collisionBehavior.translatesReferenceBoundsIntoBoundary = YES;

  //将行为添加到物理仿动画中

    [_dynamicAnimator addBehavior:_dynamicItemBehavior];

    [_dynamicAnimator addBehavior:_gravityBehavior];

    [_dynamicAnimator addBehavior:_collisionBehavior];

2.4 通过绘制贝塞尔曲线来设置碰撞边界 //通过添加贝塞尔曲线,自定义添加碰撞边界

    UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(20, 20, 100, 80)];

    path.lineWidth=5.0;

    path.lineCapStyle = kCGLineCapRound; //线条拐角

    path.lineJoinStyle = kCGLineJoinRound; //终点处理

    _collisionBehavior.collisionMode = UICollisionBehaviorModeEverything;

    [_collisionBehavior addBoundaryWithIdentifier:@"path1" forPath:path];


设置碰撞的贝塞尔曲线边界.gif

你可能感兴趣的:(iOS通过内置重力和陀螺仪实现物理仿真碰撞试验)