iOS学习笔记-018.舒尔特表游戏

本文介绍舒尔特表游戏的实现方法,包括游戏的作用、规则及iOS平台上的具体实现步骤,如计时器调用、随机数生成、按钮布局等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

舒尔特表游戏.


一、舒尔特表简介

  1. 舒尔特表可以通过动态的练习锻炼视神经末梢。心理学上用此表来研究和发展心理感知的速度,其中包括视觉定向搜索运动的速度。

  2. 培养注意力集中、分配、控制能力;拓展视幅;加快视频;提高视觉的稳定性、辨别力、定向搜索能力。

  3. 练习的时间越长,看表所需的时间会越短。随着练习的深入,眼球的末梢视觉能力提高, 不仅初学者可以有效地拓展视幅,加快阅

读 节奏,锻炼眼睛快速认读;而且对于进入提高阶 段之后,同时拓展纵横视幅,达到一目十行、一目一页非常有效。


二、 舒尔特表游戏说明

1. 说明

是全世界范围内最简单、最有效也是最科学的注意力训练方法。

2. 作用

1.培养注意力集中、分类、控制能力

2.拓展视幅、加快视频

3.提高视觉稳定性、辨别力以及定向搜索能力

3. 规则

从小到大点击数字

4. 评测

时间越短,注意力水平越高!

5.图示

这里写图片描述


三、跳到下一界面

这里写图片描述

这里写图片描述


四、获取目标ViewController

// 是ViewController内置的方法
// 所有在StoryBoard中的连线在推出新的视图控制器[之前]都会调用这个方法
// 可以通过segue的一个属性获取到目标视图控制器
-(void)prepareForSegue:(nonnull UIStoryboardSegue *)segue sender:(nullable id)sender{
    GameViewController *segueViewCon = [segue destinationViewController];
}

五、返回到主界面

/**返回到主界面*/
- (IBAction)returnToMain:(id)sender {
    // 关闭当前视图控制器。
    // 因为当前视图控制器是被上级视图控制器推出来的
    // 因此,关闭了当前这个视图控制器,原来的就露出来了
    // 提醒:关闭之后,当前视图控制器会被释放
    // 再次点击上级视图控制器的按钮,本视图控制器的ViewDidLoad方法仍然会执行。
    [self dismissViewControllerAnimated:YES completion:nil];
}

六、计时(时钟的调用)

    // 设置并启动时钟
    // 第一个参数:多长时间会触发一次,以秒为单位
    // 第二个参数:如果看到函数的参数有target,一般情况下,都用self
    // 第三个参数:SEL,需要调用其他的方法,就是每次时钟被触发的时候,去执行的方法
    // 最多可以带一个参数,就是时钟本身
    // 第四个参数,暂时不用考虑,设置成nil
    // 第五个参数:是否重复,通常会设置YES
    _gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];

   // 记录一下游戏开始时间,以当前系统的时间作为游戏开始时间
    _gameStartTime = [NSDate date];

    // 在此处设置游戏计时器标签的内容,提示玩家当前过了多少秒
    // fireDate 是时钟的当前触发时间
    NSInteger deltaTime = [timer.fireDate timeIntervalSinceDate:_gameStartTime];

    //2.3.1 关闭游戏时钟
    [_gameTimer invalidate];

七、创建存储随机数不重复的数组

/**创建存储随机数的数组*/
-(NSArray*)createRandomArray{
    //1.判断控件个数是否为nil或者为0,设置默认为 3
    if(!_cols || 0==_cols){
        _cols = DEFUALT;
    }

    //2.创建 _cols * _cols 的数组
    NSMutableArray* arrayM = [NSMutableArray array];
    NSInteger count = _cols * _cols;
    for (NSInteger i=1; i<=count; i++) {
        [arrayM addObject:@(i)];
    }

    //3.使用随机数打乱数组
    // 打乱数组的顺序
    // 思路:需要使用到随机数,不能重复
    // 1,2,3,4,5,6,7,8,9
    // 先随机出来一个位置的数字0~8 假设是5,用位置5的数字与位置0的数字进行交换
    // 6,2,3,4,5,1,7,8,9
    // 再随机出来一个位置的数字1~8 假设是3,用位置3的数字与位置1的数字进行交换
    // 6,4,3,2,5,1,7,8,9
    // 在随机出来一个位置的数字2~8 假设是8,用位置8的数字与位置2的数字进行交换
    // 6,4,9,2,5,1,7,8,3
    // ...... 以此类推,就可以得到一个随机顺序的数组
    NSInteger see;
    for (NSInteger i=0; i<count; i++) {
        see = arc4random_uniform(count-1-i);
        [arrayM exchangeObjectAtIndex:i withObjectAtIndex:see];
    }
    NSLog(@"%@",arrayM);
    return arrayM;
}

