I am developing a board game. Using Game Center for multiplayer, but currently stuck at how to send or receive invitations of GKTurnBasedMatch. I am creating match programmatically using:
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.defaultNumberOfPlayers = 2;
[GKTurnBasedMatch findMatchForRequest:request
withCompletionHandler:
^(GKTurnBasedMatch *match, NSError *error) {
if(error) {
NSLog(#"%#", error.localizedDescription);
return;
}
[self.delegate startGameForMatch:match];
}];
The GKTurnBasedMatch instance in parameter of above block, has only local player with other player as nil and I need to display details of opponent in the game.
NSMutableArray *participantIds = [[NSMutableArray alloc] init];
NSLog(#"%#", match.participants);
for (GKTurnBasedParticipant *participant in match.participants) {
if(participant.playerID) [participantIds addObject:participant.playerID];
}
[GKPlayer loadPlayersForIdentifiers:participantIds
withCompletionHandler:^(NSArray *players, NSError *error) {
NSMutableString *string = [[NSMutableString alloc] init];
for (GKPlayer *player in players) {
[string appendFormat:#"---- Alias: %# DisplayName: %#", player.alias, player.displayName];
}
NSLog(#"%#", string);
}];
Am I missing something or Game Center works like this?
I read that participants of the match wont get invitations until that GKTurnBasedParticipant is GKTurnBasedMatch.currentParticipant but I need to display the details of opponent when game started.
Thanks for the help. Point me in correct direction.
This happens when you create a match against a random opponent. Try creating a second test user in iTunesConnect and signing into that user on a second device.
Then, send that second test player an invite to be your friend. This will allow you to more easily test your game with multiplayer features without having to wait for a random match to be found.
After the friend request is accepted, try creating a new game once more. Now, invite your 'Friend' to your game and start your turn. You will now notice that the (null) variables will - for the most part - be filled in. Something like this should now appear in your log-
GKTurnBasedParticipant 0xb9432e0 - playerID:G:123456789 status:Invited matchOutcome:None lastTurnDate:(null) timeoutDate:(null)
Related
I've implemented Game Center features like achievements and leaderboards, and now I'm working on the challenges. I was under the impression that I didn't have to add any additional code - if I had achievements or leaderboards, players would be able to send challenges to their friends. But now, in iOS10, you no longer have the ability to add players as friends - the challenges are handled through iMessages. The problem is - I don't see that feature anywhere in the GKViewController screen. If you select an achievement/leaaderboard score, you can tap on 'Challenge Friends', but it only suggests the players you already have in your friends list rather than in your contact list. Apple has also deprecated GKChallengesViewController, so I'm not sure where to look on how to do this.
Does anyone know how to add the iMessage Challenges feature to Game Center in iOS 10?
Update: I have seen that this feature lives within the GKMatchmakerViewController, but that seems to be for multiplayer type things. I'm still not sure how to use this to just send challenges.
From the Apple Docs:
Issuing a challenge does not display a user interface to the player issuing the challenge; this is code you need to implement yourself.
There are also a few examples on how to issue challenges and how to find players you can invite, such as:
- (void) challengePlayersToCompleteAchievement: (GKAchievement*) achievement
{
[achievement selectChallengeablePlayers:[GKLocalPlayer localPlayer].friends withCompletionHandler:^(NSArray *challengeablePlayerI, NSError *error) {
if (challengeablePlayers)
{
[self presentChallengeWithPreselectedPlayers: challengeablePlayers];
}
}];
}
...or:
- (void) challengeLesserMortalsForScore: (int64_t) playerScore inLeaderboard: (NSString*) leaderboard
{
GKLeaderboard *query = [[GKLeaderboard alloc] init];
query.leaderboardIdentifier = leaderboard;
query.playerScope = GKLeaderboardPlayerScopeFriendsOnly;
query.range = NSMakeRange(1,100);
[query loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
NSPredicate *filter = [NSPredicate predicateWithFormat:#"value < %qi",playerScore];
NSArray *lesserScores = [scores filteredArrayUsingPredicate:filter];
[self presentChallengeWithPreselectedScores: lesserScores];
}];
}
By the looks of it you still can only invite players that are already part of game center, i.e. no arbitrary "contacts" from the contact list (which makes sense), but this is only an assumption.
I make the turn-based game on Game Center.
When I search another user through auto-match function, does GameCenter search another user that this game was installed or user that have free time?
Because when I implement auto match feature on turn based game, it returns null value,
I want to know more detail about the auto match feature.
If GameCenter searches the user that game was installed and the game is not famous, then I think that auto-match can't run.
How can I implement auto-match feature programmatically?
Following codes doesn't return any user of game center.
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
[GKTurnBasedMatch findMatchForRequest: request withCompletionHandler:^(GKTurnBasedMatch *match, NSError *error)
{
if (match){
//[self performSegueWithIdentifier:#"GamePlayScene" sender:match];
NSLog(#"match id: %#", match.matchID);
}
}];
Because it has very little info on sites for auto-match feature, so please help me for auto-match.
Thanks for your help.
I´m having troubles with ending turns in my turn based game app.
The method I´m using is
GKTurnBasedMatch *currentMatch = [[GCTurnBasedMatchHelper sharedInstance] currentMatch];
[currentMatch endTurnWithNextParticipants:p turnTimeout:1000 matchData:data completionHandler:^(NSError *error) {
if (error) {
NSLog(#"%#", error);
}
}];
Here p is my NSArray for nextParticipants and this is my declaration for it:
and this is the declaration and assignment for
NSArray *p = [[currentMatch.participants reverseObjectEnumerator] allObjects];
I´m reversing the participants array to get the turn order of the players. (Only 2)
This all compile and runs without an error, but the turn never actually passes to the other player!
Thinking my p-array is the problem I´ve tried passing it without reversing it which produced the same result.
Does anyone know the correct way to handle this?
Replace your code with
GKTurnBasedMatch *currentMatch = [[GCTurnBasedMatchHelper sharedInstance] currentMatch];
GKTurnBasedParticipant *nextPerson = [currentMatch.participants objectAtIndex:((currentIndex + 1) % [currentMatch.participants count])];
[currentMatch endTurnWithNextParticipants:[NSArray arrayWithObject:nextPerson] turnTimeout:1000 matchData:matchData completionHandler:^(NSError *error) {
if (error) {
NSLog(#"%#", error);
}
}];
Why score doesn't get incremented?
GKLeaderboard *lb = [[GKLeaderboard alloc] initWithPlayerIDs:#["G:1518137155"]];
lb.category = #"top_matcher";
[lb loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
if(error == nil){
GKScore *score = [scores lastObject];
if(score) {
score.value += 40;
[score reportScoreWithCompletionHandler:^(NSError *error) {
NSLog(#"ERR: %# SC:%lld %# %# %d", error, score.value, score.playerID, score.category, scores.count);
}];
}
}
}];
I see no error in output
ERR: (null) SC:61 G:1689523782 top_matcher 1
It's clearly documented here.
Almost all classes in Game Kit that send data to or retrieve information from Game Center expect the device to have an authenticated local player. The work those classes do is always on behalf of the local player. For example, if your game reports scores to a leaderboard, it can only report a score earned by the local player.
I'm trying to enable Game Center Leaderboard to my iPad game and I have learned that you need to post more than one score to a leaderboard for the scores to show in the default leaderboard UI.
I have two separete accounts that I used to post two different scores to the same leaderboard, but when I call loadScoresWithCompletionHandler I only get one score back (the score for the user I currently are logged in with).
Any ideas why?
GKLeaderboard *myLB = [[GKLeaderboard alloc] init];
myLB.category = #"MyLeaderboardId";
myLB.timeScope = GKLeaderboardTimeScopeAllTime;
myLB.playerScope = GKLeaderboardPlayerScopeGlobal;
myLB.range = NSMakeRange(1, 100);
[myLB loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
if (error != nil)
{
NSLog(#"%#", [error localizedDescription]);
}
if (scores != nil)
{
for (GKScore *score in scores)
{
NSLog(#"%lld", score.value);
}
}
}];
It works fine for me. Just add scores under another account.
I've got:
scores (
"<GKScore: 0x960e3e0><0x960e3e0> player=G:1208389607 rank=1 date=2012-01-19 12:56:47 +0000 value=27 formattedValue=27 context=(null)",
"<GKScore: 0x96a1bc0><0x96a1bc0> player=G:1176161436 rank=2 date=2012-01-19 08:35:06 +0000 value=16 formattedValue=16 context=(null)"
)
And center by standard controller show same results.
thanks,