Oyuncunun üzerinden çok oyunculu modlu sıra tabanlı bir oyun yapıyorum. İyi çalışan kum havuzu modunda test etmek için 2 cihazım (1 ipad, 1 iphone) var ama son zamanlarda otomatik eşleştirme sürecinde mücadele etmeye başladı. Bir kullanıcıdan ilk dönüşü gönderdikten sonra, diğer cihaz bu oyunu hemen tanımaz ancak kendi taze oyununu açar. Oyun hemen diğer cihazda başladığı noktaya ulaşabilmeden önce maçlar çok kolay geçti. Ve eşleştirme ile ilgili herhangi bir parçayı değiştirmeyi hatırlamıyorum (NSCoding
, GKTurnBasedEventHandler
, GKTurnBasedMatchmakerViewControllerDelegate
delege yöntemleri vb.).Game Center Çöpçatanlık GKTurnBasedMatch anlamlı gecikme (~ 1 dk) var
Şimdi ilk dönüşü bir cihazdan gönderiyorum ve yaklaşık 1 dakika beklemem gerekiyor, böylece diğer cihaz bu oyuna başarılı bir şekilde bağlanabiliyor. Bağlantı kurulduktan sonra endTurnWithMatchData herhangi bir sorun olmadan çağrı yapar, 1-2 saniye içinde veri gönderebilir ve alabilir. Eğer kullanıcılar yeni bir oyuna başlarlarsa ve 1 dakika beklemek zorunda kaldıklarında iyi bir UX olmayacaktır, böylece başka bir kullanıcı oyununa bağlanabilir. Otomatik eşleştirme sürecinde herhangi bir ciddi gecikme yaşanıyor mu? Henüz davetiye almadım, bu yüzden kontrol edemiyorum. NSKeyedArchiver ile arşivlediğim matchdata, neredeyse hiç veriye sahip olmayan yeni bir oyun için bile 3396 baytlık görünüyordu.
GameOptionsViewController
:
- (void)turnBasedMatchmakerViewControllerWasCancelled:(GKTurnBasedMatchmakerViewController *)viewController
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController didFailWithError:(NSError *)error
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController didFindMatch:(GKTurnBasedMatch *)match
{
[self dismissViewControllerAnimated:NO completion:nil];
self.gcMatch = match;
[self performSegueWithIdentifier:@"GameMultiplayer" sender:self];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:@"GameMultiplayer"])
{
GameViewController *GameVC = (GameViewController *)segue.destinationViewController;
[GameVC setGameMode:GAMEMODE_MULTIPLAYER_SAMEDEVICE];
//Multiplayer game it is
if(self.gcMatch != nil)
{
[GameVC setGameMode:GAMEMODE_MULTIPLAYER_GAMECENTER];
GameVC.gcMatchDelegate = self;
GameVC.gcMatch = self.gcMatch;
NSLog(@"Game OVC Segue: Match ID | %@", self.gcMatch.matchID);
}
}
else
{
...
}
}
GameViewController
:
//This method is called according to user actions
//It's the only method I use to send data to other participant
-(void) sendCurrentGameDataWithNewTurn:(BOOL) newTurn
{
NSLog(@"Sending game data current participant : %@", gcMatch.currentParticipant.playerID);
//Update match data if it is corrupted anyhow
if (gcMatch.currentParticipant == nil)
{
[GKTurnBasedMatch loadMatchWithID:gcMatch.matchID withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error)
{
if (error != nil)
{
NSLog(@"Error :%@", error);
return ;
}
[self sendCurrentGameDataWithNewTurn:newTurn];
}];
}
else
{
NSData *matchData = [NSKeyedArchiver archivedDataWithRootObject:game];
//Game advances to new player, buttons are disabled
if(newTurn)
{
NSLog(@"SENDING NEW TURN");
NSUInteger currentIndex = [gcMatch.participants
indexOfObject:gcMatch.currentParticipant];
GKTurnBasedParticipant *nextParticipant;
nextParticipant = [gcMatch.participants objectAtIndex:
((currentIndex + 1) % [gcMatch.participants count])];
[gcMatch endTurnWithNextParticipants:[NSArray arrayWithObject:nextParticipant] turnTimeout:GC_TURN_TIMEOUT matchData:matchData completionHandler:^(NSError *error) {
NSLog(@"Sent");
if (error) {
NSLog(@"SNT - %@", error);
}
}];
}
else
{
NSLog(@"ONLY UPDATING DATA");
[gcMatch saveCurrentTurnWithMatchData:matchData completionHandler:^(NSError *error) {
NSLog(@"Sent");
if (error) {
NSLog(@"OUD - %@", error);
}
}];
}
}
} Sorunuza gelince
-(void) updateGameDataWithGCMatch
{
//Update whole game data
self.game = [NSKeyedUnarchiver unarchiveObjectWithData:self.gcMatch.matchData];
//Update game ui
...
}
-(void) handleTurnEventForMatch:(GKTurnBasedMatch *)match didBecomeActive:(BOOL)didBecomeActive
{
//Check if I got data for the currently active match that options vc forwarded me here, if not do some debug print and return
if(![self.gcMatch.matchID isEqual:match.matchID])
{
//For debugging reasons I skip if i get info for any previous match (other player quit etc)
NSLog(@"GCMatch matchID: %@ match matchID: %@",self.gcMatch.matchID,match.matchID);
return;
}
NSLog(@"Turn event handle");
self.gcMatch = match;
if([match.currentParticipant.playerID isEqualToString: [GKLocalPlayer localPlayer].playerID ])
{
//Disable field buttons
[self setFieldButtonsEnabled:TRUE];
[self turnChangeAnimationFromLeftToRight:FALSE];
}
[self updateGameDataWithGCMatch];
}
Oyun Merkezi, keyfi bir gecikme yaşanabilir. Kendi ağımızdan mı, yoksa Apple’ın tarafındaki bir şeyden mi geldiğini asla bilemezsiniz. –
Şimdi bu 2-3 haftadır gecikme yaşıyorum. Şimdi daha da kötü ya da daha iyiydi. Uygulamanızı 2 cihazda korumalı alan hesaplarıyla test ederken böyle gecikmeler olduğunu sorabilir miyim. Diğer geliştiriciler de buna sahipse, bir çözüm aramayı bırakacağım; olduğu gibi test etmeye devam edin. – guenis
Ayrıca GC kum kutusu ile çalışırken önemli bir gecikme yaşadım. Aynı zamanda çalışma seansından çalışma seansına kadar biraz farklı görünmektedir. – crgt