1. 程式人生 > >ios拼圖遊戲(四)之觸控交換拼圖

ios拼圖遊戲(四)之觸控交換拼圖

之前介紹了使用長按手勢進行觸控拼圖的事件觸發,現在介紹如何觸發並實現兩個檢視之間的交換。

首先是長按手勢的事件函式。

//長按手勢執行函式
-(void)handleLongPress:(UILongPressGestureRecognizer*) recognizer{
    
    //手勢處於開始狀態時
    if(recognizer.state==UIGestureRecognizerStateBegan){
        
        NSLog(@"開始");
        _myTableView.scrollEnabled=NO;
        [self PressBegan:recognizer];
    }
    //手勢處於持續變化狀態時
    if(recognizer.state==UIGestureRecognizerStateChanged){
        
        NSLog(@"過程");
        [self PressChange:recognizer];
        
    }
    //手勢處於結束狀態時
    if(recognizer.state==UIGestureRecognizerStateEnded){
        
        NSLog(@"結束");
        _myTableView.scrollEnabled=YES;
        [self PanEnd:recognizer];
    }
    
}
在手勢開始時,執行PressBegan函式,在變化過程中執行PressChange函式,在結束時執行PanEnd函式。
@interface PieImageView : UIImageView<UIGestureRecognizerDelegate>{
    
    //記錄開始位置
    CGPoint startPoint;
    CGPoint startCenter;
    //記錄拼圖原位置
    CGPoint preCenter;
    //與本檢視交換的目標拼圖
    PieImageView* preV;
}
然後需要在該檢視類中新增一些屬性用於儲存一些值以方便判斷或還原。
//長按拖動開始執行的函式
-(void)PressBegan:(UILongPressGestureRecognizer*) recognizer{
    
    //儲存觸控起始點位置和中心位置
    CGPoint point=[recognizer locationInView:self];
    startPoint=point;
    preCenter=startCenter=self.center;
    //該view置於最前
    [[self superview]bringSubviewToFront:self];
}
//儲存分割後的拼圖檢視
@property(nonatomic,strong) NSMutableArray* pieImageViewArray;

觸發手勢的檢視必須保持在最前,否則在拖動時,就會導致被其他檢視遮擋。

//長按拖動期間執行的函式
-(void)PressChange:(UILongPressGestureRecognizer*) recognizer{
    
    
    //計算位移=當前位置-起始位置
    CGPoint point=[recognizer locationInView:self];//獲取觸控位置座標
    CGFloat dx=point.x-startPoint.x;
    CGFloat dy=point.y-startPoint.y;
    //計算移動後的view中心點
    CGPoint newCenter=CGPointMake(self.center.x+dx, self.center.y+dy);
    
    //限制使用者將檢視拖出螢幕
    CGFloat halfx=CGRectGetMaxX(self.bounds);
    //NSLog(@"%f",halfx);
    //x座標左邊界
    newCenter.x=MAX(halfx/2, newCenter.x);
    //x座標右邊界
    newCenter.x=MIN(self.superview.bounds.size.width-halfx/2, newCenter.x);
    //y座標同理
    CGFloat halfy=CGRectGetMidY(self.bounds);
    newCenter.y=MAX(halfy, newCenter.y);
    newCenter.y=MIN(self.superview.bounds.size.height-halfy, newCenter.y);
    
    //移動
    self.center=newCenter;
    
    //遍歷拼圖,交換拼圖的位置
    for(PieImageView *picV in self.pieImageViewArray){
        if(picV!=self){
            //如果檢視中心點進入另一檢視的範圍
            if(CGRectContainsPoint(picV.frame, self.center)){
                CGPoint temp;
                //如果preV非空且不等於picV,preV恢復原位置
                if(preV!=nil&&preV!=picV){
                    temp=preV.center;
                    preV.center=startCenter;
                    startCenter=temp;
                }
                preV=picV;
 
                //交換兩個檢視的中心點
                temp=picV.center;
                picV.center=startCenter;
                startCenter=temp;
                
                //保持移動檢視在最前面
                [[self superview]bringSubviewToFront:preV];
                [[self superview]bringSubviewToFront:self];
        
                //如果本拼圖回到原位置
                if(CGPointEqualToPoint(startCenter, preCenter))
                    preV=nil;
                break;
            }
        }
    }
}
以上函式實現了兩個動作,第一實現了檢視的長按後拖動的功能,通過計算觸控起點和目標點的位移,實現了檢視隨著手指的移動而移動的動作。第二實現了本檢視與目標檢視的交換,遍歷陣列pieImageViewArray,判斷本檢視的中心點是否進入了其他檢視的區域範圍,如果是就行進行檢視交換,否則繼續遍歷。在進行檢視交換時,需要判斷在本次拖動中是否已經進行過與目標檢視交換,如果是就必須把之前的目標檢視恢復原位置,然後更新目標檢視。如果本檢視在本次拖動中回到原位置,則重置目標檢視preV,如果不重置就會出現圖片被覆蓋的情況。
//拖動結束後執行的函式
-(void)PanEnd:(UIGestureRecognizer*) recognizer{
    //拼圖移動到目標位置
    self.center=startCenter;
    //重置
    preV=nil;
}
將檢視移動到目標位置,重置preV。

以上就是交換拼圖的相關操作,如有錯誤,請指正,謝謝