亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

(3/18)重學Standford_iOS7開發_Objective-C_課程筆記

2019-11-14 18:59:46
字體:
來源:轉載
供稿:網友

第三課:

本節課主要是游戲實現的demo,因此我將把課程中簡單的幾個編程技巧提取出來,重點介紹如何自己實現作業中的要求。

紙牌游戲實現:

①游戲的進行模型的一部分(理解什么是模型:Model = What your application is (but not how it is displayed) )UI無關。

②編程技巧:創建一個新類時首先考慮公共部分(API),即別人如何使用這個類,再考慮其細節實現,以此來驅動整個設計。

③關于屬性中使用NSInteger,NSUInteger,int,unsigned int只存在風格問題,只需要保持風格統一。

  關于 NSInteger 與 NSUInteger 的官方定義:

1 #if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_ipHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_642 typedef long NSInteger;3 typedef unsigned long NSUInteger;4 #else5 typedef int NSInteger;6 typedef unsigned int NSUInteger;7 #endif 

④關于屬性只讀問題:公有API中可以設置屬性為只讀,實現代碼中可以再次聲明屬性為可讀寫。屬性聲明時除非指定,否則默認為讀寫屬性。

  例如:

1 @interface example : NSObject2 3 @PRoperty (nonatomic,readonly) Objectype  number;4 5 @end
 1 @interface example() 2  3 @property (nonatomic,readwrite) Objectype number; 4  5 @end 6  7  8 @implementation NUNetWork 9 10 @end

 

⑤IBOutletConllection:多輸出口,必須為strong,因為NSArray儲存輸出口,UI由視圖指針指向,而NSArray必須指定為strong才能保持在堆中。

  如:@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;

  IBOutletCollection(UIButton)類似于IBOutlet或IBAction,編譯器會忽略。

  NSArray中的UI順序未知(不可視為拖入的順序)

⑥作業

  a.在模擬器上運行課程當前最后版本的Matchismo 

  b.添加一個button實現重新開始游戲功能(包括UI重置,牌堆重置,分數重置等)

  c.使用UISwitch或者UISegmentedControl 實現兩個card匹配與三個card匹配游戲模式之間的轉換。(注意三個card匹配成功或失敗的得分要比兩個card更顯著,在三card匹配中兩個紙牌不會產生匹配結果)(可以考慮n張牌匹配)

  d.游戲開始后,c中控制游戲的功能失效直到游戲結束或重新開始。

  e.加入lable提示游戲進行狀態(如:“Matched J♥ J♠ for 4 points.” 或“6♦ J♣ don’t match! 2 point penalty!” 或“8♦”表示只選擇一張牌還沒有進行匹配等)(不要違反MVC規則)

  f.將紙牌數量由12擴展到30(40*60)

  g.不要改變之前的代碼,可以增加公有或私有API

 

作業解答:

   最終實現效果如下圖所示

         (紙牌按鈕字體大小設置為system 15,否則原有字體不能完整顯示)

   實現過程:

    1、加入如下輸出口:

