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也是...
总之,太过精巧以至于很难结构....

望着这样的代码流口水.....


yuxue
47 声望2 粉丝

人家是妹子哟~✨


引用和评论

0 条评论