3

I'm working on a turn based iOS game using game center and right now I have my test account participating in six games in Game Center, but every time I try to quit one by swiping on it (which should really end the game because my test account is the only one in it) it removes the game from the table for a split second and then replaces it immediately and doesn't quit.

Here is my playerQuitForMatch function:

// Handle players leaving the match in and out of turn.
- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController
                      playerQuitForMatch:(GKTurnBasedMatch *)match
{
    // If the player was the current participant, remove them from the next participants array.
    if ([match.currentParticipant.playerID isEqualToString:GKLocalPlayer.localPlayer.playerID])
    {
        NSMutableArray* nextParticipants = [NSMutableArray arrayWithArray:[match participants]];
        [nextParticipants removeObjectIdenticalTo:[match currentParticipant]];

        // If they were the last player, end the match because it is empty.
        if ([nextParticipants count] == 0)
        {
            [match endMatchInTurnWithMatchData:match.matchData completionHandler:nil];
        }
        // Otherwise, remove them from the match and pass priority.
        else
        {
            [match participantQuitInTurnWithOutcome:GKTurnBasedMatchOutcomeQuit
                                   nextParticipants:nextParticipants
                                        turnTimeout:0.0f
                                          matchData:match.matchData
                                  completionHandler:nil];
        }
    }
    // If they weren't the current participant, just remove them from the match.
    else
    {
        NSMutableArray* nextParticipants = [NSMutableArray arrayWithArray:[match participants]];
        [nextParticipants removeObjectIdenticalTo:[match currentParticipant]];

        // The player can't be the last person in the game if they aren't the active player.
        [match participantQuitOutOfTurnWithOutcome:GKTurnBasedMatchOutcomeQuit withCompletionHandler:nil];
    }

    NSLog(@"playerquitforMatch, %@, %@", match, match.currentParticipant);
}

And here's the console output:

2013-05-04 13:16:13.180 XYZ Mobile[7799:c07] Authenticating local user...
2013-05-04 13:16:13.587 XYZ Mobile[7799:c07] Authentication changed: player authenticated.
May  4 13:16:13 folsom-wireless-153.dynamic2.rpi.edu XYZ Mobile[7799] <Info>: 13:16:13.597120 com.apple.AVConference: GKSConnSettings: set server: {
        "gk-cdx" = "17.173.254.218:4398";
        "gk-commnat-cohort" = "17.173.254.220:16386";
        "gk-commnat-main0" = "17.173.254.219:16384";
        "gk-commnat-main1" = "17.173.254.219:16385";
    }
2013-05-04 13:16:21.380 XYZ Mobile[7799:c07] 101
2013-05-04 13:16:58.150 XYZ Mobile[7799:c07] New Game Button Pressed
2013-05-04 13:17:00.146 XYZ Mobile[7799:c07] playerquitforMatch, <GKTurnBasedMatch 0x949ece0    id:0a8b8246-1872-410e-b9ae-819a9a00d4ff status:Open message:(null) taken:(null) created:2013-04-24 23:32:35 +0000
current:<GKTurnBasedParticipant 0x949ad50 - id:(null) status:Matching outcome:None lastTurn:(null)>
participants:
        <GKTurnBasedParticipant 0x949ad40 - id:G:1759434517 (local player) status:Done outcome:Quit lastTurn:(null)>
        <GKTurnBasedParticipant 0x949ad50 - id:(null) status:Matching outcome:None lastTurn:(null)>
        <GKTurnBasedParticipant 0x949f2b0 - id:(null) status:Matching outcome:None lastTurn:(null)>
        <GKTurnBasedParticipant 0x949f2c0 - id:(null) status:Matching outcome:None lastTurn:(null)>
        <GKTurnBasedParticipant 0x949f650 - id:(null) status:Matching outcome:None lastTurn:(null)>
        <GKTurnBasedParticipant 0x949f660 - id:(null) status:Matching outcome:None lastTurn:(null)>
        <GKTurnBasedParticipant 0x949bc20 - id:(null) status:Matching outcome:None lastTurn:(null)>
        <GKTurnBasedParticipant 0x949bc30 - id:(null) status:Matching outcome:None lastTurn:(null)>
    >, <GKTurnBasedParticipant 0x949ad50 - id:(null) status:Matching outcome:None lastTurn:(null)>