1 @property (weak, nonatomic) IBOutlet UIButton *restartButton;2 3 @property (weak, nonatomic) IBOutlet UISegmentedControl *gameModelSelectSegmented;4 5 @property (weak, nonatomic) IBOutlet UILabel *gameModelLable;6 7 @property (weak, nonatomic) IBOutlet UITextField *matchModelTextFiled;8 9 @property (weak, nonatomic) IBOutlet UILabel *gameStateLable;

 

    2、重新開始游戲功能實現

      考慮到重新啟動游戲后還未確定游戲模式,因此必須重寫不包含game屬性的初始化(game的setter會自動初始化game)

 1 - (IBAction)touchRestartButton 2  3 { 4     //恢復默認值 5     self.gameModelSelectSegmented.enabled = YES; 6     self.matchModelTextFiled.enabled = YES; 7     self.matchModelTextFiled.enabled = YES; 8     self.gameModelSelectSegmented.selectedSegmentIndex = 0; 9     self.selfDefiningModel = 2;10     self.gameModelLable.text = [NSString stringWithFormat:@"game model:%d",_selfDefiningModel];11     self.matchModelTextFiled.text = nil;12 13     self.game = nil;14     [self updateUIWithNotCreateGame];15 }16 17 - (void) updateUIWithNotCreateGame18 {19     for (UIButton *cardButton in self.cardButtons)20     {21         [cardButton setTitle:@"" forState:UIControlStateNormal];22         [cardButton setBackgroundImage:[UIImage imageNamed:@"cardBack"] forState:UIControlStateNormal];23         cardButton.enabled = YES;24     }25 26     self.gameStateLable.text = @"State";27     self.scoreLable.text = @"Score:0";28 }

    3、多種游戲模式及游戲狀態輸出的實現

      //Viewcontroller加入用戶自定義游戲模式

      @property (nonatomic) NSUInteger selfDefiningModel;

 

      選擇器初始化(此處放在了viewDidLoad方法,有點超范圍,其中選擇器的target-action即為MVC中的view同controller通信的一種方法,selfDefiningModel為用戶可自行設定的游戲模式,初始值為2)

      還可以使用UISwitch,本文為了實現多紙牌匹配因此采用了UISegmentedControll,感興趣的朋友可以試試UISwitch實現。

1 [self.gameModelSelectSegmented addTarget:self action:@selector(segmentAction:) forControlEvents:UIControlEventValueChanged];//target-action2 3 _selfDefiningModel = 2;//default model 

      選擇器響應方法(action)

 1 - (void) segmentAction:(UISegmentedControl *)Seg 2 { 3     if  (self.gameModelSelectSegmented.selectedSegmentIndex == 2)//此時為自定義輸入 4     { 5         [self assertSelfDefiningModel:self.matchModelTextFiled.text];//檢測用戶輸入 6     } 7     else 8     { 9         self.selfDefiningModel = self.gameModelSelectSegmented.selectedSegmentIndex + 2;//SegmengtdControll選擇器選項欄從0開始計數10     }11 12     self.gameModelLable.text = [NSString stringWithFormat:@"game model:%d",self.selfDefiningModel];13 } 

      自定義輸入檢測,設置為數字鍵盤,只檢測輸入范圍(由于用戶輸入的任意性,需要考慮到各種可能的輸入情況,本文為了簡便,采用了數字鍵盤,因此只需檢測數字輸入的合理性即可)

 1 - (void) assertSelfDefiningModel:(NSString *)text 2 { 3     if ([self.matchModelTextFiled.text integerValue] < 2) 4     { 5         [[[UIAlertView alloc] initWithTitle:@"Wrong" message:@"game model at least 2" delegate:nil cancelButtonTitle:@"certain" otherButtonTitles:nil, nil] show];//匹配模式至少為2 6         self.matchModelTextFiled.text = @""; 7         self.gameModelSelectSegmented.selectedSegmentIndex = 0; 8     } 9     else if ([self.matchModelTextFiled.text integerValue] > 30)10     {11         [[[UIAlertView alloc] initWithTitle:@"Wrong" message:@"beyond card max number" delegate:nil cancelButtonTitle:@"certain" otherButtonTitles:nil, nil] show];//匹配紙牌模式不能超過界面最大紙牌數量12         self.matchModelTextFiled.text = @"";13         self.gameModelSelectSegmented.selectedSegmentIndex = 0;14     }15     else16     {17         self.selfDefiningModel = [self.matchModelTextFiled.text integerValue];//自定義輸入正確時保存輸入結果18     }19 }

      UITextFiled委托(即MVC中View與Controller的另一種通訊方式,略超范圍,不理解沒有關系,暫不做要求),目的實現點擊鍵盤的return按鈕收起鍵盤

1 - (BOOL) textFieldShouldReturn:(UITextField *)textField2 {3     [textField resignFirstResponder];4     return YES;5 }

 

    4、Model部分的實現

      PlayingCard重寫match:方法

        重寫前(只實現了兩張牌的匹配):

 1 - (int)match:(NSArray *)otherCards 2 { 3     int score = 0; 4  5     // two card match 6     if ([otherCards count] == 1) 7     { 8         PlayingCard *otherCard = [otherCards firstObject]; 9         if ([self.suit isEqualToString:otherCard.suit])10         {11             score = 1;12         }13         else if (self.rank == otherCard.rank)14         {15             score = 4;16         }17     }   18     return score;19 }

 

      重寫后(適用于多紙牌匹配): 此處我簡單的實現了如下規則:任意兩張牌含有相同的屬性即認為此牌與數組中的牌匹配,讀者可以嘗試更復雜的規則,如所有的牌數字相等或者花色相等才能視為匹配等)

 1 - (int)match:(NSArray *)otherCards 2 { 3     int score = 0; 4  5     // n card match ( at least two card have same element,we think they are matched ) 6     for (PlayingCard *otherCard in otherCards) 7     { 8         if ([self.suit isEqualToString:otherCard.suit]) 9         {10             score += 1;11         }12         else if (self.rank == otherCard.rank)13         {14             score += 4;15         }16     }17 18     return score;19 }

 

      game公有API加入游戲模式及狀態屬性

        @property (nonatomic) NSUInteger gameModel;// >=2

        @property (nonatomic,readonly) NSString *gameState;

      實現文件更改權限

        @property (nonatomic,readwrite) NSString *gameState;

 

      重寫選擇紙牌方法邏輯

         此次作業最難的部分,整個游戲的邏輯核心。首先保持兩張紙牌匹配的框架不變,引入新的數組變量otherCards保存需要匹配的紙牌,先用for循環遍歷檢測紙牌狀態,若符合要求則加入otherCards,遍歷完畢再檢測數組大小是否達到游戲模式要求(注意n張牌匹配數組大小應為n-1,想想為什么?:)),若不符合則返回,若符合則開始進行匹配。數組大小小于游戲模式要求時,此處應注意紙牌狀態的保存位置與兩張牌匹配時不同,下方代碼注釋有詳細說明。匹配時的計分邏輯:在原有基礎上乘以游戲模式數量,當匹配規則越難時匹配成功得分越高。并在匹配過程中保存游戲狀態到gameState。

 1 - (void) chooseCardAtIndex:(NSUInteger)index 2 { 3     Card *card = [self cardAtIndex:index]; 4     if (!card.isMacthed) 5     { 6         if (card.isChosen) 7         { 8             card.chosen = NO; 9         }10         else11         {12             // match against other chosen cards13 14             NSMutableArray *otherCards = [NSMutableArray arrayWithCapacity:self.gameModel];15             for (Card *otherCard in self.cards)16             {17                 if (otherCard.isChosen && !otherCard.isMacthed)18                 {19                     [otherCards addObject:otherCard];20                 }21             }22 23             //不能放于for循環之前,否則會將本次被選擇的牌加入cards,不能放于下面的if之后,否則當if成立時返回,沒有將本次翻牌的cost記錄,且不能翻牌24             self.score -= COST_TO_CHOOSE * self.gameModel;25             card.chosen = YES;26 27             if ([otherCards count] < self.gameModel - 1)28             {29                 self.gameState = [NSString stringWithFormat:@"State:%@",card.contents];30                 return;31             }32             else33             {34                 int matchScore = [card match:otherCards];35                 36                 if (matchScore)37                 {38                     NSMutableString *state = [NSMutableString stringWithFormat:@"State:%@ matched",card.contents];39                     self.score += matchScore * MATCH_BOUNDS * self.gameModel;40                     for (Card *otherCard in otherCards)41                     {42                         [state appendFormat:@" %@",otherCard.contents];43                         otherCard.matched = YES;44                     }45                     [state appendFormat:@". Get %d score!",matchScore * MATCH_BOUNDS * self.gameModel];46                     card.matched = YES;47 48                     self.gameState = state;49                 }50                 else51                 {52                     NSMutableString *state = [NSMutableString stringWithFormat:@"State:%@ with",card.contents];53                     self.score -= MISMATCH_PENALTY * self.gameModel;54                     for (Card *otherCard in otherCards)55                     {56                         [state appendFormat:@" %@",otherCard.contents];57                         otherCard.chosen = NO;58                     }59                     [state appendFormat:@" not matched! %d point penalty!",MISMATCH_PENALTY * self.gameModel];60 61                     self.gameState = state;62                 }63             }64         }65     }66 }

   作業總結:雖然完成了作業的要求,但還有許多地方需要改進。如輸入情況檢測的30閾值為特定的數字,可以考慮改為[cardButtons count],游戲的計分邏輯不夠完善,在游戲匹配模式較大的情況下(貌似到5張牌匹配就出現了:p)容易出現極端的得分情況,大家可以下載源代碼玩玩試試。游戲狀態的Lable字數過多時的顯示問題。restart按鈕的邏輯有沒有更好的實現方法,本文為了防止restart中的updateUI方法在game置為nil后馬上重新初始化nil(此時selfDefiningModel為初始值2)特意重寫了一個更新UI的方法,有沒有更輕便的方法(如更符合MVC一點)?這些問題都是拋磚引玉,我并沒有細想,希望大家積極思考交流,如有不對歡迎指正:)

 

作業源碼地址:https://github.com/NSLogMeng/Stanford_iOS7_Study_Machismo/commit/39819086ac1c0b7a38679b75307b1cf0a687a190(今后同一個項目每次作業我會把當次完成的commit鏈接發給大家)

 

------------------------------------------------我是后來補充的-----------------------------------------

剛剛在真機上玩發現個嚴重的問題。。。。數字鍵盤沒有return鍵啊,數字鍵盤沒有return鍵啊,數字鍵盤沒有return鍵?。。?!模擬器直接在電腦的鍵盤上輸入的啊,根本沒有意識到_(:3 」∠)_

怒改之,添加了view響應事件,隱藏鍵盤,不過這部分源碼就不貼了,只是簡單地加了個方法,此部分已經嚴重超綱了。不過感興趣大家可以看看,github已經更新了。

最新版本:https://github.com/NSLogMeng/Stanford_iOS7_Study_Machismo/commit/117717b54bd39ffad9ea3e16bbf173ecb9c348c7

-----------------------------------------------------end-----------------------------------------------

 

課程視頻地址:網易公開課:http://open.163.com/movie/2014/1/H/U/M9H7S9F1H_M9H7VNFHU.html

       或者iTunes U搜索standford課程

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品视频久久久久久久| 欧美激情在线一区| 国产精品夜色7777狼人| 91社影院在线观看| 亚洲午夜小视频| 亚洲第一精品电影| 欧美激情视频给我| 97精品久久久中文字幕免费| 亚洲人免费视频| 一级做a爰片久久毛片美女图片| 国产精品va在线播放| 久久久精品网站| 久久99久久久久久久噜噜| 欧美激情一区二区三区成人| 亚洲成人亚洲激情| 欧美夫妻性视频| 欧美激情国产日韩精品一区18| 亚洲国产精品人人爽夜夜爽| 粉嫩老牛aⅴ一区二区三区| 国产精品久久久久久久久| 亚洲网站在线播放| 国产精品视频区| 国产精品99免视看9| 亚洲福利视频免费观看| 日韩一二三在线视频播| 中文亚洲视频在线| 日本精品免费观看| 国产精品久久久久不卡| 一区二区三区美女xx视频| 91天堂在线观看| 欧美午夜丰满在线18影院| 91产国在线观看动作片喷水| 国产精品一久久香蕉国产线看观看| 日韩在线观看网站| 亚洲国产高清高潮精品美女| 国产精品18久久久久久首页狼| 在线播放国产一区二区三区| 成人a免费视频| 中文字幕日韩有码| 中文字幕日韩免费视频| 91精品国产91久久久久久吃药| 精品国产成人在线| 在线视频欧美性高潮| 日韩电影中文字幕| 日韩一级黄色av| 久久全国免费视频| 久久久精品一区| 国产女人18毛片水18精品| 欧美午夜宅男影院在线观看| 91超碰中文字幕久久精品| 一本色道久久88综合亚洲精品ⅰ| 久久国产精品免费视频| 国产精品自产拍在线观看| 国产成人精品国内自产拍免费看| 中文字幕久久亚洲| 黑人狂躁日本妞一区二区三区| 欧美精品做受xxx性少妇| 国产精品自拍小视频| 欧美成人精品在线观看| 亚洲视频在线观看免费| 亚洲护士老师的毛茸茸最新章节| 美日韩丰满少妇在线观看| 亚洲欧美日韩精品久久奇米色影视| 国产亚洲欧美aaaa| 中文字幕亚洲在线| 91久久国产精品| 欧美一级电影久久| 精品欧美国产一区二区三区| 午夜精品国产精品大乳美女| 国产精品久久久久久久午夜| 欧美黑人xxxⅹ高潮交| 九九视频直播综合网| 国产91精品久| 欧日韩不卡在线视频| 日本中文字幕成人| 久久理论片午夜琪琪电影网| 4444欧美成人kkkk| 欧美激情2020午夜免费观看| 18一19gay欧美视频网站| 国产女精品视频网站免费| 亚洲第一天堂无码专区| 日韩欧美国产黄色| 2018国产精品视频| 欧美最猛黑人xxxx黑人猛叫黄| 国产精品日韩在线一区| 欧美激情国产精品| 国产亚洲一级高清| 国产精品一区二区三区在线播放| 亚洲综合中文字幕68页| 欧美精品久久久久久久免费观看| 欧美电影第一页| 国产suv精品一区二区| 亚洲第一区第二区| 91大神福利视频在线| 国产成人精品av| 久久免费视频观看| 欧美国产日产韩国视频| 最近2019中文字幕大全第二页| 成人性生交大片免费看小说| 在线电影欧美日韩一区二区私密| 亚洲第一网站免费视频| 91av福利视频| 国产精品狼人色视频一区| 欧美激情伊人电影| 亚洲第一av网站| 欧洲永久精品大片ww免费漫画| 91免费人成网站在线观看18| 国产亚洲人成a一在线v站| 不卡伊人av在线播放| 日韩av在线播放资源| 国产亚洲精品一区二555| 日韩av手机在线| 91精品国产综合久久久久久久久| 亚洲欧洲成视频免费观看| …久久精品99久久香蕉国产| 欧美在线亚洲一区| 日韩欧美在线观看| 久久久久久有精品国产| 亚洲精品久久久久久下一站| 高清视频欧美一级| 亚洲美女视频网站| 欧美成年人视频网站| 精品国产电影一区| 亚洲性日韩精品一区二区| 久久精品国产99国产精品澳门| 美女视频黄免费的亚洲男人天堂| 午夜精品福利在线观看| 久久久久久久亚洲精品| 人人澡人人澡人人看欧美| 国产日韩欧美综合| 大荫蒂欧美视频另类xxxx| 亚洲美女av黄| 国产精品69精品一区二区三区| 日韩有码在线电影| 国产成人在线一区| 国产热re99久久6国产精品| 日韩人体视频一二区| 日韩在线精品一区| 国产精自产拍久久久久久| 欧美性猛交xxxx免费看| 久久激情五月丁香伊人| 亚洲综合成人婷婷小说| 国产精品亚洲片夜色在线| 91精品在线观| 亚洲国产成人久久综合| 高清日韩电视剧大全免费播放在线观看| 中文字幕久久久| 日韩毛片在线看| 91精品久久久久久久| 91色琪琪电影亚洲精品久久| 亚洲小视频在线观看| 红桃视频成人在线观看| 超碰97人人做人人爱少妇| 亚洲男人天堂2019| 日韩国产一区三区| 国产精品三级美女白浆呻吟| 91成人性视频| 97高清免费视频| 懂色av影视一区二区三区| 91精品国产91久久久久久最新| 国产精品久久久久9999| 欧美日韩国产在线看| 5566日本婷婷色中文字幕97| 欧美性猛交xxxx久久久|