lecture 3的slides和老师讲的实际稍有区别
实际上lecture 2结束的时候做了一个flip card的app,但是实际上我们之前写的四个类都没有用到,到了lecture 3,我也开始犯迷糊,有点晕了
其实还是因为基础的原因,没有写多个类的经验,没有做稍大项目的经验
然后我又觉得这一切太复杂,需要梳理一下各个类之间的关系
用Python写了一个小的Parse Header的脚本(Github上找了一个稍微改了改,连正则表达式都难得查,真是半罐水和到处飘)
让我来理一理
Card
objectivec
通用类,继承自NSObject +------------Class Name--------------+ Card : NSObject +------------Public Methods----------+ -(int)match :(NSArray *)otherCards; +---------Public Properties----------+ @property (strong, nonatomic) NSString *contents; @property (nonatomic, getter = isChosen) BOOL chosen; @property (nonatomic, getter = isMatched) BOOL matched; +------------------------------------+
Deck
objectivec
通用类,import了Card,因为Deck由Card组成 +-------------Class Name--------------+ Deck : NSObject +------------Public Methods----------+ -(void)addCard:(Card *)card atTop:(BOOL)atTop; -(void)addCard:(Card *)card; -(Card *)drawRandomCard; +---------Public Properties----------+
PlayingCard
objectivec
继承自Card,重写了match方法,重写了contents getter +-----------------------------------+ PlayingCard : Card +------------Public Methods----------+ + (NSArray *)validSuits; + (NSArray *)rankStrings; + (NSUInteger)maxRank; +---------Public Properties----------+ @property (strong, nonatomic) NSString *suit; @property (nonatomic) NSUInteger rank;
PlayingCardDeck
objectivec
继承自Deck,所以继承了一干方法 -(instancetype)init的特殊方法来init 要玩的纸牌 +-----------------------------------+ PlayingCardDeck : Deck +------------Public Methods----------+ +---------Public Properties----------+
这四个类,都是Model
这一讲首先先解答了lecture 2的答案,制作也是精巧啊~~
看slides也会觉得很有意思,比如直接复制粘贴的按钮都会有drawRandomCard的效果...
然而还是来看一下最终要制作游戏的步骤吧:
新建了一个Model,也就是这个model来控制游戏
objectivec
CardMatchingGame是来控制游戏的,import了Deck和Card 这是好事,因为import的是通用的类别 +-----------------------------------+ CardMatchingGame : NSObject +------------Public Methods----------+ -(instancetype)initWithCardCount :(NSUInteger)count -(void)chooseCardAtIndex:(NSUInteger)index; -(Card *)cardAtIndex:(NSUInteger)index; +---------Public Properties----------+ @property (nonatomic,readonly)NSInteger score;
这个method -(instancetype)initWithCardCount :(NSUInteger)count来装载Card
实际上我觉得 -(void)chooseCardAtIndex:(NSUInteger)index 虽说不那么难理解,但是觉得写出来还蛮难的
注意readonly property仅仅是为了防止被外部修改score
内部可以重新将score定义为readwrite
最终的最终,我们终于可以将这五个类统治/使用起来
objectivec
#import "CardGameViewController.h" #import "PlayingCardDeck.h" #import "Deck.h" #import "CardMatchingGame.h" @interface CardGameViewController () @property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons; @property (weak, nonatomic) IBOutlet UILabel *scoreLabel; @property (strong,nonatomic) CardMatchingGame *game; @end @implementation CardGameViewController -(CardMatchingGame *)game{ if (!_game) _game = [[CardMatchingGame alloc]initWithCardCount:[self.cardButtons count] usingDeck:[self createDeck]]; return _game; } -(Deck *)createDeck{ return [[PlayingCardDeck alloc]init]; } - (IBAction)touchCardButton:(UIButton *)sender { int chosenButtonIndex = [self.cardButtons indexOfObject:sender]; [self.game chooseCardAtIndex:chosenButtonIndex]; [self updateUI]; } - (void)updateUI{ for (UIButton *cardButton in self.cardButtons) { int cardButtonIndex = [self.cardButtons indexOfObject:cardButton]; Card *card = [self.game cardAtIndex:cardButtonIndex]; [cardButton setTitle:[self titleForCard:card] forState:UIControlStateNormal]; [cardButton setBackgroundImage:[self backgroundImageForCard:card] forState:UIControlStateNormal]; cardButton.enabled = !card.isMatched; self.scoreLabel.text = [NSString stringWithFormat:@"Score : %d",self.game.score]; } } -(NSString *)titleForCard:(Card *)card{ return card.isChosen ? card.contents : @""; } -(UIImage *)backgroundImageForCard:(Card *)card{ return [UIImage imageNamed:card.isChosen ? @"cardfront" : @"cardback"]; } @end
代码写的非常非常漂亮,对我来说,觉得这是比较难以想象的。T_T
有很多精巧很有趣的地方,比如IBOutletCollection,写一个createDeck方法
UpdateUI放出来感觉这个可能可以想到
但是简洁的setTitle和background也是...
总之,太过精巧以至于很难结构....
望着这样的代码流口水.....
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。