猫猫学IOS(六)UI之iOS热门游戏_超级猜图

猫猫分享,必须精品
素材地址:http://blog.csdn.net/u013357243/article/details/44539069
原文地址:http://blog.csdn.net/u013357243/article/details/44538955

先看效果图

超级猜图
超级猜图
超级猜图
超级猜图
超级猜图
超级猜图

思路

需求分析

1,搭建界面
1》上半部分,固定的,用Storyboard直接连线(OK)
2》下半部分,根据题目的变化,不断变化和调整,用代码方式实现比较合适(OK)
*备选按钮区域(OK)
*答案按钮区域(OK)

2,编写代码
1》大图,小图的切换(OK)
2》下一题(OK)
3》备选按钮的点击,让文字进入答案区(Ok)
4》判断对错胜负(OK)
*胜利:进入下一题(OK)
*失败:提示用户重新选择(OK)
5》答案按钮的点击(OK)
把答案区的文字回复到备选区域(Ok)

代码

/*
ps:猫猫的文章竟然被好多地方转载了,受宠若惊啊,不过转的时候请转的全一点,别丢下素材什么的,不标注转载也没事,大家一起努力学习猫猫就很高兴了,如果需要学习资料视频素材等等的可以加猫猫QQ:1764541256 或则微信znycat  
让我们一起努力学习吧。
目前将这个游戏的功能都实现了,虽然部分代码抽取的不是那么完美
素材地址:http://blog.csdn.net/u013357243/article/details/44539069
原文地址:http://blog.csdn.net/u013357243/article/details/44538955

九宫格学习: 猫猫学IOS(五)UI之360等下载管理器九宫格UI
http://blog.csdn.net/u013357243/article/details/44521437
*/

//


//  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

上面是全部代码,
学习过程首先自己拖界面上半部分,需求里面写的很清楚了,
然后代码实现下面部分,基本是一个九宫格的布局,猫猫的上一篇里面写了类似哪那样下载功能的用代码实现过程,这里就不啰嗦了。
九宫格学习: 猫猫学IOS(五)UI之360等下载管理器九宫格UI
http://blog.csdn.net/u013357243/article/details/44521437

注释当中写的相当清楚,每个mark都间隔出来了部分的功能,因为是学习写的代码,所以注释写的很全,应该可以看懂。

完成布局后就开始写模型字典了。这里就用到了mvc设计模式,当然这个游戏中主要用到的时mc view方面并不是那么多,主要是对设计逻辑的学习与体现。

然后就按照需求来设计学习编写啦。

原文地址:https://www.cnblogs.com/znycat/p/4375208.html