美文网首页iOS开发攻城狮的集散地
iOS 小游戏项目——你话我猜升级版

iOS 小游戏项目——你话我猜升级版

作者: 齐舞647 | 来源:发表于2018-11-01 18:47 被阅读13次

    前言:最近公司部门在组织团建,需要准备准备两个团建小游戏,
    分别是“数字速算升级版”和“你话我猜升级版”。

    小编琢磨了一下,发现这个两个小项目很适合入门iOS,故这篇文章诞生了。
    本篇将介绍iOS 小游戏项目——你画我猜升级版。
    希望通过这篇文章,能够帮助对iOS感兴趣的同学快速入门iOS。

    我们先来看看效果图:

    效果图

    一、项目需求:

    1. UI层面:
      比较基础,上面三个Label显示数据(分别是:错误数、倒计时、正确数),中间的一个大Label显示所猜词条,下面三个Button分别对应(答错、开始/复位、答对)。

    图解:


    UI
    1. 逻辑层面:

      • 点击对/错按钮,对应的Label的数字要+1
      • 做一个计时器,游戏时长定为300秒,时间到0时,结束游戏,对错按钮禁止点击。
      • 点击开始、对/错按钮 中间的词条都需要更新。
      • 点击开始按钮,出现一个弹窗,点击确定,开始倒计时。
    2. 词库搭建:

      • 词库难度分为5个等级,等级越高,抽到的概率越小。
      • 词库去重处理,抽到的词条不再显示。
      • 概率算法。

    二、实现思路:

    1. UI层面:

    • 方式一:storyboard(拖控件、加约束)
    • 方式二:纯代码

    项目中,我选择的storyboard。独立开发时,用storyboard比较高效。
    日常还是多用纯代码比较好,毕竟代码是万能的~

    @property (weak, nonatomic) IBOutlet UILabel *wordLabel;//!< 猜题Label
    @property (weak, nonatomic) IBOutlet UILabel *secondsLabel;//!< 计时Label
    @property (weak, nonatomic) IBOutlet UILabel *correctLabel;//!< 成功计数Label
    @property (weak, nonatomic) IBOutlet UILabel *wrongLabel;//!< 失败计数Label
    @property (weak, nonatomic) IBOutlet UIButton *correctButton;//!< 成功按钮
    @property (weak, nonatomic) IBOutlet UIButton *wrongButton;//!< 失败按钮
    @property (weak, nonatomic) IBOutlet UIButton *startButton;//!< 开始按钮
    

    2. 业务逻辑:

    • 所要保存的属性:
    @property (nonatomic, assign) NSUInteger seconds;//!< 剩余时间
    @property (nonatomic, assign) NSInteger correctCount;//!< 答对题数
    @property (nonatomic, assign) NSInteger wrongCount;//!< 答错题数
    
    @property (nonatomic, strong) QiGuessWords *guessWords;//!< 词条(题目)
    @property (nonatomic, strong) NSTimer *timer;//!< 计时器
    
    • 开始按钮业务逻辑:
    //! 开始按钮点击事件
    - (IBAction)startButtonClicked:(UIButton *)sender {
        
        NSString *message = [NSString stringWithFormat:@"确定要 %@ 吗?", sender.currentTitle];
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:nil message:message preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
        UIAlertAction *confirmAction = [UIAlertAction actionWithTitle:sender.currentTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            sender.selected = !sender.selected;
        
            self.correctButton.enabled = !self.correctButton.enabled;
            self.wrongButton.enabled = !self.wrongButton.enabled;
            
            if (sender.selected) {
                self.wordLabel.text = self.guessWords.randomWord;
                [self startTimer];
            } else {
                [self resetElements];
            }
        }];
        [alertController addAction:cancelAction];
        [alertController addAction:confirmAction];
        
        [self.navigationController presentViewController:alertController animated:YES completion:nil];
    }
    
    • 成功/失败按钮业务逻辑:
    //! 成功按钮点击事件
    - (IBAction)correctButtonClicked:(id)sender {
        
        _correctLabel.text = [NSString stringWithFormat:@"%li",(long)++_correctCount];
        _wordLabel.text = _guessWords.randomWord;
    }
    
    //! 失败按钮点击事件
    - (IBAction)wrongButtonClicked:(id)sender {
        
        _wrongLabel.text = [NSString stringWithFormat:@"%li",(long)++_wrongCount];
        _wordLabel.text = _guessWords.randomWord;
    }
    
    • 定时器相关代码:
    #pragma mark - Private functions
    
    - (void)startTimer {
        
        [self stopTimer];
        
        _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(countDown) userInfo:nil repeats:YES];
    }
    
    - (void)stopTimer {
        
        [_timer invalidate];
        _timer = nil;
    }
    
    - (void)countDown {
    
        _secondsLabel.text = [NSString stringWithFormat:@"%li", (long)--_seconds];
        
        if (_seconds <= 0) {
            [self stopTimer];
            _correctButton.enabled = NO;
            _wrongButton.enabled = NO;
        }
        else if (_seconds < 30) {
            _secondsLabel.textColor = [UIColor redColor];
        }
    }
    
    • 重置元素逻辑:
    - (void)resetElements {
        
        _wordLabel.text = @"";
        
        _seconds = 300;
        _wrongCount = 0;
        _correctCount = 0;
        _secondsLabel.text = [NSString stringWithFormat:@"%li", (long)_seconds];
        _correctLabel.text = [NSString stringWithFormat:@"%li", (long)_correctCount];
        _wrongLabel.text = [NSString stringWithFormat:@"%li", (long)_wrongCount];
        _correctButton.enabled = NO;
        _wrongButton.enabled = NO;
        _startButton.enabled = YES;
        
        [self stopTimer];
    }
    

    三、难点:词库工具

    词库的难点在于:去重、分级、按概率抽题。

    QiGuessWords.h中,

    1. 先定义一个枚举:表示题的难度系数
    typedef NS_ENUM(NSUInteger, QiGuessWordsType) {
        QiGuessWordsTypePrimary,
        QiGuessWordsTypeMiddle,
        QiGuessWordsTypeSenior,
        QiGuessWordsTypeComplex,
        QiGuessWordsTypeCustom
    };
    
    1. 暴露一个属性,直接出随机词条。甚至暴露一个方法,直接返回一个指定难度的随机的词条数组。
    @property (nonatomic, copy) NSString *randomWord;
    
    - (NSArray<NSString *> *)randomWordsWithType:(QiGuessWordsType)type count:(NSUInteger)count;
    

    QiGuessWords.m中,

    1. init方法
    - (instancetype)init {
        
        self = [super init];
        
        if (self) {
            
            NSString *primaryWords = @"螃蟹,口红...";
            NSString *middleWords = @"班主任,放风筝...";
            NSString *seniorWords = @"落井下石,七上八下...";
            NSString *complexWords = @"低头思故乡,处处闻啼鸟...";
            NSString *customWords = @"TCP,360杀毒...";
            
            _primaryWords = [primaryWords componentsSeparatedByString:@","].mutableCopy;
            _middleWords = [middleWords componentsSeparatedByString:@","].mutableCopy;
            _seniorWords = [seniorWords componentsSeparatedByString:@","].mutableCopy;
            _complexWords = [complexWords componentsSeparatedByString:@","].mutableCopy;
            _customWords = [customWords componentsSeparatedByString:@","].mutableCopy;
            
            _allWords = @[_primaryWords, _middleWords, _seniorWords, _complexWords, _customWords];
        }
        
        return self;
    }
    
    1. Getter方法:
      注意这里三元表达式的运用。

    思想:系统算出一个0~9的随机数,

    随机数 词条类型 概率
    0,1,2 primaryWords(初级) 30%
    3,4 middleWords(中等) 20%
    5,6 seniorWords(高级) 20%
    7 complexWords(复杂) 10%
    8,9 customWords(自定义) 20%
    #pragma mark - Getters
    
    - (NSString *)randomWord {
        
        NSUInteger r = arc4random() % 10;
        NSUInteger i = r < 2? 0: r < 4? 1: r < 6? 2: r < 7? 3: 4;
        
        NSMutableArray<NSString *> *words = _allWords[i];
        
        if (words.count == 0) {
            return self.randomWord;
        } //!< 所有数据取完后会造成死循环
        
        NSUInteger index = arc4random() % words.count;
        NSString *randomWord = words[index];
        [words removeObject:randomWord];
        
        return randomWord;
    }
    

    最后,工程源码:游戏源码

    相关文章

      网友评论

        本文标题:iOS 小游戏项目——你话我猜升级版

        本文链接:https://www.haomeiwen.com/subject/iypgzftx.html