使用Object-C制作了一个骰子游戏

首先蜜蜂祝大家狗年一帆风顺,因年底比较空闲,自己琢磨了一个骰子游戏

github地址

项目使用了Cocoapods,又设置了忽略文件,所以下载的时候请自行 pod install 一下

项目主要利用CATransform3DRotate改变view的perspective来实现骰子的3D旋转功能,再进行随机数来达到摇骰子的功能

因为使用了毛玻璃,所以在模拟器的情况下会崩溃,建议真机运行,或者将毛玻璃效果(全局搜索maoboli)屏蔽即可

先附上效果图(使用liceape制作的gif,gif效果没有实际的好):

gif

实现思路

首先,一个骰子为一个View,分别set 6张图片,然后分别设置对应的的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属性设置一下,才能看到3D效果

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

在controller初始化骰子所在的view(diceview)的时候,记得设置一下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;

然后点击的时候,创建了一个timer,让CATransform3DRotate改变,从而达到骰子3D翻转的效果

- (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;
    
}

再次点击的时候创建先停止之前的timer,然后做另外一个timer的Action,一开始脑子没转过来,总是想着让骰子摇到特定的角度,后来思路一通,先是用随机数随机出一个数,然后再让骰子做动画听到那个点数

- (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;
    }
}

最后有多个骰子存在的情况下,加了动画改进,让5个骰子做旋转动画,一开始想到的是用贝塞尔曲线实现,后来尝试
了一下利用CATransform3DRotate只改变Z的数值,发现这种方法也可行,然后再加上一个坐标往center的动画,效果出来就很炫酷了

- (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;
    
}

参考资料

具体的知识点可以参考 《核心动画高级技巧》

各路大神觉得不错的赏颗star吧,萌新求罩~😆

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容