使用Object-C制作了一個(gè)骰子游戲

首先蜜蜂祝大家狗年一帆風(fēng)順,因年底比較空閑,自己琢磨了一個(gè)骰子游戲

github地址

項(xiàng)目使用了Cocoapods,又設(shè)置了忽略文件,所以下載的時(shí)候請自行 pod install 一下

項(xiàng)目主要利用CATransform3DRotate改變view的perspective來實(shí)現(xiàn)骰子的3D旋轉(zhuǎn)功能,再進(jìn)行隨機(jī)數(shù)來達(dá)到搖骰子的功能

因?yàn)槭褂昧嗣A?,所以在模擬器的情況下會(huì)崩潰,建議真機(jī)運(yùn)行,或者將毛玻璃效果(全局搜索maoboli)屏蔽即可

先附上效果圖(使用liceape制作的gif,gif效果沒有實(shí)際的好):

gif

實(shí)現(xiàn)思路

首先,一個(gè)骰子為一個(gè)View,分別set 6張圖片,然后分別設(shè)置對應(yīng)的的CATransform3D

eg:

- (UIView *)view1
{
    if (!_view1) {
        _view1 = [[UIView alloc]init];        
        UIImageView *img = [[UIImageView alloc]init];
        [img setImage:[UIImage imageNamed:@"one"]];
        img.layer.allowsEdgeAntialiasing = true;
        [_view1 addSubview:img];
        [img mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.left.mas_equalTo(0.3);
            make.bottom.right.mas_equalTo(-0.3);
        }];
        _view1.layer.borderWidth = 1;
        _view1.layer.borderColor = [UIColor lightGrayColor].CGColor;
        _view1.layer.cornerRadius = 3;
    }
    return _view1;

}
[self addSubview:self.view1];
[self.view1 mas_makeConstraints:^(MASConstraintMaker *make) {
    make.left.right.top.bottom.mas_equalTo(0);
}];
CATransform3D viewTrans = CATransform3DIdentity;
viewTrans = CATransform3DRotate(view2Trans, M_PI_2, 0, 1, 0);
viewTrans = CATransform3DTranslate(view2Trans, theWidth/2, 0, -theWidth/2);
self.view1.layer.transform = viewTrans;

最重要的,記得吧骰子所在的view的M34屬性設(shè)置一下,才能看到3D效果

CATransform3D perspective = CATransform3DIdentity;
perspective.m34 = -1.0/500.0;
self.layer.sublayerTransform = perspective;

在controller初始化骰子所在的view(diceview)的時(shí)候,記得設(shè)置一下3d角度,便于觀察

CATransform3D perspective1 = CATransform3DIdentity;
perspective1.m34 = -1/500;
perspective1 = CATransform3DRotate(perspective1, -M_PI_4 + M_PI_2, 1, 0, 0);
perspective1 = CATransform3DRotate(perspective1, -M_PI_4, 0, 0, 1);
perspective1 = CATransform3DTranslate(perspective1, 0, 0, 25);
self.diceView.layer.sublayerTransform = perspective1;

然后點(diǎn)擊的時(shí)候,創(chuàng)建了一個(gè)timer,讓CATransform3DRotate改變,從而達(dá)到骰子3D翻轉(zhuǎn)的效果

- (void)timerAction
{
    
    self.theNum += 0.35;
    
    CATransform3D perspective = CATransform3DIdentity;
    perspective.m34 = -1.0/500.0;
    
    perspective = CATransform3DRotate(perspective, self.theNum, 1, 0, 0);
    perspective = CATransform3DRotate(perspective, self.theNum, 0, 1, 0);
    perspective = CATransform3DRotate(perspective, self.theNum, 0, 0, 1);
    
    perspective = CATransform3DTranslate(perspective, 0, 0, 25);
    self.diceView.layer.sublayerTransform = perspective;
    
}

再次點(diǎn)擊的時(shí)候創(chuàng)建先停止之前的timer,然后做另外一個(gè)timer的Action,一開始腦子沒轉(zhuǎn)過來,總是想著讓骰子搖到特定的角度,后來思路一通,先是用隨機(jī)數(shù)隨機(jī)出一個(gè)數(shù),然后再讓骰子做動(dòng)畫聽到那個(gè)點(diǎn)數(shù)

