V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
Cee
V2EX  ›  分享创造

Co!orMix 小记──关于开发的那点儿事

  •  1
     
  •   Cee ·
    Cee · 2015-09-10 23:19:28 +08:00 · 3634 次点击
    这是一个创建于 3399 天前的主题,其中的信息可能已经有所发展或是发生改变。

    本文作者 LuckyMore

    关于 Co!orMix

    前几天, Cee 童鞋把 Co!orMix 开源了。当时刚上架的时候,团队里的另外两个童鞋都发了文,@Cee 讲产品,@Albus 讲设计(这两篇文章都在 V2EX 上发布过)。

    既然代码开源了,那是时候说一下项目本身了。

    Co!orMix 里面并没有什么特别有技术含量的东西,可以说,任何一个人都可以毫不费力地把它做出来。对于新手来说,也值得一试。不过毫不谦虚地说,如果要达到零错误率,还是有一定难度的,而上线至今,它的 Crash 率一直保持在 0 ,这是我所引以为豪的。(欢迎大家试玩!偷偷说一句,我可是跟组里承诺过,只要出现一个 crash ,就请吃饭的哦!)

    动手之前的思考

    无论是多简单的项目,开动之前必须要思考一下大致的架构。 Co!orMix 本身是一个相对很简单的游戏。

    从页面考虑:主页、设置页、游戏界面、游戏结果页、引导页
    从游戏本身考虑:题目、选项、得分、策略、游戏模式

    第一天晚上我们三个人商量出了游戏的大致功能和规则,我和 Cee 便直接开始讨论起了实现。由于游戏本身的复杂度不高,我们决定采用最传统的 MVC 来完成这个应用。

    • Model 层

      CMCard :卡片(对应游戏界面上半部分)
      CMColor :颜色(游戏中所对应的颜色的概念)
      CMQuestion :问题(包含 CMCard ,以及对应的 Option 和 Answer )
      CMScene :游戏场景(对应一次游戏,根据游戏模式区分不同表现)
      Factory :工厂(工厂模式,生产问题)

    • View 层

      CMCardView :卡片 View
      CMQuestionView :问题 View
      CMScoreView :得分

    • Controller 层

      CMClassicTutorialViewController/CMFantasyTutorialViewController :新手引导
      CMGameResultViewController :游戏结果
      CMGameViewController :游戏界面
      CMMenuViewController :游戏菜单界面
      CMSettingViewController :游戏设置界面

    项目结构

    由于项目比较简单,所以并没有按照功能模块进行分类,项目的结构大致如下:

    目录 职能
    Category 工具、扩展类
    ViewController Controller 层
    View View 层
    Model Model 层

    项目并没有使用任何第三方库(除了友盟统计),所以自然也就没有使用 Cocoapods 了。

    关于开发细节

    • 规范

    项目主体编码主要是我负责的,@Cee 在初期做了 Code Review 工作(惊讶吧!这么小的项目还做 Code Review )。开发在 dev 分支做,记得第一次提交的时候,@Cee 写了 N 个 comments ,很多都是关于 Coding Style 的问题(我自认已经很注意了,但是在某个人的强迫症面前根本不值一提),改完了所有的问题。之后就更加小心地完成编码工作。最后通过 Pull Request 合并进主分支。之后又开发了 Android 版本,感兴趣的童鞋可以去 dev_android 的分支看一下安卓版本,实现的大致逻辑和 iOS 差不多。

    • 适配

    项目采用 xib + AutoLayout + Size Classes 完成界面搭建,这也是我们第一次尝试使用 Size Classes 。

    总体来说,算是不错的一次实践, 0 代码完成全平台适配。我们以游戏界面中的 QuestionView 为例(CMQuestionView)做一下介绍,这个界面算是相当相当的典型了!

    分析一下这个界面,基本可以分三部分:卡片、问题、选项。这里我总共分了三个 View 来区分,分别为 Options 、 Card 、 Question ,其中 Options 是撑满整个 View 的。(参看 Fantasy 模式下的表现)

    可以注意一下这里还有一个背景占位符,它是一个垫在最底层撑满整个屏幕的透明的 View ,用来给其他 subview 做尺寸上的参考,比如 Card 部分的高度所做的约束通过背景占位符高度的一半来限定。

    另外分享一个小的 Tip ,在 xib 中可以直接通过右侧的选项实时查看不同设备下界面的布局:


    再有就是 Tutorial 的这个界面,细心的用户也会发现也是全适配的。我们的游戏引导界面并没有单纯地使用图片,而是在原有的游戏界面上加上了对应的引导元素,不管是箭头还是文字都是使用 AutoLayout 拉的约束。


    • 分享

    为求最简,我们的分享使用的系统原生的 UIActivityViewController 来实现。不过这里在适配的时候遇到了个坑,直接上代码:

    - (IBAction )onShareButtonClicked:(id )sender {
        [MobClick event:@"Share"];
        CMScoreView *scoreView = [[CMScoreView alloc] initWithScore:self.score];
        UIImage *imageToShare = [UIImage captureImageFromView:scoreView];
        NSString *stringToShare = [NSString stringWithFormat:@"I scored %ld in the %@ mode, play #Co!orMix with me: %@", (long )self.score, self.gameMode == classicMode ? @"classic" : @"fantasy" , kAppStoreUrl ];
        NSArray *activityItems = [[NSArray alloc] initWithObjects:imageToShare,stringToShare, nil];
        UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
        activityVC.excludedActivityTypes = @[UIActivityTypeSaveToCameraRoll];
        if (IS_IPAD ) {
            UIPopoverController *popup = [[UIPopoverController alloc] initWithContentViewController:activityVC];
            self.shareController = popup;
            popup.delegate = self;
            [popup presentPopoverFromRect:CGRectMake (self.view.frame.size.width / 2, self.shareBtn.frame.size.height + self.shareBtn.frame.origin.y , 0, 0 )inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
        } else {
            [self presentViewController:activityVC animated:YES completion:nil];
        }
    }
    

    对于 UIActivityViewController,在 iPhone 上,我们可以直接使用 present 的方式;但是在 iPad 上,这会引起崩溃,可以使用 UIPopoverController 来包装 UIActivityViewController

    • 设置界面的效果

    个人还是很喜欢这个效果的,使用的是 iOS8 自带的毛玻璃效果。上代码:

    - (IBAction )onSettingButtonClicked:(id )sender {
        [MobClick event:@"Setting"];
        self.settingViewController = [[CMSettingViewController alloc] initWithNibName:NSStringFromClass ([CMSettingViewController class]) bundle:nil];
        self.settingViewController.view.frame = self.view.bounds;
        self.settingViewController.view.alpha = 0;
        [self.view addSubview:self.blurView];
        [self.view addSubview:self.settingViewController.view];
        [self addChildViewController:self.settingViewController];
        [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            _blurView.alpha = 1;
            self.settingViewController.view.alpha = 1;
        } completion:nil];
    }
    
    - (UIView *)blurView {
        if (!_blurView ) {
            _blurView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
            _blurView.frame = [[UIScreen mainScreen] bounds];
            _blurView.alpha = 0;
        }
        return _blurView;
    }
    
    • GameCenter 和友盟

    这两块都是 @Cee 负责弄的。友盟的接入相对简单,不过 GameCenter @Cee 弄了一晚上,还吐槽网上没有成熟的 GameCenter 接入指南,我觉得有必要让他专门写一份了。

    • 面向对象

    项目虽小,可以用任何方式实现。不过这样一个小项目可以把面向对象思想很好地加以实践。所有的类都实现了对应的职能,隐藏了内部细节。

    总结

    以前写过不少项目,不过都比较庞大,而且基本都是负面教材。 Co!orMix 是一个小而精的 App ,从萌生想法,到 Demo ,到设计出炉正式完工,整个周期一共就一星期:设计花了一整天做出了可供交互的原型;在代码上只花了两天,但是却不仓促。代码均在 GitHub 上托管,测试上使用 TestFlight 完成分发,通过种子用户的体验修改游戏参数,提高用户体验。同时兼顾各种极端操作,保证代码安全性,做到零错误率。

    简单来说,对于新手来说,大家可以先下一下这个 App ,感兴趣的可以自己实现一遍,一点都不困难!然后再对比一下我们的实现。如果 Co!orMix 有任何不合理的地方,也欢迎指正!

    最后欢迎大家体验!

    16 条回复    2015-09-17 09:35:53 +08:00
    loveuqian
        1
    loveuqian  
       2015-09-10 23:26:13 +08:00 via iPhone
    赞,必须学习
    Dreista
        2
    Dreista  
       2015-09-10 23:26:16 +08:00 via Android
    赞。
    razrlele
        3
    razrlele  
       2015-09-10 23:53:49 +08:00
    顶 Cee 总!
    jetbillwin
        4
    jetbillwin  
       2015-09-11 08:12:33 +08:00
    赞 Cee 总!
    RyuZheng
        5
    RyuZheng  
       2015-09-11 10:25:45 +08:00
    zld
        6
    zld  
       2015-09-11 10:26:57 +08:00
    挺 Cee 总!
    kxxoling
        7
    kxxoling  
       2015-09-11 10:56:18 +08:00
    给 Cee 总点个赞!
    msxcms
        8
    msxcms  
       2015-09-11 16:34:39 +08:00
    ぺろぺろ
    21grams
        9
    21grams  
       2015-09-12 08:12:49 +08:00
    iOS 上的?
    SeanChense
        10
    SeanChense  
       2015-09-12 09:06:01 +08:00
    超级喜欢设置的设计
    Cee
        11
    Cee  
    OP
       2015-09-12 14:02:26 +08:00
    @21grams 恩是的,現在適配了 iPhone 和 iPad 。 考慮往 tvOS 上適配了。
    @SeanChense 謝謝!
    SeanChense
        12
    SeanChense  
       2015-09-12 14:38:46 +08:00
    @Cee 然后就照着你的思路也给我的项目加了个模糊背景了 哈哈哈
    hweining
        13
    hweining  
       2015-09-13 15:12:53 +08:00
    Cee 菊苣不准备把 android 版的开源了吗 感觉国内 quiz 这类游戏还有市场未挖掘‘
    Cee
        14
    Cee  
    OP
       2015-09-13 15:40:23 +08:00
    @hweining 其實有 http://github.com/Cee/ColorMix/blob/dev-android/
    當時偷懶就 android 也放在一個 repo 下了
    Caringor
        15
    Caringor  
       2015-09-15 12:00:07 +08:00
    Cee 苣苣 prpr
    wsph123
        16
    wsph123  
       2015-09-17 09:35:53 +08:00
    prprprpr !
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1015 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:32 · PVG 05:32 · LAX 13:32 · JFK 16:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.