日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS开发必备指南合集之游戏接入GameCenter 指南

發布時間:2023/12/15 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS开发必备指南合集之游戏接入GameCenter 指南 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原地址:http://bbs.9ria.com/thread-248408-1-1.html

?iTunes Connect 設置

? ? 首先,申請一個應用程序,不必提交.目地是為了得到Bundle ID.
? ? 然后設置一下工程中Info.plist的Bundle identifier使之與iTunes Connect中的Bundle ID相同,否則當你嘗試登錄GameCenter的時候,會提示一個不支持GameCenter的錯誤.
? ? 申請完畢,打開你剛申請的application,點擊Manage Game Center選項.

? ? 進入后點擊Enable Game Center使你的Game Center生效.
? ? 接下來就可以設置自己的Leaderboard和Achievements.

2.? ? Leaderboard設置
? ? Leaderboard縱觀圖如下所示.

? ? 1.sort Order: Leaderboard中的內容是以升序還是降序排列.
? ? 2.Score Format Type:分數的類型.
? ? 3.*Categorieseaderboard的一個分數榜,這個可以創建多個,比如游戲可以分為Easy,Normal,Hard三個難度,每個難度一個榜.

?




? ? *設置完成后保存,完成了一個 Leaderboard的設置.我們可以根據需要添加多個 leaderboard.
? ? 4.**Score Format Location: leaderboard支持的語言.




? ? **可以支持多種語言,每支持一種語言,需要完成一個上述操作.
這個時候右下角會出現save change按鈕,點擊完成leaderboard的設置.
你可以根據需要隨時更改你的leaderboard,操作與上述內容類似.

3.? ? Achievements設置


? ? Achievements界面內容比較少,點擊左上角的Add New Achievement,打開如下圖所示的Achievements創建界面.

?




? ? Hidden:表示該成就為解鎖前玩家是否可見.
? ? Achievement ID:程序通過這個屬性來識別成就.
? ? *Achievement Localization:該成就支持的語言.
? ? *Achievement Localization設置如下圖所示.

?


? ? *其中,成就的Image必須是512X512,72DPI的.
一切設置完成后,點擊save change按鈕即完成一個成就的設置.

4.總體功能
在使用各個功能前,你需要了解一下塊函數。傳送門:https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html

4.1 對Game Center支持判斷

?

  • ??- (BOOL) isGameCenterAvailable
  • ? ? {
  • ? ?? ???Class gcClass = (NSClassFromString(@"GKLocalPlayer"));
  • ? ?? ?? ?NSString *reqSysVer = @"4.1";
  • ? ?? ?? ?NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
  • ? ?? ?? ?BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);
  • ? ?? ???
  • ? ?? ???return (gcClass && osVersionSupported);
  • ? ???}復制代碼
  • 復制代碼



4.2用戶登錄

?

  • ??- (void) authenticateLocalPlayer
  • ? ???{
  • ? ?? ?? ?[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error){
  • ? ?? ?? ?? ?if (error == nil) {
  • ? ?? ?? ?? ?? ? //成功處理
  • ? ?? ?? ?? ?? ? NSLog(@"成功");
  • ? ?? ?? ?? ?? ? NSLog(@"1--alias--.%@",[GKLocalPlayer localPlayer].alias);
  • ? ?? ?? ?? ?? ???NSLog(@"2--authenticated--.%d",[GKLocalPlayer localPlayer].authenticated);
  • ? ?? ?? ?? ?? ? NSLog(@"3--isFriend--.%d",[GKLocalPlayer localPlayer].isFriend);
  • ? ?? ?? ?? ?? ? NSLog(@"4--playerID--.%@",[GKLocalPlayer localPlayer].playerID);
  • ? ?? ?? ?? ?? ?NSLog(@"5--underage--.%d",[GKLocalPlayer localPlayer].underage);
  • ? ?? ?? ???}else {
  • ? ?? ?? ?? ?? ? //錯誤處理
  • ? ?? ?? ?? ?? ?NSLog(@"失敗??%@",error);
  • ? ?? ?? ?? ?}
  • ? ?? ? }];
  • ? ? }復制代碼
  • 復制代碼



對于開發者來說,Game Center必須經過測試才能上線,沒有上線的程序在測試環境中登錄時會出現sandbox提示.如圖.


? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??



4.3用戶變更檢測
由于4.0以后系統支持多任務,玩家的機器有可能被不同的玩家接觸,導致Game Center上的用戶發生變化,當發生變化的時候,程序必須在游戲中通知玩家.

  • - (void) registerForAuthenticationNotification
  • ? ? {
  • ? ?? ???NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
  • ? ?? ???[nc addObserver:self
  • ? ?? ?? ?? ?? ?selector:@selector(authenticationChanged)
  • ? ?? ?? ?? ?? ?? ???name:GKPlayerAuthenticationDidChangeNotificationName
  • ? ?? ?? ?? ?? ???object:nil];
  • ? ? }
  • ? ??
  • ? ?- (void) authenticationChanged
  • ? ?{
  • ? ?? ???if ([GKLocalPlayer localPlayer].isAuthenticated)
  • ? ?? ???{
  • ? ?? ?? ?? ?;// Insert code here to handle a successful authentication.
  • ? ?? ???}
  • ? ?? ? else
  • ? ?? ? {
  • ? ?? ?? ???;// Insert code here to clean up any outstanding Game Center-related classes.
  • ? ?? ?}
  • ? ?}復制代碼
  • 復制代碼



    5.對Leaderboard進行操作
    5.1上傳一個分數

  • ??- (void) reportScore: (int64_t) score forCategory: (NSString*) category
  • ? ? {
  • ? ?? ? GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:category] autorelease];
  • ? ?? ???scoreReporter.value = score;
  • ? ?? ???
  • ? ?? ?? ?[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
  • ? ?? ?? ?? ?if (error != nil)
  • ? ?? ?? ?? ?{
  • ? ?? ?? ?? ?? ?// handle the reporting error
  • ? ?? ?? ?? ?? ? NSLog(@"上傳分數出錯.");
  • ? ?? ?? ?? ?? ?//If your application receives a network error, you should not discard the score.
  • ? ?? ?? ?? ?? ?//Instead, store the score object and attempt to report the player’s process at
  • ? ?? ?? ?? ?? ? //a later time.
  • ? ?? ?? ?? ?}else {
  • ? ?? ?? ?? ?? ?NSLog(@"上傳分數成功");
  • ? ?? ?? ???}
  • ? ?
  • ? ?? ? }];
  • ? ? }復制代碼
  • 復制代碼



    當上傳分數出錯的時候,要將上傳的分數存儲起來,比如將SKScore存入一個NSArray中.等可以上傳的時候再次嘗試.

    5.2下載一個分數

  • ? ?//GKScore objects provide the data your application needs to create a custom view.
  • ? ? //Your application can use the score object’s playerID to load the player’s alias.
  • ? ???//The value property holds the actual value you reported to Game Center. the formattedValue
  • ? ???//property provides a string with the score value formatted according to the parameters
  • ? ???//you provided in iTunes Connect.
  • ? ???- (void) retrieveTopTenScores
  • ? ???{
  • ? ?? ???GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
  • ? ?? ? if (leaderboardRequest != nil)
  • ? ?? ???{
  • ? ?? ?? ???leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
  • ? ?? ?? ???leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;
  • ? ?? ?? ???leaderboardRequest.range = NSMakeRange(1,10);
  • ? ?? ?? ?? ?leaderboardRequest.category = @"TS_LB";
  • ? ?? ?? ?? ?[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
  • ? ?? ?? ?? ?? ? if (error != nil){
  • ? ?? ?? ?? ?? ?? ???// handle the error.
  • ? ?? ?? ?? ?? ?? ???NSLog(@"下載失敗");
  • ? ?? ?? ?? ?? ? }
  • ? ?? ?? ?? ?? ?if (scores != nil){
  • ? ?? ?? ?? ?? ?? ? // process the score information.
  • ? ?? ?? ?? ?? ?? ? NSLog(@"下載成功....");
  • ? ?? ?? ?? ?? ?? ?NSArray *tempScore = [NSArray arrayWithArray:leaderboardRequest.scores];
  • ? ?? ?? ?? ?? ?? ???for (GKScore *obj in tempScore) {
  • ? ?? ?? ?? ?? ?? ?? ? NSLog(@"? ? playerID? ?? ?? ?? ?: %@",obj.playerID);
  • ? ?? ?? ?? ?? ?? ?? ???NSLog(@"? ? category? ?? ?? ?? ?: %@",obj.category);
  • ? ?? ?? ?? ?? ?? ?? ???NSLog(@"? ? date? ?? ?? ?? ?? ? : %@",obj.date);
  • ? ?? ?? ?? ?? ?? ?? ???NSLog(@"? ? formattedValue? ? : %@",obj.formattedValue);
  • ? ?? ?? ?? ?? ?? ?? ?? ?NSLog(@"? ? value? ?? ?? ?? ?? ? : %d",obj.value);
  • ? ?? ?? ?? ?? ?? ?? ???NSLog(@"? ? rank? ?? ?? ?? ?? ? : %d",obj.rank);
  • ? ?? ?? ?? ?? ?? ?? ? NSLog(@"**************************************");
  • ? ?? ?? ?? ?? ?? ???}
  • ? ?? ?? ?? ?? ? }
  • ? ?? ?? ???}];
  • ? ?? ? }
  • ? ?}復制代碼
  • 復制代碼



    說明:
    1)? ? playerScope:表示檢索玩家分數范圍.
    2)? ? timeScope:表示某一段時間內的分數
    3)? ? range:表示分數排名的范圍
    4)? ? category:表示你的Leaderboard的ID.

    5.3玩家信息交互
    Game Center最重要的一個功能就是玩家交互.所以,必須檢索已經登錄玩家的好友信息.根據自己的需要做出設置,比如,可以與好友比較分數,或者好友排行榜等.
    //檢索已登錄用戶好友列表

  • ? ? - (void) retrieveFriends
  • ? ? {
  • ? ?? ???GKLocalPlayer *lp = [GKLocalPlayer localPlayer];
  • ? ?? ???if (lp.authenticated)
  • ? ?? ???{
  • ? ?? ?? ?? ?[lp loadFriendsWithCompletionHandler:^(NSArray *friends, NSError *error) {
  • ? ?? ?? ?? ?? ? if (error == nil)
  • ? ?? ?? ?? ?? ?{
  • ? ?? ?? ?? ?? ?? ???[self loadPlayerData:friends];
  • ? ?? ?? ?? ?? ?}
  • ? ?? ?? ?? ?? ?else
  • ? ?? ?? ?? ?? ?{
  • ? ?? ?? ?? ?? ?? ? ;// report an error to the user.
  • ? ?? ?? ?? ?? ?}
  • ? ?? ?? ???}];
  • ? ?? ?? ?? ?
  • ? ?? ? }
  • ? ?}復制代碼
  • 復制代碼



    上面的friends得到的只是一個身份列表,里面存儲的是NSString,想要轉換成好友ID,必須調用- (void) loadPlayerData: (NSArray *) identifiers方法,該方法得到的array里面存儲的才是GKPlayer對象.如下

  • ??/*
  • ? ???Whether you received player identifiers by loading the identifiers for the local player’s
  • ? ? friends, or from another Game Center class, you must retrieve the details about that player
  • ? ? from Game Center.
  • ? ???*/
  • ? ? - (void) loadPlayerData: (NSArray *) identifiers
  • ? ???{
  • ? ?? ? [GKPlayer loadPlayersForIdentifiers:identifiers withCompletionHandler:^(NSArray *players, NSError *error) {
  • ? ?? ?? ???if (error != nil)
  • ? ?? ?? ???{
  • ? ?? ?? ?? ?? ? // Handle the error.
  • ? ?? ?? ? }
  • ? ?? ?? ???if (players != nil)
  • ? ?? ?? ???{
  • ? ?? ?? ?? ???NSLog(@"得到好友的alias成功");
  • ? ?? ?? ?? ?? ?GKPlayer *friend1 = [players objectAtIndex:0];
  • ? ?? ?? ?? ???NSLog(@"friedns---alias---%@",friend1.alias);
  • ? ?? ?? ?? ???NSLog(@"friedns---isFriend---%d",friend1.isFriend);
  • ? ?? ?? ?? ???NSLog(@"friedns---playerID---%@",friend1.playerID);
  • ? ?? ?? ???}
  • ? ?? ? }];
  • ? ?}復制代碼
  • 復制代碼



    至此,leaderboard功能介紹完畢

    6.對Achievement進行操作
    ??這一部分內容比較多,而且有的地方有點重復的感覺.
    6.1匯報一個成就的進度
    ??對于一個玩家可見的成就,你需要盡可能的報告給玩家解鎖的進度;對于一個一部完成的成就,則不需要,當玩家的進度達到100%的時候,會自動解鎖該成就.

  • - (void) reportAchievementIdentifier: (NSString*) identifier percentComplete: (float) percent
  • ? ? {
  • ? ?? ?? ?GKAchievement *achievement = [[[GKAchievement alloc] initWithIdentifier: identifier] autorelease];
  • ? ?? ???if (achievement)
  • ? ?? ? {
  • ? ?? ?? ?? ?achievement.percentComplete = percent;
  • ? ?? ?? ?? ? [achievement reportAchievementWithCompletionHandler:^(NSError *error)
  • ? ?? ?? ?? ???{
  • ? ?? ?? ?? ?? ?? ?if (error != nil)
  • ? ?? ?? ?? ?? ? {
  • ? ?? ?? ?? ?? ?? ? //The proper way for your application to handle network errors is retain
  • ? ?? ?? ?? ?? ?? ???//the achievement object (possibly adding it to an array). Then, periodically
  • ? ?? ?? ?? ?? ?? ? //attempt to report the progress until it is successfully reported.
  • ? ?? ?? ?? ?? ?? ? //The GKAchievement class supports the NSCoding protocol to allow your
  • ? ?? ?? ?? ?? ?? ???//application to archive an achie
  • ? ?? ?? ?? ?? ?? ???NSLog(@"報告成就進度失敗 ,錯誤信息為: \n %@",error);
  • ? ?? ?? ?? ???}else {
  • ? ?? ?? ?? ?? ?? ?? ?//對用戶提示,已經完成XX%進度
  • ? ?? ?? ?? ?? ?? ???NSLog(@"報告成就進度---->成功!");
  • ? ?? ?? ?? ?? ?? ???NSLog(@"? ? completed:%d",achievement.completed);
  • ? ?? ?? ?? ?? ?? ? NSLog(@"? ? hidden:%d",achievement.hidden);
  • ? ?? ?? ?? ?? ?? ???NSLog(@"? ? lastReportedDate:%@",achievement.lastReportedDate);
  • ? ?? ?? ?? ?? ?? ? NSLog(@"? ? percentComplete:%f",achievement.percentComplete);
  • ? ?? ?? ?? ?? ?? ???NSLog(@"? ? identifier:%@",achievement.identifier);
  • ? ?? ?? ?? ?? ?}
  • ? ?? ?? ?? ? }];
  • ? ?? ? }
  • ? ?}復制代碼
  • 復制代碼



    其中該函數的參數中identifier是你成就的ID, percent是該成就完成的百分比

    6.2讀取一個成就
    方法一:得到所有的成就

  • - (void) loadAchievements
  • ? ???{
  • ? ?? ? NSMutableDictionary *achievementDictionary = [[NSMutableDictionary alloc] init];
  • ? ?? ?? ?[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements,NSError *error)
  • ? ?? ?? ?{
  • ? ?? ?? ?? ? if (error == nil) {
  • ? ?? ?? ?? ?? ? NSArray *tempArray = [NSArray arrayWithArray:achievements];
  • ? ?? ?? ?? ?? ???for (GKAchievement *tempAchievement in tempArray) {
  • ? ?? ?? ?? ?? ?? ?? ?[achievementDictionary setObject:tempAchievement forKey:tempAchievement.identifier];
  • ? ?? ?? ?? ?? ?? ???NSLog(@"? ? completed:%d",tempAchievement.completed);
  • ? ?? ?? ?? ?? ?? ???NSLog(@"? ? hidden:%d",tempAchievement.hidden);
  • ? ?? ?? ?? ?? ?? ? NSLog(@"? ? lastReportedDate:%@",tempAchievement.lastReportedDate);
  • ? ?? ?? ?? ?? ?? ???NSLog(@"? ? percentComplete:%f",tempAchievement.percentComplete);
  • ? ?? ?? ?? ?? ?? ???NSLog(@"? ? identifier:%@",tempAchievement.identifier);
  • ? ?? ?? ?? ?? ? }
  • ? ?? ?? ?? ?}
  • ? ?? ?? ?}];
  • ? ?}復制代碼
  • 復制代碼



    函數中NSArray返回的是你的所有成就ID.

    方法二:根據ID獲取成就

  • - (GKAchievement*) getAchievementForIdentifier: (NSString*) identifier
  • ? ???{
  • ? ?? ???NSMutableDictionary *achievementDictionary = [[NSMutableDictionary alloc] init];
  • ? ?? ? GKAchievement *achievement = [achievementDictionary objectForKey:identifier];
  • ? ?? ???if (achievement == nil)
  • ? ?? ???{
  • ? ?? ?? ?? ? achievement = [[[GKAchievement alloc] initWithIdentifier:identifier] autorelease];
  • ? ?? ?? ?? ?[achievementDictionary setObject:achievement forKey:achievement.identifier];
  • ? ?? ???}
  • ? ?? ?return [[achievement retain] autorelease];
  • ? ?}復制代碼
  • 復制代碼



    6.3獲取成就描述和圖片
    在自定義界面中,玩家需要一個成就描述,以及該成就的圖片,Game Center提供了該功能.當然,你也可以自己在程序中完成,畢竟玩家不可能時刻處于在線狀態.

  • ??- (NSArray*)retrieveAchievmentMetadata
  • ? ? {
  • ? ?? ???//讀取成就的描述
  • ? ?? ???[GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:
  • ? ?? ?? ? ^(NSArray *descriptions, NSError *error) {
  • ? ?? ?? ?? ?if (error != nil)
  • ? ?? ?? ?? ? {
  • ? ?? ?? ?? ?? ?? ?// process the errors
  • ? ?? ?? ?? ?? ?? ?NSLog(@"讀取成就說明出錯");
  • ? ?? ?? ?? ?}
  • ? ?? ?? ???if (descriptions != nil)
  • ? ?? ?? ?? ? {
  • ? ?? ?? ?? ?? ? // use the achievement descriptions.
  • ? ?? ?? ?? ?? ? for (GKAchievementDescription *achDescription in descriptions) {
  • ? ?? ?? ?? ?? ?? ?? ?NSLog(@"1..identifier..%@",achDescription.identifier);
  • ? ?? ?? ?? ?? ?? ?? ?NSLog(@"2..achievedDescription..%@",achDescription.achievedDescription);
  • ? ?? ?? ?? ?? ?? ???NSLog(@"3..title..%@",achDescription.title);
  • ? ?? ?? ?? ?? ?? ?? ?NSLog(@"4..unachievedDescription..%@",achDescription.unachievedDescription);
  • ? ?? ?? ?? ?? ?? ? NSLog(@"5............%@",achDescription.image);
  • ? ?? ?? ?? ?? ?? ??
  • ? ?? ?? ?? ?? ?? ?? ?//獲取成就圖片,如果成就未解鎖,返回一個大文號
  • ? ?? ?? ?? ?? ?? ???/*
  • ? ?? ?? ?? ?? ?? ???[achDescription loadImageWithCompletionHandler:^(UIImage *image, NSError *error) {
  • ? ?? ?? ?? ?? ?? ?? ?? ?if (error == nil)
  • ? ?? ?? ?? ?? ?? ?? ?? ?{
  • ? ?? ?? ?? ?? ?? ?? ?? ?? ? // use the loaded image. The image property is also populated with the same image.
  • ? ?? ?? ?? ?? ?? ?? ?? ?? ? NSLog(@"成功取得成就的圖片");
  • ? ?? ?? ?? ?? ?? ?? ?? ?? ???UIImage *aImage = image;
  • ? ?? ?? ?? ?? ?? ?? ?? ?? ?UIImageView *aView = [[UIImageView alloc] initWithImage:aImage];
  • ? ?? ?? ?? ?? ?? ?? ?? ?? ? aView.frame = CGRectMake(50, 50, 200, 200);
  • ? ?? ?? ?? ?? ?? ?? ?? ?? ? aView.backgroundColor = [UIColor clearColor];
  • ? ?? ?? ?? ?? ?? ?? ?? ?? ? [[[CCDirector sharedDirector] openGLView] addSubview:aView];
  • ? ?? ?? ?? ?? ?? ?? ?? ? }else {
  • ? ?? ?? ?? ?? ?? ?? ?? ?? ?NSLog(@"獲得成就圖片失敗");
  • ? ?? ?? ?? ?? ?? ?? ?? ?}
  • ? ?? ?? ?? ?? ?? ? }];
  • ? ?? ?? ?? ?? ?? ?? ? */
  • ? ?? ?? ?? ?? ? }
  • ? ?? ?? ?? ?}
  • ? ?? ???}];
  • ? ?? ?return nil;
  • ? ?}復制代碼
  • 復制代碼



    ? ? 如果你不主動使用注釋中的方法,那么你得到的description中不會有圖片,這樣可以減少網絡的使用,盡量少下載東西.當使用注釋中的代碼時,如果成就已經解鎖,則返回該成就的圖標,如果沒有解鎖,則返回一個大問號,至于未解鎖圖標是否可以自定義,我找尋的結果好像是不可以.GameCenter??成就提示更新:?GameCenter中成就提示需要開發者自定義,即使官方Demo的例子程序中也沒有給與提示框(橫幅樣式)通知用戶的官方代碼,所以這里Himi介紹如何模仿官方的成就提示:? ?1. iOS5以及更高SDK中,apple已經提供官方的成就提示:方法很簡單,代碼如下:

  • - (void)sendAchievement:(GKAchievement *)achievement {
  • achievement.percentComplete = 100.0;? ?//Indicates the achievement is done
  • achievement.showsCompletionBanner = YES;? ? //Indicate that a banner should be shown
  • [achievement reportAchievementWithCompletionHandler:
  • ^(NSError *error) {
  • dispatch_async(dispatch_get_main_queue(), ^(void)
  • {
  • if (error == NULL) {
  • NSLog(@"Successfully sent archievement!");
  • } else {
  • NSLog(@"Achievement failed to send... will try again \
  • later.??Reason: %@", error.localizedDescription);
  • }
  • });
  • }];
  • }復制代碼
  • 復制代碼


    ? ? 將“showsCompletionBanner”屬性設置成YES,提交給蘋果。新iOS屬性“showsCompletionBanner”,其默認設置是NO,但若將其調整成YES,屏幕就呈現包含成就標題和描述的漂亮橫幅;
    2.如果低于5.0的SDK設備中是沒有 “showsCompletionBanner”屬性的,所以需要我們自定義提示樣式,當然這里Himi也分享一下如何模仿官方橫幅提示樣式的方法和代碼:? ?? ?首先,我借鑒Type One Error所展示的優秀代碼,從https://github.com/typeoneerror/GKAchievementNotification中抓取一些代碼植入自己的項目。我們將采用GKAchievementNotification和GKAchievementHandler類,同時進行相應更新和修改。首先,若你在游戲中運用ARC,快速掃描代碼,移除那些發行、保留和自動發行代碼屬性。若你不想進行掃描,試著將文件放入項目及修復不符編譯程序的內容,然后再創建內容。Type One Error類將展示類似于iOS 5所呈現的通知內容,但代碼需獲悉成就標題和描述是什么。為實現這點,你需要嵌入“showsCompletionBanner”目標。GKAchievementDescription目標的優點是它們已根據用戶語言設定進行本土化,因此采用此方式不存在任何本土化問題。其弊端在于你無法只加載一個成就描述,你需要加載所有內容。我認為進行此操作的最佳時間是用戶已在應用上認證Game Center,此時你需要通過異步調用獲得這些消息。值得欣慰的是,蘋果在此設有API調用,我將此放置在用戶認證訪問的CompletionHandler中。若你采用Ray Wenderlich網站的代碼,那么你就既能夠運用此方法,又擁有新方法。將NSMutableDictionary * self.achievementsDescDictionary添加至所有處理游戲Game Center代碼的類(游戲邦注:它會在隨后的體驗中存儲成就數據)。

  • - (void)authenticateLocalUser {
  • if (!gameCenterAvailable) return;
  • NSLog(@”Authenticating local user…”);
  • if ([GKLocalPlayer localPlayer].authenticated == NO) {
  • [[GKLocalPlayer localPlayer]
  • authenticateWithCompletionHandler:^(NSError *error) {
  • if([GKLocalPlayer localPlayer].isAuthenticated){
  • [self retrieveAchievmentMetadata];? ?? ?? ?//Here is the new code
  • }
  • }];
  • }
  • }
  • //Here is the new method.
  • - (void) retrieveAchievmentMetadata
  • {
  • self.achievementsDescDictionary = [[NSMutableDictionary alloc] initWithCapacity:2];
  • [GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:
  • ^(NSArray *descriptions, NSError *error) {
  • if (error != nil) {
  • NSLog(@"Error %@", error);
  • } else {
  • if (descriptions != nil){
  • for (GKAchievementDescription* a in descriptions) {
  • [achievementsDescDictionary setObject: a forKey: a.identifier];
  • }
  • }
  • }
  • }];
  • }
  • “retrieveAchievmentMetadata”方法會初始化所有信息庫,然后調用游戲所有成就描述,進行循環,將它們添加至信息庫。這屬于異步調用,所以不應減緩游戲或項目的啟動。
  • 現在我們握有各成就的標題和描述,因此能夠修改原始代碼創造iOS 4/5的善意通知,其將通過Type One Error代碼連續展示所有成就。
  • - (void)reportAchievement:(NSString *)identifier
  • percentComplete:(double)percentComplete {
  • GKAchievement* achievement = [[GKAchievement alloc]
  • initWithIdentifier:identifier];
  • achievement.percentComplete = percentComplete;
  • if (percentComplete == 100.0) {
  • //Show banners manually
  • GKAchievementDescription *desc = [achievementsDescDictionary objectForKey:identifier]; //Update pull achievement description for dictionary
  • [[GKAchievementHandler defaultHandler] notifyAchievement:desc];??//Display to user
  • }
  • [achievementsToReport addObject:achievement];? ? //Queue up the achievement to be sent
  • [self save];
  • if (!gameCenterAvailable || !userAuthenticated) return;
  • [self sendAchievement:achievement];? ?//Try to send achievement
  • }
  • - (void)sendAchievement:(GKAchievement *)achievement {
  • [achievement reportAchievementWithCompletionHandler:
  • ^(NSError *error) {
  • dispatch_async(dispatch_get_main_queue(), ^(void)
  • {
  • if (error == NULL) {
  • NSLog(@"Successfully sent archievement!");
  • [achievementsToReport removeObject:achievement];? ?//Remove Achievement from queue.
  • } else {
  • NSLog(@”Achievement failed to send… will try again \
  • later.??Reason: %@”, error.localizedDescription);
  • }
  • });
  • }];
  • }復制代碼
  • 復制代碼


    ? ? 如果你想讓成就中顯示為你在itunes connect中設置成就的自定義圖片,首先將通知部分代碼修改成如下代碼:

  • if (percentComplete == 100.0) {
  • //Show banners manually
  • GKAchievementDescription *desc = [achievementsDescDictionary objectForKey:identifier];
  • [desc loadImageWithCompletionHandler:^(UIImage *image, NSError *error) {
  • if (error == nil)
  • {
  • [[GKAchievementHandler defaultHandler] setImage:desc.image];? ?//If image found, updates the image to the achievement image.
  • }
  • [[GKAchievementHandler defaultHandler] notifyAchievement:desc];
  • }];
  • }復制代碼
  • 復制代碼


    ? ? 使用以上方式默認為橫屏顯示成就通知,如果想換成豎屏提示,那么這里Himi給出參考代碼:在“GKAchievementHandler”類中找到“notifyAchievement”,更新為:

  • - (void)notifyAchievement:(GKAchievementDescription *)achievement
  • {
  • GKAchievementNotification *notification = [[GKAchievementNotification alloc] initWithAchievementDescription:achievement];
  • notification.frame = kGKAchievementFrameStart;
  • notification.handlerDelegate = self;
  • //Adjusting rotation.
  • if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft) {
  • notification.transform = CGAffineTransformRotate(notification.transform, degreesToRadian(-90));
  • } else {
  • notification.transform = CGAffineTransformRotate(notification.transform, degreesToRadian(90));
  • }
  • [_queue addObject:notification];
  • if ([_queue count] == 1)
  • {
  • [self displayNotification:notification];
  • }
  • }復制代碼
  • 復制代碼

    ?

    總結

    以上是生活随笔為你收集整理的iOS开发必备指南合集之游戏接入GameCenter 指南的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。