級(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)目需求:
- UI層面:
比較基礎(chǔ),上面三個(gè)Label顯示數(shù)據(jù)(分別是:錯(cuò)誤數(shù)花吟、倒計(jì)時(shí)秸歧、正確數(shù)),中間的一個(gè)大Label顯示所猜詞條衅澈,下面三個(gè)Button分別對(duì)應(yīng)(答錯(cuò)键菱、開始/復(fù)位、答對(duì))今布。
圖解:
-
邏輯層面:
- 點(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í)。
- 點(diǎn)擊對(duì)/錯(cuò)按鈕经备,對(duì)應(yīng)的Label的數(shù)字要
-
詞庫(kù)搭建:
- 詞庫(kù)難度分為
5
個(gè)等級(jí)请敦,等級(jí)越高镐躲,抽到的概率越小。 - 詞庫(kù)去重處理侍筛,抽到的詞條不再顯示萤皂。
- 概率算法。
- 詞庫(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
中蠢络,
- 先定義一個(gè)枚舉:表示題的難度系數(shù)衰猛。
typedef NS_ENUM(NSUInteger, QiGuessWordsType) {
QiGuessWordsTypePrimary,
QiGuessWordsTypeMiddle,
QiGuessWordsTypeSenior,
QiGuessWordsTypeComplex,
QiGuessWordsTypeCustom
};
- 暴露一個(gè)屬性,直接出隨機(jī)詞條谢肾。并暴露了一個(gè)方法腕侄,直接返回一個(gè)指定“難度”、“數(shù)量”的隨機(jī)的詞條數(shù)組芦疏。
@property (nonatomic, copy) NSString *randomWord;
- (NSArray<NSString *> *)randomWordsWithType:(QiGuessWordsType)type count:(NSUInteger)count;
在QiGuessWords.m
中冕杠,
- 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;
}
- 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代碼(七)
奇舞周刊