舒尔特表游戏.
一、舒尔特表简介
舒尔特表可以通过动态的练习锻炼视神经末梢。心理学上用此表来研究和发展心理感知的速度,其中包括视觉定向搜索运动的速度。
培养注意力集中、分配、控制能力;拓展视幅;加快视频;提高视觉的稳定性、辨别力、定向搜索能力。
练习的时间越长,看表所需的时间会越短。随着练习的深入,眼球的末梢视觉能力提高, 不仅初学者可以有效地拓展视幅,加快阅
读 节奏,锻炼眼睛快速认读;而且对于进入提高阶 段之后,同时拓展纵横视幅,达到一目十行、一目一页非常有效。
二、 舒尔特表游戏说明
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