- (void)timer2Action
{
    self.Num1 = self.Num1 - 0.025;
    if (self.Num1 > 0) {
        CATransform3D perspective = CATransform3DIdentity;
        perspective.m34 = -1.0/500.0;
        switch (self.onPoint) {
            case 0:
            {
                // 1 的情況
                perspective = CATransform3DRotate(perspective, -M_PI_4 + M_PI_2 - self.Num1, 1, 0, 0);
                perspective = CATransform3DRotate(perspective, -self.Num1 , 0, 1, 0);
                perspective = CATransform3DRotate(perspective, M_PI_4 + M_PI_2 * self.roundPoint -self.Num1, 0, 0, 1);
            }
                break;
            case 1:
            {
                // 2 的情況
                perspective = CATransform3DRotate(perspective, -M_PI_4 - self.Num1, 1, 0, 0);
                perspective = CATransform3DRotate(perspective, -M_PI_4 + M_PI_2 * self.roundPoint - self.Num1, 0, 1, 0);
                perspective = CATransform3DRotate(perspective, M_PI_2 - self.Num1, 0, 0, 1);
                
            }
                break;
            case 2:
            {
                // 3 的情況
                perspective = CATransform3DRotate(perspective, -M_PI_4 + M_PI_2 * 2 - self.Num1, 1, 0, 0);
                perspective = CATransform3DRotate(perspective, -M_PI_4 - self.Num1 + M_PI_2 * self.roundPoint, 0, 1, 0);
                perspective = CATransform3DRotate(perspective, - self.Num1, 0, 0, 1);
                
            }
                break;
            case 3:
            {
                // 4 的情況
                perspective = CATransform3DRotate(perspective, -M_PI_4 - self.Num1, 1, 0, 0);
                perspective = CATransform3DRotate(perspective, -M_PI_4 - self.Num1 + M_PI_2 * self.roundPoint, 0, 1, 0);
                perspective = CATransform3DRotate(perspective, - self.Num1, 0, 0, 1);
                
            }
                break;
            case 4:
            {
                // 5 的情況
                perspective = CATransform3DRotate(perspective, -M_PI_4 - self.Num1, 1, 0, 0);
                perspective = CATransform3DRotate(perspective, -M_PI_4 + M_PI_2 * self.roundPoint - self.Num1, 0, 1, 0);
                perspective = CATransform3DRotate(perspective, -M_PI_2 - self.Num1, 0, 0, 1);
                
            }
                break;
            case 5:
            {
                // 6 的情況
                perspective = CATransform3DRotate(perspective, -M_PI_4 - M_PI_2 - self.Num1, 1, 0, 0);
                perspective = CATransform3DRotate(perspective, -self.Num1 , 0, 1, 0);
                perspective = CATransform3DRotate(perspective, M_PI_4 + M_PI_2 * self.roundPoint -self.Num1, 0, 0, 1);
            }
                break;
                
            default:
                break;
        }
        
        perspective = CATransform3DTranslate(perspective, 0, 0, 25 );
        self.diceView.layer.sublayerTransform = perspective;

    }else{
        [self.timer2 setFireDate:[NSDate distantFuture]];
        self.thetag = 0;
    }
}

最后有多個(gè)骰子存在的情況下,加了動(dòng)畫改進(jìn),讓5個(gè)骰子做旋轉(zhuǎn)動(dòng)畫,一開始想到的是用貝塞爾曲線實(shí)現(xiàn),后來嘗試
了一下利用CATransform3DRotate只改變Z的數(shù)值,發(fā)現(xiàn)這種方法也可行,然后再加上一個(gè)坐標(biāo)往center的動(dòng)畫,效果出來就很炫酷了

- (void)timerAction
{
    self.zTrans += M_PI_2*8/125;
    self.theNum += 0.35;
    CATransform3D perspective = CATransform3DIdentity;
    perspective.m34 = -1.0/500.0;
    perspective = CATransform3DRotate(perspective, self.theNum, 1, 0, 0);
    perspective = CATransform3DRotate(perspective, self.theNum, 0, 1, 0);
    perspective = CATransform3DRotate(perspective, self.theNum, 0, 0, 1);
    perspective = CATransform3DTranslate(perspective, 0, 0, 25);
    self.diceView.layer.sublayerTransform = perspective;
    self.diceView1.layer.sublayerTransform = perspective;
    self.diceView2.layer.sublayerTransform = perspective;
    self.diceView3.layer.sublayerTransform = perspective;
    self.diceView4.layer.sublayerTransform = perspective;
    
    CATransform3D perspective1 = CATransform3DIdentity;
    perspective1 = CATransform3DRotate(perspective1, self.zTrans, 0, 0, 1);
    self.layer.sublayerTransform = perspective1;
    
}

參考資料

具體的知識(shí)點(diǎn)可以參考 《核心動(dòng)畫高級(jí)技巧》

各路大神覺得不錯(cuò)的賞顆star吧,萌新求罩~??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容