2013-05-04 13:17:08.523 XYZ Mobile[7799:c07] has cancelled
4

2 回答 2

2

我是否正确理解您: * 游戏是在游戏中心的内置 UI 中滑动的,而不是自定义的?* 有问题的游戏有玩家作为当前参与者吗?

我相信你必须为无与伦比的球员设定比赛结果。如果你不这样做,它们仍然会匹配。所以会发生的情况是 GC 发现一个人试图加入你的游戏,然后这个人会看到一个游戏,其中有 1 人退出,他自己是当前参与者和 6 名不匹配的玩家。使用您的代码可能会发生有人加入游戏而 7 人已经离开!是的,GC 很奇怪。

您想要结束游戏的操作是为所有玩家设置比赛结果,然后调用

endMatchInTurnWithMatchData:completionHandler:
于 2013-05-07T14:54:11.910 回答
0

感谢上面答案 1 中的提示,当两人比赛的发起者在轮到他们之前退出但玩家 2 收到了一个退出玩家的比赛时,我遇到了类似的问题。我在“轮流功能”中执行了以下操作,以确保玩家 2 可以从他们的游戏中心视图中删除比赛。发布了很多代码,但要做的关键是:

1-将数据发送到游戏中心,因为它目前可能没有足够的信息。

2-以编程方式让所有玩家退出比赛

3 以编程方式结束比赛

4-以编程方式从游戏中心删除比赛。

//CHECKING IF PLAYER HAS QUIT.

NSUInteger currentIndex = [match.participants indexOfObject:match.currentParticipant];

//find the next participant in the match
GKTurnBasedParticipant *nextParticipant;

//Note if player 1's turn result is (0+1) % 2 = 0 remainder 1, therefore nextIndex = 1 (i.e. player 2 on a zero based index)
//Note if player 2's turn result is (1+1) % 2 = 1 remainder 0, therefore nextIndex = 0 (i.e. player 1 on a zero based index)

NSUInteger nextIndex = (currentIndex + 1) % [match.participants count];

nextParticipant = [match.participants objectAtIndex:nextIndex];

//check to see if any of the participants has quit.
for (int i = 0; i < [match.participants count]; i++)
{
    nextParticipant = [match.participants objectAtIndex:((currentIndex + 1 + i) % [match.participants count ])];

    if (nextParticipant.matchOutcome != GKTurnBasedMatchOutcomeQuit)
    {
        NSLog(@"Player %@ has not quit", nextParticipant);
        break;
    }
    else
    {
        NSLog(@"Next participant %@ has quit", nextParticipant);

        //because the initiator has quit before playing, player "2 i.e current player index 1" should send dummy data to game centre
        //to allow them to delete this from their game centre view otherwise the match cannot be deleted from their game centre
        if(currentIndex == 1)
        {

             //send dummy data as is no turn has been taken. This allows the functions below to be carried out.
            [self CallToSendPlayerTurnData];

            for (GKTurnBasedParticipant *part in match.participants)
            {
                 part.matchOutcome = GKTurnBasedMatchOutcomeQuit;
            }

            //then end the match
            [match endMatchInTurnWithMatchData:match.matchData completionHandler:^(NSError *error)
             {
                 if (error)
                 {
                     NSLog(@"Erro ending quit match %@", error.localizedDescription);
                     {

                     }
                 }
              }
             ];

          //then remove the match programatically otherwise players GC viewer cannnot do this.
            NSLog(@"%@", match.matchID);
            [match removeWithCompletionHandler:^(NSError *error)
             {
                 NSLog(@"%@", error.localizedDescription);
             }
             ];

            //disable player buttons
            [self disablePlayerButtons ];

            //stop timing either player.
            self.playerTimerTurn = 0;

            self.playerturn = 3; //when player has quit

            [statusLabel setString:[NSString stringWithFormat:@"Sorry, the intiator quit the match so it will now be deleted."]];


        }
        else
        {

            //disable player buttons
            [self disablePlayerButtons ];

            //stop timing either player.
            self.playerTimerTurn = 0;

            self.playerturn = 3; //when player has quit

            [statusLabel setString:[NSString stringWithFormat:@"Sorry, a player has quit the match so it cannot be progressed."]];

        }


        return;
    }
}
///IF PLAYER HAS QUIT EXIT MATCH ELSE CONTINUE BELOW
于 2013-06-02T19:09:05.380 回答