iOS【開發熱門遊戲_超級猜圖Demo】
阿新 • • 發佈:2019-02-14
先看效果圖
思路
需求分析
1,搭建介面
1》上半部分,固定的,用Storyboard直接連線(OK)
2》下半部分,根據題目的變化,不斷變化和調整,用程式碼方式實現比較合適(OK)
*備選按鈕區域(OK)
*答案按鈕區域(OK)
2,編寫程式碼
1》大圖,小圖的切換(OK)
2》下一題(OK)
3》備選按鈕的點選,讓文字進入答案區(Ok)
4》判斷對錯勝負(OK)
*勝利:進入下一題(OK)
*失敗:提示使用者重新選擇(OK)
5》答案按鈕的點選(OK)
把答案區的文字回覆到備選區域(Ok)
程式碼
//
// NYViewController.m
// 01-超級猜圖遊戲
//
// Created by apple on 15-3-21.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYViewController.h"
#import "NYQuestion.h"
@interface NYViewController ()
@property (weak, nonatomic) IBOutlet UIButton *iconButton;
@property (nonatomic, strong) UIButton *cover;
@property (nonatomic , strong) NSArray *questions;
@property (weak, nonatomic) IBOutlet UILabel *noLabel;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UIButton *nextQuestionButton;
@property (weak, nonatomic) IBOutlet UIView *answerView;
@property (weak, nonatomic) IBOutlet UIView *optionsView;
@property (weak, nonatomic) IBOutlet UIButton *scoreButton;
/** 題目索引*/
@property (nonatomic, assign) int index;
@end
@implementation NYViewController
#define kButtonWidth 35
#define kButtonHeight 35
#define kButtonMargin 10
#define kTotolCol 7
-(NSArray *)questions
{
if (_questions == nil) {
_questions = [NYQuestion questions];
}
return _questions;
}
-(UIButton *)cover{
if (_cover == nil) {
//1,新增蒙版(遮罩)
_cover = [[UIButton alloc] initWithFrame:self.view.bounds];
_cover.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5];
[self.view addSubview:_cover];
_cover.alpha = 0.0;
[_cover addTarget:self action:@selector(bigImage) forControlEvents:UIControlEventTouchUpInside];
}
return _cover;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.index = -1;
[self nextQuestion];
}
//設定狀態列為亮色,可以顯示(最上面顯示時間訊號那一行)
- (UIStatusBarStyle)preferredStatusBarStyle
{
// UIStatusBarStyleDefault = 0,黑色黑色狀態列
// StatusBarStyleLightContent NS_ENUM_AVAILABLE_IOS(7_0) = 1,亮色狀態列
return UIStatusBarStyleLightContent;
}
#pragma mark - 大圖小圖切換
/**
*大圖小圖顯示切換
*/
- (IBAction)bigImage
{
//如果沒有放大就放大,放大了就縮小
//通過判斷iconButton的大小
if (self.cover.alpha == 0) {
//2,把影象按鈕放到最前邊
[self.view bringSubviewToFront:self.iconButton];
//3,動畫放大影象按鈕
CGFloat w = self.view.bounds.size.width;
CGFloat h = w;
CGFloat y = (self.view.bounds.size.height-h)*0.5;
[UIView animateWithDuration:1.0 animations: ^{
self.iconButton.frame = CGRectMake(0, y, w, h);
self.cover.alpha = 1.0;
}];
}else{//縮小圖片
//將圖片恢復初始位置
[UIView animateWithDuration:1.0 animations:^{
self.iconButton.frame = CGRectMake(85, 85, 150, 150);
self.cover.alpha = 0.0;//讓遮罩逐漸消失
}];
}
}
#pragma mark - 下一題
/**
*下一個題目
*
*主要的方法,儘量保留簡短的程式碼,主要體現思路和流程即可。
*/
-(IBAction)nextQuestion{
//1,當前答題的索引,索引遞增
self.index ++;
//如果index到達最後一個題,那麼提示使用者,播放動畫。。。
if (self.index == self.questions.count) {
NSLog(@"通關啦!!!");
return;
}
//2,從陣列中按照索引取出題目資料模型
NYQuestion *question = self.questions[self.index];
//3,設定基本資訊
[self setupBasicInfo:question];
//4,設定答案按鈕
[self creatAnswerButton:question];
//5,設定備選按鈕
[self creatOptionsButton:question];
}
/** 設定基本資訊*/
-(void)setupBasicInfo:(NYQuestion *)question
{
self.noLabel.text = [NSString stringWithFormat:@"%d/%d",self.index+1,self.questions.count ];
self.titleLabel.text = question.title;
[self.iconButton setImage:[UIImage imageNamed:question.icon] forState:UIControlStateNormal];
//如果達到最後一題,禁用一下按鈕
self.nextQuestionButton.enabled = (self.index < self.questions.count-1);
}
/** 建立答案區按鈕*/
-(void)creatAnswerButton:(NYQuestion *)question
{
//刪除answerView已經存在的控制元件
for (UIView *btn in self.answerView.subviews){
[btn removeFromSuperview];
}
CGFloat answerW = self.answerView.bounds.size.width;
int length = question.answer.length;//答案的字元數量
CGFloat answerX = (answerW - length*kButtonWidth - (length-1)*kButtonMargin)*0.5;//答案按鈕開始的第一個字的最左邊座標
//建立所有答案的按鈕
for (int i = 0; i<length; i++) {
CGFloat x = answerX + i*(kButtonWidth + kButtonMargin);
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(x, 0, kButtonWidth, kButtonHeight)];
[btn setBackgroundImage:[UIImage imageNamed:@"btn_answer"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"bn_answer_highlighted" ] forState:UIControlStateHighlighted];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.answerView addSubview:btn];
[btn addTarget:self action:@selector(answerClick:) forControlEvents:UIControlEventTouchUpInside];
}
}
/** 建立備選區按鈕*/
-(void)creatOptionsButton:(NYQuestion *)question
{
//問題:每次呼叫下一題方法時,都會重新建立21個按鈕
//解決:如果按鈕已經存在,並且是21個,只需要更改按鈕標題即可
if (self.optionsView.subviews.count != question.options.count) {
//定義行和列
CGFloat optionW = self.optionsView.bounds.size.width;
CGFloat optionX = (optionW - kButtonWidth*kTotolCol - kButtonMargin *(kTotolCol-1))*0.5;
for(int i = 0 ; i<question.options.count;i++)
{
int row = i/kTotolCol;//行
int col = i%kTotolCol;//列
CGFloat x = optionX + col * (kButtonMargin+kButtonWidth);
CGFloat y = row * (kButtonHeight+kButtonMargin);
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(x, y, kButtonWidth, kButtonHeight)];
/*喵了個咪的,這裡出了這麼一個錯誤
每一個按鈕可以有8張圖片,4個狀態每個狀態有兩個,image和backgroundImage,如果你設定了image圖片那麼你的設定的title將會被你的image擠開到一邊,如果你的image大的話你就真的看不到他了*/
// [btn setImage:[UIImage imageNamed:@"btn_option"] forState:UIControlStateNormal];
// [btn setImage:[UIImage imageNamed:@"btn_option_highlighted"] forState:UIControlStateHighlighted];
[btn setBackgroundImage:[UIImage imageNamed:@"btn_option"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"btn_option_highlighted"] forState:UIControlStateHighlighted];
//新增備選區域按鈕標題
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];//設定標題顏色
[self.optionsView addSubview:btn];//用爹來新增,刪除時候是用爹找到所有兒子然後讓兒子自己刪自己
//新增被選取按鈕點選事件
[btn addTarget:self action:@selector(optionClick:) forControlEvents:UIControlEventTouchUpInside];
}
}
//如果按鈕已經存在,在點選下一題的時候,只需要設定標題即可
int i = 0;
for (UIButton *btn in self.optionsView.subviews){
//設定標題內容
[btn setTitle:question.options[i++] forState:UIControlStateNormal];
//取消按鈕的隱藏
btn.hidden = NO;
}
}
#pragma mark - 備選按鈕點選方法
/**新增被選取按鈕點選事件*/
-(void)optionClick:(UIButton *)button
{
//1,在答案區找到第一個標題為空的按鈕
UIButton *ansBtn = [self firstAnswerButton];
if (ansBtn == nil)return;
//2,將button的標題賦值給答案去的按鈕
[ansBtn setTitle:button.currentTitle forState:UIControlStateNormal];
//3,隱藏按鈕
button.hidden = YES;
//4,判斷結果
[self judge];
}
/**判斷結果*/
-(void)judge{
//如果答題區按鈕都有答案,才需要判斷結果
//遍歷所有答題區的按鈕
BOOL isFull = YES;
NSMutableString * strM = [NSMutableString string];
for(UIButton * btn in self.answerView.subviews)
{
if (btn.currentTitle.length == 0) {
//只要有一個按鈕沒有字 //
isFull = NO;
break;//跳出迴圈
}else{//有字,拼接臨時字串
[strM appendString:btn.currentTitle];
}
}
if (isFull) {
NSLog(@"都有字");
NYQuestion *question = self.questions[self.index];//得到問題
//判斷是否和答案一致,
if([question.answer isEqualToString:strM]){//判斷問題和字串是否相等
//如果相等
NSLog(@"答對了");
//如果一致,設定成藍色進入下一題
[self setAnswerButtonColor:[UIColor blueColor]];
//等待0.5秒,進入下一題
[self performSelector:@selector(nextQuestion) withObject:nil afterDelay:0.5];
}else{
NSLog(@"答錯了");
//如果不一致,修改按鈕文字顏色,提示使用者
[self setAnswerButtonColor:[UIColor redColor]];
}
}else {
NSLog(@"繼續");
}
}
/**修改答題區按鈕的顏色*/
-(void)setAnswerButtonColor:(UIColor *)color
{
for (UIButton *btn in self.answerView.subviews) {
[btn setTitleColor:color forState:UIControlStateNormal];
}
}
/**在答案區找到第一個標題為空的按鈕
如果答案區按鈕都滿了就返回nil
*/
-(UIButton *) firstAnswerButton
{
// 取出按鈕標題,遍歷答題區按鈕
for (UIButton *btn in self.answerView.subviews) {
if (btn.currentTitle.length == 0) {
return btn;
}
}
return nil;
}
#pragma mark - 答題區按鈕點選方法
-(void)answerClick:(UIButton *)button
{
//如果按鈕沒有字,直接返回
if (button.currentTitle.length == 0) {
return;
}
//如果有字,清除文字,候選區按鈕顯示
//1,使用button的title去查詢候選區中對應的按鈕
UIButton *btn = [self optionButtonWithTitle:button.currentTitle isHidden:YES];
//2,顯示對應按鈕
btn.hidden = NO;
//3,清除答案區button的文字
[button setTitle:@"" forState:UIControlStateNormal];
//4,只要點選了按鈕,答題區就少了,然後就設成黑色
[self setAnswerButtonColor:[UIColor blackColor]];
}
/**遍歷備選的按鈕 如果返回與title相同 並且 hidden為YES(隱藏) 的btn*/
-(UIButton *) optionButtonWithTitle:(NSString *)title isHidden:(BOOL) isHidden
{
for (UIButton *btn in self.optionsView.subviews) {
if ([btn.currentTitle isEqualToString:title] && btn.hidden) {
return btn;
}
}
return nil;
}
#pragma mark - 提示功能
-(IBAction)tipClick
{
//1,把答題區的所有的按鈕清空
for (UIButton *btn in self.answerView.subviews) {
// [btn setTitle:@"" forState:UIControlStateNormal];
[self answerClick:btn];
}
//2,把正確答案的第一個字,設定到答題區中
//找到答案的第一個字
NYQuestion *question = self.questions[self.index];
NSString *first = [question.answer substringToIndex:1];
//取出文字對應的候選按鈕
// for (UIButton *btn in self.optionsView.subviews) {
// if ([btn.currentTitle isEqualToString:first] && !btn.hidden) {
// [self optionClick:btn];//找到正確答案後按一下,然後自動就上答案區了
// break;
// }
// }
UIButton * btn = [self optionButtonWithTitle:first isHidden:NO];
[self optionClick:btn];
//提示的時候需要扣分
[self changeScore:-1000];
}
#pragma mark - 分數處理
-(void)changeScore:(int) score
{
//取出當前分數
int currentScore = self.scoreButton.currentTitle.intValue;
//使用score調整分數
currentScore += score;
//重新設定分數
[self.scoreButton setTitle:[NSString stringWithFormat:@"%d",currentScore ] forState:UIControlStateNormal];
}
@end
字典的程式碼
//
// NYQuestion.h
// 01-超級猜圖遊戲
//
// Created by apple on 15-3-21.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NYQuestion : NSObject
@property (nonatomic, copy) NSString *answer;
@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, strong) NSArray *options;
-(instancetype)initWithDict:(NSDictionary *)dict;
+(instancetype)questionWithDick:(NSDictionary *)dict;
/**
*返回所有題目陣列
*/
+(NSArray *)questions;
/**打亂備選文字的陣列*/
-(void)randomOptions;
@end
//
// NYQuestion.m
// 01-超級猜圖遊戲
//
// Created by apple on 15-3-21.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYQuestion.h"
@implementation NYQuestion
//相當於構造方法(用NSDictionary 字典構造)
-(instancetype)initWithDict:(NSDictionary *)dict
{
self = [super init];
if (self) {
[self setValuesForKeysWithDictionary:dict];
//讓模型打亂資料
[self randomOptions];
}
return self;
}
//提供類方法來呼叫initWithDict:dict方法,方便呼叫
+(instancetype)questionWithDick:(NSDictionary *)dict
{
return [[self alloc]initWithDict:dict];
}
/**
*返回所有題目陣列
*/
+(NSArray *)questions
{
//array中是檔案中的字典陣列
NSArray *array = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"questions.plist" ofType:nil]];
//初始化一個可以新增的陣列為了存放模型資料
NSMutableArray *arrayM = [NSMutableArray array];
for (NSDictionary *dict in array) {
[arrayM addObject:[self questionWithDick:dict]];
}
return arrayM;
}
-(void)randomOptions
{
//對options做亂序
self.options = [self.options sortedArrayUsingComparator:^NSComparisonResult(NSString *str1, NSString *str2) {
int seed = arc4random_uniform(2);
if (seed) {
return [str1 compare:str2];
}else
{
return [str2 compare:str1];
}
}];
}
@end
上面是全部程式碼,
學習過程首先自己拖介面上半部分,需求裡面寫的很清楚了,
註釋當中寫的相當清楚,每個mark都間隔出來了部分的功能,因為是學習寫的程式碼,所以註釋寫的很全,應該可以看懂。
完成佈局後就開始寫模型字典了。這裡就用到了mvc設計模式,當然這個遊戲中主要用到的時mc view方面並不是那麼多,主要是對設計邏輯的學習與體現。
然後就按照需求來設計學習編寫啦。