游戏中心配对GKTurnBasedMatch有显着滞后(约1分钟) [英] Game Center Matchmaking GKTurnBasedMatch has significant lag (~1 min)

查看:95
本文介绍了游戏中心配对GKTurnBasedMatch有显着滞后(约1分钟)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过游戏中心实现多人模式的回合制游戏。我有2个设备(1个ipad,1个iphone)在沙盒模式下进行测试,这些设备工作正常,但最近它开始在汽车配对过程中挣扎。在我从一个用户发送第一个回合后,另一个设备不会立即识别该游戏,而是打开自己的新游戏。之前它能够立即发现在其他设备上开始的游戏,并且配对相当简单。而且我不记得更改与配对相关的任何部分( NSCoding GKTurnBasedEventHandler GKTurnBasedMatchmakerViewControllerDelegate 委托方法等)。

I'm implementing a turn-based game with multiplayer mode through gamecenter. I have 2 devices (1 ipad, 1 iphone) to test in sandbox mode which were working fine but lately it has started to struggle in auto matchmaking process. After I send the first turn from one user, the other device doesn't immediately recognize that game but opens up its own fresh game. Before it was able to immediately spot the game started in the other device and matchmaking was fairly straightforward. And I don't remember changing any parts relevant to matchmaking (NSCoding, GKTurnBasedEventHandler, GKTurnBasedMatchmakerViewControllerDelegate delegate methods etc).

现在我从一台设备发送第一个转弯,需要等待大约1分钟,以便其他设备可以成功连接到该游戏。连接发生后,endTurnWithMatchData调用没有任何问题,它可以在1-2秒内发送和接收数据。但如果用户开始新游戏并且必须等待1分钟以便其他用户可以连接到他的游戏,那么它将不是一个好的用户体验。有没有人在汽车配对过程中遇到明显的滞后?我还没有实现邀请,所以我无法检查。我与NSKeyedArchiver存档的matchdata似乎相当大,3396字节,即使对于几乎没有数据的新游戏。以下是我的代码的相关部分:

Now I send the first turn from one device and need to wait around 1 min so the other device can successfully connect to that game. After connection occurs endTurnWithMatchData calls work without any problems, it can send and receive data within 1-2 secs. But it won't be a good UX if users start a fresh game and had to wait 1 min so another user can connect to his game. Has anyone been experiencing significant lag in auto matchmaking process? I didn't implement invitations yet, so I cannot check it. The matchdata I archive with NSKeyedArchiver seemed quite big, 3396 bytes, even for a fresh game with almost no data. And here are relevant parts of my code:

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);
            }
        }];
    }
}

}

-(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];
}


推荐答案

至于你的问题:

我自己在游戏中心的配对上做了相当多的调整,并经常经历滞后,这已被证明不是由我引起的网站,但由苹果游戏中心服务器。

I myself tempered with matchmaking over Game Center quite a bit and also experienced lags quite frequently, which have been proven to not have been caused by my site but by apples game center servers.

至于其他指导:

据我所知,您当前在设备上进行配对的方法是:

As far as I can see your current approach to matchmaking on a device is:

查看我是否可以连接到匹配项 - >如果是,则请求gamedata并连接比赛ELSE开始你自己的比赛并广播比赛数据

look if there is a match I can connect to --> If YES request gamedata and connect to the match ELSE start your own match and broadcast the matchdata

从我的经验来看,最好先练习matchrequestbroadcasts,等到你找到第二个球员,定义服务器设备(例如,通过游戏中心名称的较低校验和),然后在该设备上启动游戏。

From my experience it is better practice to start with matchrequestbroadcasts, wait until you find a second player, define the server device (e.g. by lower checksum of game-center names) and then start the game on that device.

这篇关于游戏中心配对GKTurnBasedMatch有显着滞后(约1分钟)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