Note that there are some explanatory texts on larger screens.

plurals
  1. PODetermining the player who got connected in first place
    primarykey
    data
    text
    <p>In the game I'm working on I would like to give users the possibility to select between asynchronous and real-time turn-based matches. The one thing I'm missing from the latter is how do I know who's got the first turn. I'm trying to find a way to detect who's got connected first and set that player's turn automatically. Unfortunately, it seems that both players get connected at the same time since right after finding a match expectedPlayersCount yields 1 for both players and in the didChangeState event that same variable yields 0 for both of them too. So I have no way to tell who's got first to the match since it seems that it all happens simultaneously. As a temporary fix, I'm just using their IDs. The one with the lowest ID is the one having the first turn. However, I'm trying to find a better way since with this approach player A will always get the first turn when playing against player B and that represents a small advantage in my game.</p> <p>This method is what I call when starting a new game. I pass a realTime bool value to specify whether the game returned by the game center wrapper should be a GKMatch or GKTurnBasedMatch.</p> <pre><code>//Calculate the level group to find other players in the same group NSInteger levelGroup = (self.player.levelValue / STLevelSkillInterval) * STLevelSkillInterval; //Find a match for the local player [self.gameCenter findMatchWithPlayerAttributes:levelGroup realTime:realTime group:0 onCompletion:^(GKTurnBasedMatch *turnMatch, GKMatch *realTimeMatch) { [self handleTurnMatchFound:turnMatch realTimeMatch:realTimeMatch completionBlock:onCompletion]; }]; </code></pre> <p>...</p> <p>This method here is the responsible to handle game center response after finding match. The create and synchronize method stores a match instance in CoreData and also fills its data by fetching the corresponding info from Game Center and my backend. So if at the time of that's done the expected player count reached 0, I call the completion block immediately since the match can begin. Otherwise I just store the completion block so I can use it later when the other player connects to the match. The problem in that part is that it never reaches 0, not for any of the two players. </p> <pre><code>- (void)handleTurnMatchFound:(GKTurnBasedMatch *)turnMatch realTimeMatch:(GKMatch *)realTimeMatch completionBlock:(void(^)(STMatch *match, NSError *error))onCompletion { if (turnMatch != nil) { [self createAndSynchronizeLocalMatch:turnMatch onCompletion:^(STMatch *localMatch) { onCompletion(localMatch, nil); }]; } else if (realTimeMatch != nil) { [self createAndSynchronizeRealTimeLocalMatch:realTimeMatch onCompletion:^(STMatch *localMatch) { if (realTimeMatch.expectedPlayerCount == 0) { onCompletion(localMatch, nil); } else { self.findRealTimeMatchCompletionBlock = onCompletion; } }]; } else { onCompletion(nil, nil); } } </code></pre> <p>...</p> <p>This is the method that handles player's state changes. So basically here I just update the local instance of the real time match with values from the connected player and then I call the completion block stored earlier. </p> <pre><code>- (void)match:(GKMatch *)match player:(NSString *)playerID didChangeState:(GKPlayerConnectionState)state { if (state == GKPlayerStateConnected) { STMatchParticipant *placeholderParticipant = [self.realTimeMatch getMatchParticipantWithPlayerId:nil]; placeholderParticipant.playerId = playerID; placeholderParticipant.statusValue = GKTurnBasedParticipantStatusActive; //This will sync the information for the connected player only [self syncAllPlayerInfoForRealTimeMatchOnCompletion:^(NSArray *players) { self.findRealTimeMatchCompletionBlock(self.realTimeMatch, nil); }]; } else { //Notify the observers that the participant has disconnected from the match STMatchParticipant *participant = [self.realTimeMatch getMatchParticipantWithPlayerId:playerID]; for (id&lt;STTurnBasedMatchDelegate&gt; observer in self.matchesObservers) { if ([observer respondsToSelector:@selector(realTimeMatch:participantDidDisconnect:)]) { [observer realTimeMatch:self.realTimeMatch participantDidDisconnect:participant]; } } } } </code></pre> <p>I would appreciate any comments. </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload