iOS 小游戲項(xiàng)目——你話我猜升級(jí)版

級(jí)別: ★☆☆☆☆
標(biāo)簽:「iOS」「小游戲項(xiàng)目」「你話我猜」
作者: MrLiuQ
審校: QiShare團(tuán)隊(duì)

前言:最近公司部門在組織團(tuán)建弥锄,需要準(zhǔn)備兩個(gè)團(tuán)建小游戲:
分別是“數(shù)字速算升級(jí)版”和“你話我猜升級(jí)版”户魏。

小編琢磨了一下闲孤,發(fā)現(xiàn)這個(gè)兩個(gè)小項(xiàng)目很適合iOS入門學(xué)習(xí),故這篇文章誕生了洞拨。
本篇將介紹iOS 小游戲項(xiàng)目——你話我猜升級(jí)版扯罐。
希望通過這篇文章,幫助對(duì)iOS感興趣的同學(xué)快速入門iOS烦衣。

我們先來看看效果圖:

效果圖

一歹河、項(xiàng)目需求:

  1. UI層面:
    比較基礎(chǔ),上面三個(gè)Label顯示數(shù)據(jù)(分別是:錯(cuò)誤數(shù)花吟、倒計(jì)時(shí)秸歧、正確數(shù)),中間的一個(gè)大Label顯示所猜詞條衅澈,下面三個(gè)Button分別對(duì)應(yīng)(答錯(cuò)键菱、開始/復(fù)位、答對(duì))今布。

圖解:


UI
  1. 邏輯層面:

    • 點(diǎn)擊對(duì)/錯(cuò)按鈕经备,對(duì)應(yīng)的Label的數(shù)字要+1
    • 做一個(gè)計(jì)時(shí)器部默,游戲時(shí)長(zhǎng)定為300秒侵蒙,時(shí)間到0時(shí),結(jié)束游戲傅蹂,對(duì)/錯(cuò)按鈕禁止點(diǎn)擊蘑志。
    • 點(diǎn)擊開始、對(duì)/錯(cuò)按鈕贬派,中間的詞條都需要更新急但。
    • 點(diǎn)擊開始按鈕,出現(xiàn)一個(gè)彈窗搞乏,點(diǎn)擊確定波桩,開始倒計(jì)時(shí)。
  2. 詞庫(kù)搭建:

    • 詞庫(kù)難度分為5個(gè)等級(jí)请敦,等級(jí)越高镐躲,抽到的概率越小。
    • 詞庫(kù)去重處理侍筛,抽到的詞條不再顯示萤皂。
    • 概率算法。

二匣椰、實(shí)現(xiàn)思路:

1. UI層面:

  • 方式一:storyboard(拖控件裆熙、加約束)。
  • 方式二:純代碼。

項(xiàng)目中入录,我選擇的storyboard蛤奥。獨(dú)立開發(fā)時(shí),使用storyboard比較高效僚稿。

@property (weak, nonatomic) IBOutlet UILabel *wordLabel;//!< 猜題Label
@property (weak, nonatomic) IBOutlet UILabel *secondsLabel;//!< 計(jì)時(shí)Label
@property (weak, nonatomic) IBOutlet UILabel *correctLabel;//!< 成功計(jì)數(shù)Label
@property (weak, nonatomic) IBOutlet UILabel *wrongLabel;//!< 失敗計(jì)數(shù)Label
@property (weak, nonatomic) IBOutlet UIButton *correctButton;//!< 成功按鈕
@property (weak, nonatomic) IBOutlet UIButton *wrongButton;//!< 失敗按鈕
@property (weak, nonatomic) IBOutlet UIButton *startButton;//!< 開始按鈕

2. 業(yè)務(wù)邏輯:

  • 所要保存的屬性:
@property (nonatomic, assign) NSUInteger seconds;//!< 剩余時(shí)間
@property (nonatomic, assign) NSInteger correctCount;//!< 答對(duì)題數(shù)
@property (nonatomic, assign) NSInteger wrongCount;//!< 答錯(cuò)題數(shù)

@property (nonatomic, strong) QiGuessWords *guessWords;//!< 詞條(題目)
@property (nonatomic, strong) NSTimer *timer;//!< 計(jì)時(shí)器
  • 開始按鈕業(yè)務(wù)邏輯:
//! 開始按鈕點(diǎn)擊事件
- (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];
}
  • 成功/失敗按鈕業(yè)務(wù)邏輯:
//! 成功按鈕點(diǎn)擊事件
- (IBAction)correctButtonClicked:(id)sender {
    
    _correctLabel.text = [NSString stringWithFormat:@"%li",(long)++_correctCount];
    _wordLabel.text = _guessWords.randomWord;
}

//! 失敗按鈕點(diǎn)擊事件
- (IBAction)wrongButtonClicked:(id)sender {
    
    _wrongLabel.text = [NSString stringWithFormat:@"%li",(long)++_wrongCount];
    _wordLabel.text = _guessWords.randomWord;
}
  • 定時(shí)器相關(guān)代碼:
#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];
}

三、難點(diǎn):詞庫(kù)工具

詞庫(kù)的難點(diǎn)在于:去重蚀同、分級(jí)缅刽、按概率抽題。

QiGuessWords.h中蠢络,

  1. 先定義一個(gè)枚舉:表示題的難度系數(shù)衰猛。
typedef NS_ENUM(NSUInteger, QiGuessWordsType) {
    QiGuessWordsTypePrimary,
    QiGuessWordsTypeMiddle,
    QiGuessWordsTypeSenior,
    QiGuessWordsTypeComplex,
    QiGuessWordsTypeCustom
};
  1. 暴露一個(gè)屬性,直接出隨機(jī)詞條谢肾。并暴露了一個(gè)方法腕侄,直接返回一個(gè)指定“難度”、“數(shù)量”的隨機(jī)的詞條數(shù)組芦疏。
@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 = @"班主任,放風(fēng)箏...";
        NSString *seniorWords = @"落井下石,七上八下...";
        NSString *complexWords = @"低頭思故鄉(xiāng),處處聞啼鳥...";
        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方法:
    注意這里三元表達(dá)式的運(yùn)用。

思想:系統(tǒng)算出一個(gè)0~9的隨機(jī)數(shù)酸茴,

隨機(jī)數(shù) 詞條類型 概率
0分预,1 primaryWords(初級(jí)) 20%
2,3 middleWords(中等) 20%
4薪捍,5 seniorWords(高級(jí)) 20%
6 complexWords(復(fù)雜) 10%
7笼痹,8,9 customWords(自定義) 30%
#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;
    } //!< 所有數(shù)據(jù)取完后會(huì)造成死循環(huán)
    
    NSUInteger index = arc4random() % words.count;
    NSString *randomWord = words[index];
    [words removeObject:randomWord];
    
    return randomWord;
}

最后酪穿,游戲工程源碼:游戲源碼


了解更多iOS及相關(guān)新技術(shù)凳干,請(qǐng)關(guān)注我們的公眾號(hào):

關(guān)注我們的途徑有:
QiShare(簡(jiǎn)書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公眾號(hào))

推薦文章:
iOS 文件操作簡(jiǎn)介
iOS 關(guān)鍵幀動(dòng)畫
iOS 編寫高質(zhì)量Objective-C代碼(七)
奇舞周刊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市被济,隨后出現(xiàn)的幾起案子救赐,更是在濱河造成了極大的恐慌,老刑警劉巖只磷,帶你破解...
    沈念sama閱讀 218,386評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件经磅,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡钮追,警方通過查閱死者的電腦和手機(jī)预厌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來元媚,“玉大人轧叽,你說我怎么就攤上這事苗沧。” “怎么了犹芹?”我有些...
    開封第一講書人閱讀 164,704評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵崎页,是天一觀的道長(zhǎng)鞠绰。 經(jīng)常有香客問我腰埂,道長(zhǎng),這世上最難降的妖魔是什么蜈膨? 我笑而不...
    開封第一講書人閱讀 58,702評(píng)論 1 294
  • 正文 為了忘掉前任屿笼,我火速辦了婚禮,結(jié)果婚禮上翁巍,老公的妹妹穿的比我還像新娘驴一。我一直安慰自己,他們只是感情好灶壶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評(píng)論 6 392
  • 文/花漫 我一把揭開白布肝断。 她就那樣靜靜地躺著,像睡著了一般驰凛。 火紅的嫁衣襯著肌膚如雪胸懈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評(píng)論 1 305
  • 那天恰响,我揣著相機(jī)與錄音趣钱,去河邊找鬼。 笑死胚宦,一個(gè)胖子當(dāng)著我的面吹牛首有,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播枢劝,決...
    沈念sama閱讀 40,314評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼井联,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了您旁?” 一聲冷哼從身側(cè)響起烙常,我...
    開封第一講書人閱讀 39,230評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎被冒,沒想到半個(gè)月后军掂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昨悼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評(píng)論 3 336
  • 正文 我和宋清朗相戀三年蝗锥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片率触。...
    茶點(diǎn)故事閱讀 39,991評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡终议,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情穴张,我是刑警寧澤细燎,帶...
    沈念sama閱讀 35,706評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站皂甘,受9級(jí)特大地震影響玻驻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜偿枕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評(píng)論 3 330
  • 文/蒙蒙 一璧瞬、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧渐夸,春花似錦嗤锉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至苫幢,卻和暖如春访诱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背态坦。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工盐数, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伞梯。 一個(gè)月前我還...
    沈念sama閱讀 48,158評(píng)論 3 370
  • 正文 我出身青樓玫氢,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親谜诫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子漾峡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容