八、动态创建按钮布局

 //5.更加计算的位置,动态创建控件
    for (NSInteger i=0; i<_cols; i++) {
        for (NSInteger j=0; j<_cols; j++) {
            NSInteger startX = MARGIN_WIDTH + (MARGIN_WIDTH+width)*j;
            NSInteger startY = MARGIN_WIDTH + (MARGIN_WIDTH+width)*i;
            UIButton * button = [[UIButton alloc]initWithFrame:CGRectMake(startX, startY, width, width)];

            //5.给控件设置值和一些属性]
            //5.1 文字
            [button setTitle:[NSString stringWithFormat:@"%@",arrayList[index++]] forState:UIControlStateNormal];
            //5.2 字体颜色
            [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            //5.3 背景颜色
            [button setBackgroundColor:[UIColor grayColor]];

            //6。给控件点击事件添加代理
            [button addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside];

            //.把控件添加到myView中
            [_myVIew addSubview:button];
        }
    }

九、UIAlertView 的代理方法

1.遵从< UIAlertViewDelegate > 协议;
2.代理方法

-(void)alertView:(UIAlertView*)alerView clickedButtonAtIndex:(NSInteger)clickIndex{
    NSLog(@"点击了%ld",clickIndex);
    [self returnToMain:nil];
}
 UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];;
  [alert show];

十、协议代理

1. 图示

这里写图片描述

2.定义协议和代理

// 定义协议
@protocol GameViewControllerDelegate <NSObject>

// 游戏完成
- (void)gameViewDidDone:(NSTimeInterval)gameTime;

@end

@interface GameViewController : UIViewController <UIAlertViewDelegate>

// 定义代理
@property (weak, nonatomic) id<GameViewControllerDelegate> delegate;

3.定义协议和代理

         //2.5 // 委托代理执行方法,如果没有设置代理,这条指令不生效,但是也不会报错
        [_delegate gameViewDidDone:_usedTime.text];

4.ViewController遵从游戏视图控制器协议

#import <UIKit/UIKit.h>
#import "GameViewController.h"
// 遵从游戏视图代理
@interface ViewController : UIViewController <GameViewControllerDelegate>
@end

5.声明作为游戏视图控制器的代理

// 是ViewController内置的方法
// 所有在StoryBoard中的连线在推出新的视图控制器[之前]都会调用这个方法
// 可以通过segue的一个属性获取到目标视图控制器
-(void)prepareForSegue:(nonnull UIStoryboardSegue *)segue sender:(nullable id)sender{
    GameViewController *segueViewCon = [segue destinationViewController];
    [segueViewCon setCols:_selectSizi];

    // 申请成为游戏视图的代理,设置后,游戏视图控制器的协议方法就会在当前视图控制器中执行
    [segueViewCon setDelegate:self];

}

提示:
1.Storyboard中用连线打开视图控制器都会调用prepareForSegue方法
2.用segue的destinationViewController属性可以获得目标控制器


十一、代码示例

1. ViewController.h

//
//  ViewController.h
//  03_UIView06_舒尔特表
//
//  Created by 杞文明 on 15/12/24.
//  Copyright © 2015年 杞文明. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "GameViewController.h"
// 遵从游戏视图代理
@interface ViewController : UIViewController <GameViewControllerDelegate>

/**最高记录*/
@property (weak, nonatomic) IBOutlet UILabel *recordLb;

@end

2. ViewController.m

//
//  ViewController.m
//  03_UIView06_舒尔特表
//
//  Created by 杞文明 on 15/12/24.
//  Copyright © 2015年 杞文明. All rights reserved.
//
#import "ViewController.h"

@interface ViewController (){

