背景:
最近看到UIDynamicAnimator相关库,想到可以利用重力,碰撞等物理效果,写一个之前流行的小游戏"合成大西瓜"出来,于是加了一点花活,整了一个出来.
核心要点
- UIGravityBehavior
- UICollisionBehavior
- UIPanGestureRecognizer
说明:
首先,UIGravityBehavior和UICollisionBehavior是苹果的物理动态库,详细应用随手一搜就能搜到很多文章,这里不再赘述.这里要注意的是这两者初始化时
可以使用initWithItems:初始化,不过需要传入的是一个 →包含item的数组← (比如:@[view])
- (instancetype)initWithItems:(NSArray<id <UIDynamicItem>> *)items NS_DESIGNATED_INITIALIZER;
也可以使用alloc]init]初始化,初始化后再通过addItem的方法添加item,此时传入的是item(比如view)而不是数组
- (void)addItem:(id <UIDynamicItem>)item;
另外此处UIDynamicItem,并非一个具体的类,而是遵循了UIDynamicItem协议,也就是说,如果你自定义的对象,如果遵循了UIDynamicItem协议,那可以当做item用.另外UIView对象是遵循了UIDynamicItem协议的,所以UIView以及其子类都可以是item.
在UIDynamicItem协议里有个UIDynamicItemCollisionBoundsType属性,这个属性是readonly,但我们可以通过自定义类继承UIView来重写这个属性.当然,除了在@interface里要重写,
@property (nonatomic) UIDynamicItemCollisionBoundsType collisionBoundsType;
还要在@implementation中加入
@synthesize collisionBoundsType;
然后切完圆角的view就在物理上也能展现圆的特性了.
然后,考虑到刚生成的水果是允许玩家左右移动到满意的位置的,所以每个水果view的对象需要添加UIPanGestureRecognizer,也就是pan手势.但放入的水果又不允许拖出来反复放,所以要在恰当的时机移除掉这个手势.这个时机就是
pan.state == UIGestureRecognizerStateEnded
同时,在移除手势前需要将view(item)加入Gravity,Collision,UIDynamicAnimator
最后,两个水果(view)的碰撞的识别,以及多个水果(view)没有发生合成以至于累加到屏幕上层的识别,都是通过UICollisionBehaviorDelegate以及UIDynamicAnimatorDelegate中的协议方法实现的.详见代码->传送门<-
- 最后,若有错误,恳请斧正。