IOS学习日志(Controller)1.3
来源:互联网 发布:全能抽奖软件注册码 编辑:程序博客网 时间:2024/06/05 05:36
1.MVC设计模式,MVVM
预备:设计模式
M:Model 模型 数据模型(存数据的结构) 业务模型(多线程、文件存储、网络数据解析等等) V:View 视图 展示数据C:Controller 控制器 在M和C之间控制数据的传递
2.体会MVC的练习:纸牌对对碰
阶段一:
搭建出界面,并且实现,在界面中点击时,能够知道点击的牌的位置
阶段二:
1.分几个类,存哪些数据
第一个类:每一张纸牌的数据Card(数据模型)
第二个类:扑克牌类(数据模型)
第三个类:游戏规则类(Game)(业务模型)
2.随机出12张牌,将12张牌的数据显示到界面上
定义Card类
定义Poker类
定义Game类
在控制器中,创建了poker和game的实例
更新界面方法中:
遍历按钮,找到按钮对应的纸牌,将纸牌的花色+大小
阶段三:
核心业务:点击后对纸牌的比对
阶段四:
统计分数:
涉及到的其他知识点:
a.懒加载lazy loading
某一个存储数据的空间,不要一早就分出来,直到不得不使用这块空间存储数据时再分配,什么时候第一次用这块空间了,再分配,尽量晚分配
b,随机整数
使用C语言的一个函数arc4random()
随机的范围:[0~4个字节表示的最大整数]
content in GameViewController.m
#import "GameViewController.h"#import "Card.h"#import "Poker.h"#import "Game.h"@interface GameViewController ()@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *allButtons;//增加两个属性,用于模拟游戏,和使用到扑克@property(nonatomic,strong)Poker *poker;@property(nonatomic,strong)Game *game;@property (weak, nonatomic) IBOutlet UILabel *scoreLabel;@end@implementation GameViewController- (void)viewDidLoad { [super viewDidLoad]; //1.初始化全新的扑克牌 self.poker=[[Poker alloc]init]; //2.创建游戏 self.game=[[Game alloc]initWithPoker:self.poker forCardCount:self.allButtons.count]; //3.更新界面 [self updateView]; // Do any additional setup after loading the view from its nib.}- (IBAction)clickButton:(UIButton *)sender { //1.查找该按钮对应的下标 NSInteger index=[self.allButtons indexOfObject:sender];//所点的那个位置下标// 2.通知游戏类,本次点击的纸牌的位置 [self.game tapCardAtIndex:index]; //3.根据game改完的数据,刷新界面 [self updateView];}//更新界面-(void)updateView{ //更新分数的显示 self.scoreLabel.text=[NSString stringWithFormat:@"分数:%ld",self.game.score]; //遍历所有按钮,按照按钮的下标,去游戏中找到下标对应的纸牌,然后将纸牌信息显示到按钮上 for (int i=0; i<self.allButtons.count; i++) { //根据下标找到该位置的纸牌 Card *card=self.game.allRandomCards[i]; //根据下标找到该位置的按钮 UIButton *button=self.allButtons[i]; //根据纸牌的状态,决定按钮上显示的背景图 [button setBackgroundImage:[UIImage imageNamed:[self imageNameForCard:card]] forState:UIControlStateNormal]; //根据纸牌的状态,决定按钮上显示的文字 [button setTitle:[self titleForCard:card] forState:UIControlStateNormal]; //根据纸牌的是否被匹配,决定按钮是否可用 //card matched YES NO //button enabled NO YES button.enabled=!card.isMatched; }}//依据传入的纸牌对象,返回要加载的图片名称-(NSString*)imageNameForCard:(Card*)card{ return card.isFaceUp?@"cardfront.png":@"cardback.png";}//根据传入的纸牌对象,返回要显示的按钮的文字信息-(NSString*)titleForCard:(Card*)card{ return card.isFaceUp?card.cardInfo:@"";}@end
content in Card.h
#import <Foundation/Foundation.h>/* 类型:纸牌类 属性: 花色:suit 大小:rank 是否面儿朝上:faceUp 是否已匹配:matched */@interface Card : NSObject@property (nonatomic,strong)NSString *suit;//strong和copy的区别@property (nonatomic,strong)NSString *rank;@property (nonatomic,getter=isFaceUp)BOOL faceUp;@property (nonatomic,getter=isMatched)BOOL matched;//增加一个属性,用于存储牌面信息(花色+大小)//增加此属性的目的,是为了方便外接访问花色+大小的信息@property (nonatomic,strong,readonly)NSString *cardInfo;/*自定义的构造方法,创建的同时,指定好花色和大小*/-(instancetype)initWithSuit:(NSString*)suit andRank:(NSString*)rank;+(NSArray *)allsuits;//类方法存储花色的数组+(NSArray *)allranks;//用来返回合法的大小@end
content in Card.m
#import "Card.h"@implementation Card-(instancetype)initWithSuit:(NSString *)suit andRank:(NSString *)rank{ self=[super init]; if (self) { self.suit=suit;//_suit代表直接访问变量,self.suit会多走一次setter方法 self.rank=rank; self.faceUp=NO; self.matched=NO; } return self;}/*目标:在给suit或rank赋值时,数据非法,则不能存入属性中 措施:重写属性的setter方法,先判断数据是否合法,再存入到实例变量中 通用规则:如何符合“一给xxx属性赋值,就要做xxx”这样的句式,那么就可以通过重写setter方法,捕获赋值这个时机,实现操作 */-(void)setSuit:(NSString *)suit{ if ([[Card allsuits] containsObject:suit]) { _suit=suit; }}-(void)setRank:(NSString *)rank{ if ([[Card allranks] containsObject:rank]) { _rank=rank; }}//为cardInfo属性说明返回信息是什么-(NSString *)cardInfo{ return [self.suit stringByAppendingString:self.rank];}//返回所有合法的花色+(NSArray *)allsuits{ return @[@"♠️",@"♥️",@"♣️",@"♦️"];}//返回所有合法的大小+(NSArray *)allranks{ return @[@"A",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10",@"J",@"Q",@"K"];}@end
content in Poker.h
#import <Foundation/Foundation.h>/* Poker:一副扑克牌类 作用:能够存储52张标准的card对象即可 属性:NSMutableArray allCards */@interface Poker : NSObject@property (nonatomic,strong) NSMutableArray* allCards;@end
content in Poker.m
#import "Poker.h"#import "Card.h"@implementation Poker//重写系统提供的allCards属性的getter方法,懒加载的应用//目的什么时候用到了数组属性才为数组分配空间-(NSMutableArray *)allCards{ // !_allCards 等价于 _allCards==nil if (!_allCards) { _allCards=[NSMutableArray array]; } return _allCards;}//一创建扑克实例时,就应该立即准备好52张纸牌对象//放入到allCards数组中-(instancetype)init{ self=[super init]; //self 等价于self!=nil if (self) { NSArray *allSuits=[Card allsuits]; NSArray *allRanks=[Card allranks]; for (NSString *suit in allSuits) { for (NSString *rank in allRanks) { Card *card=[[Card alloc]initWithSuit:suit andRank:rank]; [self.allCards addObject:card]; } } } return self;}@end
content in Game.h
#import <Foundation/Foundation.h>#import "Poker.h"/* Game:游戏类 作用: 1.在游戏开始时,能够依靠指定的扑克牌,随机抽取出所需的纸牌 2.在点击某张牌时,根据业务原则进行比对 属性: 1.为了存储随机出来的纸牌,有一个可变数组 allRandomCards */@interface Game : NSObject//记录分数的属性@property(nonatomic)NSInteger score;@property(nonatomic,strong)NSMutableArray * allRandomCards;//依靠传入的poker和count,决定当游戏开始时在哪个对象中,抽取多少张牌-(instancetype)initWithPoker:(Poker *)poker forCardCount:(NSInteger)count;//@property(nonatomic,strong)Poker *poker;//核心业务逻辑:根据传入的点击位置,进行比对-(void)tapCardAtIndex:(NSInteger)index;@end
content in Game.m
#import "Game.h"#import "Card.h"@implementation Game//重写allRandomCards的getter方法,保证在使用数组时空间存在-(NSMutableArray *)allRandomCards{ if (!_allRandomCards) { _allRandomCards=[NSMutableArray array]; } return _allRandomCards;}/* 参数1:poker 要抽取的纸牌的 参数2:cardsCount 要抽取的纸牌的个数 */-(instancetype)initWithPoker:(Poker *)poker forCardCount:(NSInteger)count{ self=[super init]; if (self) { //随机抽取纸牌 for (int i=0; i<count; i++) { //1.先随机出一个下标 NSInteger index=arc4random()%poker.allCards.count; //2.按照这个下标去poker中找到这个位置的纸牌 Card *card=poker.allCards[index]; //将随机到的这张牌从原油的poker中移除 [poker.allCards removeObjectAtIndex:index]; //3.将这张牌放入到用于保存随机牌的allRandomCards数组中 [self.allRandomCards addObject:card]; } } return self;}/* 1.根据点击的位置,找到对应的纸牌对象 2.如果这张牌,面朝上,那么就翻下来 3.否则 a.先将牌翻成面朝上 b.本张牌与剩下的,已经翻上来,且,没有被匹配的进行比对 1.如果花色相同 两张牌修改为已经被匹配 2.否则,如果,大小相同 两张牌修改为已经被匹配 3.否则 将被比较的那张牌翻成背朝上 */-(void)tapCardAtIndex:(NSInteger)index{ Card *chooseCard=self.allRandomCards[index]; if (chooseCard.isFaceUp) { chooseCard.faceUp=NO; } else{ chooseCard.faceUp=YES; for (int i=0; i<self.allRandomCards.count; i++) { if(i!=index) { Card *otherCard=self.allRandomCards[i]; if (otherCard.isFaceUp&&!otherCard.isMatched) { if ([chooseCard.suit isEqualToString:otherCard.suit]) { chooseCard.matched=YES; otherCard.matched=YES; //花色相同计1分 self.score+=1; } else if([chooseCard.rank isEqualToString:otherCard.rank]) { chooseCard.matched=YES; otherCard.matched=YES; //大小相同计4分 self.score+=4; } else { otherCard.faceUp=NO; } } } } }}@end
0 0
- IOS学习日志(Controller)1.3
- IOS学习日志(Controller)1.1
- IOS学习日志(Controller)1.2
- IOS学习日志(Controller)1.4
- IOS学习日志(Controller)1.5
- IOS学习日志(Controller)1.6
- IOS学习日志(Controller)1.7
- IOS学习日志(Controller)1.8
- IOS学习日志(Controller)1.9
- IOS学习日志(OC)1.3
- iOS学习- 05 Navigation Controller
- iOS 5 Storyboard 学习之 Tabbar Controller,Navigation Controller (1)
- iOS 5 Storyboard 学习之 Tabbar Controller,Navigation Controller (3)
- iOS学习日志
- IOS学习——Navigation Controller
- iOS学习- 05 Tab Bar Controller
- 日志AOP拦截Controller
- controller日志AOP处理
- SparkSQL On Yarn with Hive,操作和访问Hive表
- 正则表达式 BY deerchao
- Xcode Archive打包时不报错,但是buildFailed原因以及解决方案
- copy使用...自定义类实现copy操作...
- UVa 100 &&HDU 1032 The 3n + 1 problem【暴力统计】
- IOS学习日志(Controller)1.3
- ScrollView嵌套ListView的解决方案
- 颜色、光照、材料属性(openGL)
- POJ 3468 A Simple Problem with Integers(线段树|区间加减&&区间求和)
- 在引用第三方库MXPrallaxHeader时的一些经历(做个记录)
- PAT甲级1002. A+B for Polynomials (25)
- linux常用指令集
- 在Yarn上运行spark-shell和spark-sql命令行
- java 范型