    //记住选择的是多少个数
    NSInteger _selectSizi;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

// 是ViewController内置的方法
// 所有在StoryBoard中的连线在推出新的视图控制器[之前]都会调用这个方法
// 可以通过segue的一个属性获取到目标视图控制器
-(void)prepareForSegue:(nonnull UIStoryboardSegue *)segue sender:(nullable id)sender{
    GameViewController *segueViewCon = [segue destinationViewController];
    [segueViewCon setCols:_selectSizi];

    // 申请成为游戏视图的代理,设置后,游戏视图控制器的协议方法就会在当前视图控制器中执行
    [segueViewCon setDelegate:self];

}

/**选择多少的个数*/
- (IBAction)selectCount:(UIButton*)button {
    //记住选中的个数
    _selectSizi =  button.tag;
    //设置背景颜色
    button.backgroundColor = [UIColor redColor];
}

/**设置时间*/
- (void)gameViewDidDone:(NSString *)timeString{
    _recordLb.text = [NSString stringWithFormat:@"最高记录:%@",timeString];
    NSLog([NSString stringWithFormat:@"最高记录:%@",timeString]);
}

@end

3. GameViewController.h

//
//  GameViewController.h
//  03_UIView06_舒尔特表
//
//  Created by 杞文明 on 15/12/24.
//  Copyright © 2015年 杞文明. All rights reserved.
//
#import <UIKit/UIKit.h>

// 1. 定义协议
// 协议名称通常是:委托方类名+Deleage
@protocol GameViewControllerDelegate <NSObject>
// 游戏完成
- (void)gameViewDidDone:(NSString *)timeString;
@end

@interface GameViewController : UIViewController
/**定义代理*/
@property(weak,nonatomic)id<GameViewControllerDelegate> delegate;
/**显示控件的view*/
@property (weak, nonatomic) IBOutlet UIView *myVIew;
/**控件的行数   控件个数为 _cols * cols*/
@property NSInteger cols;
@property NSInteger answerCount;
/**计时*/
@property (weak, nonatomic) IBOutlet UILabel *usedTime;

@end

4. GameViewController.m

//
//  GameViewController.m
//  03_UIView06_舒尔特表
//
//  Created by 杞文明 on 15/12/24.
//  Copyright © 2015年 杞文明. All rights reserved.
//

#import "GameViewController.h"
#define MARGIN_WIDTH 3
#define DEFUALT 2

@interface GameViewController ()
{
    // 游戏开始的时间
    NSDate      *_gameStartTime;
    // 游戏时钟
    NSTimer     *_gameTimer;
    NSString* _message;
}
@end

@implementation GameViewController

/**加载*/
-(void)viewDidLoad{
    [super viewDidLoad];
    //加载控件
    [self createViews];
    //计时开始
    [self startTimer];
}

/**返回到主界面*/
- (IBAction)returnToMain:(id)sender {
    // 关闭当前视图控制器。
    // 因为当前视图控制器是被上级视图控制器推出来的
    // 因此,关闭了当前这个视图控制器,原来的就露出来了
    // 提醒:关闭之后,当前视图控制器会被释放
    // 再次点击上级视图控制器的按钮,本视图控制器的ViewDidLoad方法仍然会执行。
    [self dismissViewControllerAnimated:YES completion:nil];
}


/**开始计时*/
-(void)startTimer{
    //设置时钟
    // 设置并启动时钟
    // 第一个参数:多长时间会触发一次,以秒为单位
    // 第二个参数:如果看到函数的参数有target,一般情况下,都用self
    // 第三个参数:SEL,需要调用其他的方法,就是每次时钟被触发的时候,去执行的方法
    // 最多可以带一个参数,就是时钟本身
    // 第四个参数,暂时不用考虑,设置成nil
    // 第五个参数:是否重复,通常会设置YES
    _gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];
    // 记录一下游戏开始时间,以当前系统的时间作为游戏开始时间
    _gameStartTime = [NSDate date];
}

/**计时的处理*/
-(void)updateTime:(NSTimer*)timer{
    // 在此处设置游戏计时器标签的内容,提示玩家当前过了多少秒
    // fireDate 是时钟的当前触发时间
    NSInteger deltaTime = [timer.fireDate timeIntervalSinceDate:_gameStartTime];
    // 设置时间的字符串 00:00 mm:ss
    NSString *text = [NSString stringWithFormat:@"%02d:%02d", deltaTime / 60, deltaTime % 60];

    // 设置计时器标签文字
    [_usedTime setText:text];

    NSLog(@"过了一秒 %ld", deltaTime);
}

