2012-08-01 67 views
2

我想知道如何在遊戲進程正在進行時爲本地玩家獲取斷開連接信息,並且我們無法將我們的數據傳達給其他玩家。由於文檔中沒有任何內容表明「這種方法會在您的連接失敗時通知您」,所以我有點不知所措。如何判斷我們何時與GameCenter GKMatch會話斷開連接?

我試圖使用這段代碼,希望它可以工作,但它是徒勞的。 「我們斷開連接」。消息從不被觸發。

- (void)match:(GKMatch *)theMatch player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state { 
    if (self.match != theMatch) return; 

    switch (state) { 

    case GKPlayerStateDisconnected: 
     //disconnected 
     NSLog(@"player status changed: disconnected"); 
     matchStarted = NO; 
     GKLocalPlayer *player = [GKLocalPlayer localPlayer]; 
     if ([playerID isEqualToString:player.playerID]) { 

     // We have been disconnected 
     NSLog(@"We're disconnected."); 
     } 
     if ([delegate respondsToSelector:@selector(matchEnded)]) { 
     [delegate matchEnded]; 
     } 
     break; 
    } 
} 

,我發現可能會告訴我們,我們是無法溝通的唯一其他行是當我們真正發送的數據是這樣的:

- (void)sendRandomMatchData:(NSData *)data { 
    GKMatch *match = [GCHelper sharedInstance].match; 
    BOOL success = [match sendDataToAllPlayers:data 
           withDataMode:GKMatchSendDataReliable 
             error:nil]; 
    if (!success) { 
    [self matchEnded]; 
    } 
} 

但我認爲「成功」也將如果對手斷開連接並且我們無法向他們發送消息,則爲false。

我有一個非常嚴格的遊戲邏輯,如果有人已經斷開連接,我需要通知他們,他們無法繼續玩比賽,他們已經輸了。

任何幫助,高度讚賞。

+0

我已經注意到了這一點。如果玩家主動結束比賽,GKPlayerStateDisconnected被擊中,但是在網絡錯誤時,它從不被觸發,並且可以在無效狀態下獲得主動比賽。 – 2013-05-30 23:03:09

回答

0

什麼檢查error下面的代碼行後:

BOOL success = [match sendDataToAllPlayers:data 
           withDataMode:GKMatchSendDataReliable 
             error:nil]; //replace nil with NSError variable 

也許error會給你額外的信息u需要。
另一個想法是創建NSTimer並設置一定的時間進行移動/轉動。如果某玩家在某段時間內沒有成功,則假定該玩家已斷開連接。你也可以檢查你的互聯網連接狀態,以確定你有一個連接因爲也許你只是失去了它,這就是你無法發送/接收任何數據的原因。
您也可以通過使用GC向他們發送一些短數據量來定期檢查每個玩家,以便他們回答您。這樣你可以確保所有玩家都「活着」或檢測到一些「殭屍」。
記住,如果玩家使用主頁按鈕將遊戲移動到背景,那麼無論如何cuz代碼都不會執行。而這種情況並不意味着該玩家是「殭屍」。玩家可能正忙着打電話或其他應用程序。玩家可能暫時失去互聯網連接。這意味着他/她很快就能回到遊戲中......

+0

感謝您的回答。 – Eugene 2012-12-05 22:52:39

+0

'sendDataToAllPlayers'是異步的。返回代碼只會告訴你_queue_是否成功,如果傳輸成功,則不_not_。你也應該抓住'NSError'! – bobobobo 2013-05-27 16:52:56

1

有2個地方可以做到這一點,兩者都在GKMatchDelegate協議。

首先是實施:

- (void)match:(GKMatch *)match player:(NSString *)playerID 
    didChangeState:(GKPlayerConnectionState)state 
{ 
} 

而且如果它是一個2玩家匹配,你可以趕上斷開第二位的是:

- (BOOL)match:(GKMatch *)theMatch shouldReinvitePlayer:(NSString *)playerID 
{ 
} 

這兩項事件引發可靠當GKMatch終止時。如果斯坦的回答回答你的問題,那麼我會高度建議在無論他們可用的地方採取捕捉NSError的做法!可以爲你節省很多時間。

因此,要發送的數據和捕獲的錯誤:

NSError* nsErr ; 
int result = [theMatch sendData:nsd toPlayers:theMatch.playerIDs 
       withDataMode:GKMatchSendDataReliable error:&nsErr] ; 
if(!result) { // NO if the match was unable to queue the data. 
    error(nsErr, "Failed to sendRoundtripPing") ; 
}