• AJ学IOS(06)UI之iOS热门游戏_超级猜图


    AJ分享,必须精品

    先看效果图

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

    思路

    需求分析

    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方面并不是那么多,主要是对设计逻辑的学习与体现。

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

  • 相关阅读:
    组装树状结构文本框
    在jsp页面动态添加,删除文本框模块
    sql字段拆分 ,连表子查询获取值
    jsp页面技术总结
    C语言的基本数据类型
    如何学习一些需要算法的程序
    如何学习一门新的编程语言
    C++ 预处理器
    C++ 函数模板&类模板
    C++ 文件和流
  • 原文地址:https://www.cnblogs.com/luolianxi/p/4990390.html
Copyright © 2020-2023  润新知