在之前的關於 UIKit Dynamics 的二三事一文中,我們已經介紹過 iOS 7 SDK 中的新成員 UIKit Dynamics,下面示範我們就透過 UIKit Dynamics 來實作遊戲中常見的物理這裡撞擊效果,這只是一個簡單的示範,如果你正打算使用 UIKit Dynamics 來寫遊戲的話這邊並不建議,反而,在遊戲方面你可以透過 iOS 7 SDK 中的另一個新成員 Sprite Kit Framework 或是 cocos2d API 來達成。
示範中將參考憤怒鳥(Angry birds)的遊戲機制,來實作一個簡單的碰撞效果,當手指點擊畫面上任意一處時,紅色方塊便會飛向手指所點擊的位置,沿途如果觸碰到棕色矩型或是綠色方塊,都會產稱物理碰撞的效果,並且會以閃爍來做顯示被碰撞的物件。
相關文章
使用 UIKit Dynamics 中的 UIGravityBehavior、UICollisionBehavior 和 UIPushBehavior 物件,來幫助我們實現自由落體(拋物線)、物理碰撞、飛躍的效果。
捕捉手勢點擊的瞬間,並將位置換算成飛躍時的向量。
透過 <UICollisionBehaviorDelegate> 協定來取得兩個 UIView 碰撞的瞬間,並且使用 Block 技術在當前的函式中就設定好閃爍動畫。
部分關鍵程式碼
@Interface 區塊的設定
@interface MLViewController ()<UICollisionBehaviorDelegate> {
UIDynamicAnimator* animator;
UIGravityBehavior* gravity;
UICollisionBehavior* collision;
UIPushBehavior *push;
UIView *bird, *pig, *woodH, *woodV;
}
@end
設定場景(所有UIView的初始位置)
- (void)settingScenes {
//鳥
CGRect tmp = CGRectMake(10, 290, 30, 30);
bird = [[UIView alloc]initWithFrame:tmp];
[bird setBackgroundColor:[UIColor redColor]];
[bird setTag:1];
[[self view]addSubview:bird];
//垂直木條
tmp = CGRectMake(420, 200, 20, 120);
woodV = [[UIView alloc]initWithFrame:tmp];
[woodV setBackgroundColor:[UIColor brownColor]];
[woodV setTag:2];
[[self view]addSubview:woodV];
//水平木條
tmp = CGRectMake(370, 180, 120, 20);
woodH = [[UIView alloc]initWithFrame:tmp];
[woodH setBackgroundColor:[UIColor brownColor]];
[woodH setTag:2];
[[self view]addSubview:woodH];
//豬
tmp = CGRectMake(415, 150, 30, 30);
pig = [[UIView alloc]initWithFrame:tmp];
[pig setBackgroundColor:[UIColor greenColor]];
[pig setTag:3];
[[self view]addSubview:pig];
}
UIKit Dynamics 設定
- (void)settingDynamic {
//替self.view作UIDynamicBehavior的容器
animator = [[UIDynamicAnimator alloc] initWithReferenceView:[self view]];
//UIGravityBehavior
gravity = [[UIGravityBehavior alloc] initWithItems:@[bird, woodH, woodV, pig]];
[animator addBehavior:gravity];
//UICollisionBehavior(能與ReferenceView邊界產生碰撞)
collision = [[UICollisionBehavior alloc] initWithItems:@[bird, woodH, woodV, pig]];
[animator addBehavior:collision];
[collision setTranslatesReferenceBoundsIntoBoundary:YES];
[collision setCollisionDelegate:self];
//UIDynamicItemBehavior
UIDynamicItemBehavior* itemBehaviour = [[UIDynamicItemBehavior alloc] initWithItems:@[woodH,woodV]];
[itemBehaviour setElasticity:0.4]; //反彈係數
[itemBehaviour setAllowsRotation:YES];//旋轉
[itemBehaviour setFriction:0.2]; //磨擦力
[itemBehaviour setResistance:0.0]; //阻力
[animator addBehavior:itemBehaviour];
}
<UICollisionBehaviorDelegate> 協定
//碰撞時所觸發的函式
- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <uidynamicitem>)item1 withItem:(id <uidynamicitem>)item2 atPoint:(CGPoint)p {
UIView* view1 = (UIView*)item1;
UIView* view2 = (UIView*)item2;
//判斷碰撞是由鳥所引起
if (view1.tag == 1) {
[view2 setBackgroundColor:[UIColor whiteColor]];
//閃爍效果
[UIView animateWithDuration:0.3 animations:^{
if (view2.tag == 2)
[view2 setBackgroundColor:[UIColor brownColor]];
if (view2.tag == 3)
[view2 setBackgroundColor:[UIColor greenColor]];
}];
}
}
手指觸碰畫面
//朝向座標點發射
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint p = [touch locationInView:[self view]];
CGPoint bp = [bird frame].origin;
//飛出去
push = [[UIPushBehavior alloc] initWithItems:@[bird]mode:UIPushBehaviorModeInstantaneous];
[push setPushDirection:CGVectorMake((p.x - bp.x)*0.003, (p.y - bp.y)*0.003)];
[animator addBehavior:push];
}
執行結果
沒有留言:
張貼留言