/**创建存储随机数的数组*/
-(NSArray*)createRandomArray{
    //1.判断控件个数是否为nil或者为0,设置默认为 3
    if(!_cols || 0==_cols){
        _cols = DEFUALT;
    }

    //2.创建 _cols * _cols 的数组
    NSMutableArray* arrayM = [NSMutableArray array];
    NSInteger count = _cols * _cols;
    for (NSInteger i=1; i<=count; i++) {
        [arrayM addObject:@(i)];
    }

    //3.使用随机数打乱数组
    // 打乱数组的顺序
    // 思路:需要使用到随机数,不能重复
    // 1,2,3,4,5,6,7,8,9
    // 先随机出来一个位置的数字0~8 假设是5,用位置5的数字与位置0的数字进行交换
    // 6,2,3,4,5,1,7,8,9
    // 再随机出来一个位置的数字1~8 假设是3,用位置3的数字与位置1的数字进行交换
    // 6,4,3,2,5,1,7,8,9
    // 在随机出来一个位置的数字2~8 假设是8,用位置8的数字与位置2的数字进行交换
    // 6,4,9,2,5,1,7,8,3
    // ...... 以此类推,就可以得到一个随机顺序的数组
    NSInteger see;
    for (NSInteger i=0; i<count; i++) {
        see = arc4random_uniform(count-1-i);
        [arrayM exchangeObjectAtIndex:i withObjectAtIndex:see];
    }
    NSLog(@"%@",arrayM);
    return arrayM;
}

/**创建控件 更加传递过来的个数,来生成对应的控件数*/
-(void)createViews{
    //1.判断控件个数是否为nil或者为0,设置默认为 3
    if(!_cols || 0==_cols){
        _cols = DEFUALT;
    }

    //2.控件之间的间隔是固定的为 MARGIN_WIDTH
    //3.根据控件的个数,和间隔来计算每个控件的宽度
    NSInteger width = (self.view.bounds.size.width - (_cols +1 )*MARGIN_WIDTH)/_cols;

    //4.获取数组
    NSArray *arrayList = [self createRandomArray];

    NSInteger index = 0;
    //5.更加计算的位置,动态创建控件
    for (NSInteger i=0; i<_cols; i++) {
        for (NSInteger j=0; j<_cols; j++) {
            NSInteger startX = MARGIN_WIDTH + (MARGIN_WIDTH+width)*j;
            NSInteger startY = MARGIN_WIDTH + (MARGIN_WIDTH+width)*i;
            UIButton * button = [[UIButton alloc]initWithFrame:CGRectMake(startX, startY, width, width)];

            //5.给控件设置值和一些属性]
            //5.1 文字
            [button setTitle:[NSString stringWithFormat:@"%@",arrayList[index++]] forState:UIControlStateNormal];
            //5.2 字体颜色
            [button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
            //5.3 背景颜色
            [button setBackgroundColor:[UIColor grayColor]];

            //6。给控件点击事件添加代理
            [button addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside];

            //.把控件添加到myView中
            [_myVIew addSubview:button];
        }
    }
}

/**控件的点击事件*/
-(void)clickButton:(UIButton*)button{
    NSLog(button.titleLabel.text);
    //1.获取当前控件的 文本值转为NSInteger
    NSInteger number = [button.titleLabel.text integerValue];

    if(number == _answerCount+1){
        //2.如果个值比上一次的值大1,那么说明正确
        //2.1 当前控件改为 绿色
        [button setBackgroundColor:[UIColor greenColor]];
        //2.2 当前控件不可用
        [button setEnabled:NO];
        //2.3 判断这个值是否是最大值,如果是,那么弹出提示框
        if(_cols*_cols == number){
          //2.3.1 关闭游戏时钟
            [_gameTimer invalidate];
          //2.3.2 从label中取出使用的时间
            NSString * message = [NSString stringWithFormat:@"你胜利拉!!,用时%@",_usedTime.text];
            UIAlertView * alert = [[UIAlertView alloc]initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];;
            [alert show];
        }
        //2.4 设置值
        _answerCount = number;
        //2.5 // 委托代理执行方法,如果没有设置代理,这条指令不生效,但是也不会报错
        [_delegate gameViewDidDone:_usedTime.text];
    }else{
        //3.如果个值比上一次的值不大1,那么说明不正确,不处理

    }
}

-(void)alertView:(UIAlertView*)alerView clickedButtonAtIndex:(NSInteger)clickIndex{
    NSLog(@"点击了%ld",clickIndex);
    [self returnToMain:nil];
}

@end

十二、示例图示

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值