Ok let's see this time how to get the MULTIPLAYER connected avatars and show them.
This tutorial is for the coders already know how to start a multiplayer game with the Game Center.
So you have the NSArray of the connected players.... (this is for 2 players game)
Important A:
You need to use the way to call the untitled view controller i shown in my template (in another post) or you need to create your way.
Important B:
In this code there is a rotation used when the old AppGameKit version had bugs on the UIInterfaceOrientation, so maybe now we
don't need it. Do some test.
UntitledViewController.h
- (void) ShowAvatars;
- (void) ShowAvatarMe;
- (void) ShowAvatarPlayer :(GKPlayer*)player;
The "version" is the iOS version when the avatars functions was added.
UntitledViewController.m
- (void) ShowAvatars
{
[self ShowAvatarMe];
GKPlayer *pl = [ListaPlayers objectAtIndex:0];
[self ShowAvatarPlayer:pl];
}
- (void) ShowAvatarMe
{
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
UIImageView *Avatar1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 420, 50, 50)];
if(version > 5){
[[GKLocalPlayer localPlayer] loadPhotoForSize:GKPhotoSizeSmall withCompletionHandler:^(UIImage *photo1, NSError *error){
if(error == nil){
[Avatar1 setImage:photo1];
} else {
UIImage *_temp = [UIImage imageNamed:@"noavatar1.png"];
[Avatar1 setImage:_temp];
}
Avatar1.transform = CGAffineTransformConcat(Avatar1.transform, CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(-90)));
[appDelegate.viewController.view insertSubview:Avatar1 atIndex:2];
Opzioni[0].avatar1 = true;
}];
} else {
UIImage *_temp = [UIImage imageNamed:@"noavatar1.png"];
[Avatar1 setImage:_temp];
Avatar1.transform = CGAffineTransformConcat(Avatar1.transform, CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(-90)));
[appDelegate.viewController.view insertSubview:Avatar1 atIndex:2];
Opzioni[0].avatar1 = true;
}
}
- (void) ShowAvatarPlayer :(GKPlayer*)player
{
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
NSString *disp = [self.RiconosciDispositivo objectAtIndex:1];
UIImageView *Avatar2 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 10, 50, 50)];
if(version > 5 && player != nil){
[player loadPhotoForSize:GKPhotoSizeSmall withCompletionHandler:^(UIImage *photo2, NSError *error){
if(error == nil){
[Avatar2 setImage:photo2];
} else {
UIImage *_temp = [UIImage imageNamed:@"noavatar2.png"];
[Avatar2 setImage:_temp];
}
Avatar2.transform = CGAffineTransformConcat(Avatar2.transform, CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(-90)));
[appDelegate.viewController.view insertSubview:Avatar2 atIndex:3];
[self DammiRankPlayer:player.playerID];
Opzioni[0].avatar2 = true;
}];
} else {
UIImage *_temp = [UIImage imageNamed:@"noavatar2.png"];
[Avatar2 setImage:_temp];
Avatar2.transform = CGAffineTransformConcat(Avatar2.transform, CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(-90)));
[appDelegate.viewController.view insertSubview:Avatar2 atIndex:3];
Opzioni[0].avatar2 = true;
}
}
After this code you have 2 (global) variables:
- Avatar1 = true;
- Avatar2 = true;
When they are both true you can change your state from "waiting avatars", for example, to the next.
This is the only reason i added this, the loading of avatar is not sync but async, so you need to wait.
Now let's see the rank.
- (void)RankPlayer :(NSString*)PlayerID
{
GKLeaderboard *query = [GKLeaderboard alloc];
query.category = @"PONG_Rank";
[query initWithPlayerIDs:[NSArray arrayWithObjects:PlayerID, nil]];
if(query != nil){
[query loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
/*if(error != nil){
NSLog(@"Errore rank.");
} else {
//NSLog(@"%@", scores);
NSLog(@"Rank : %@", scores);
}*/
if(scores != nil){
//GKScore *_sc = [scores objectAtIndex:0];
//int64_t rank = _sc.value;
if(PlayerID == [GKLocalPlayer localPlayer].playerID){
//Opzioni[0].rank1 = rank;
//rank1 = true;
} else {
//Opzioni[0].rank2 = rank;
//rank2 = true;
}
} else {
if(PlayerID == [GKLocalPlayer localPlayer].playerID){
//Opzioni[0].rank1 = 0;
//rank1 = true;
} else {
//Opzioni[0].rank2 = 0;
//rank2 = true;
}
}
}];
}
}
I use this method to get 1 score but you can edit it as you need, you can also submit a query with a range.
Of course change the category with your own.
You can also change the scope of the query and request other things like friends or who play this game.
This is the Apple example:
- (void) retrieveTopTenScores
{
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
if (leaderboardRequest != nil)
{
leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
leaderboardRequest.timeScope = GKLeaderboardTimeScopeToday;
leaderboardRequest.category = @"Combined.LandMaps"
leaderboardRequest.range = NSMakeRange(1,10);
[leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
if (error != nil)
{
// Handle the error.
}
if (scores != nil)
{
// Process the score information.
}
}];
}
}
Now let's see how to get names:
This is more complex to understand.
You need the ListPlayers array ready to be filled with the players connected.
In fact, this function is called by the GKMatchViewController delegate when a player will connect.
You can see, as i'm using it for 2 players only, it store the connected player name and change the status to the next (start fighting)...
- (void) PlayersData
{
//NSLog(@"Looking up %d players...", Match.playerIDs.count);
[GKPlayer loadPlayersForIdentifiers:Match.playerIDs withCompletionHandler:^(NSArray *players, NSError *error) {
if(error != nil){
NSLog(@"Error retrieving player info: %@", error.localizedDescription);
//multiplayer_started = NO;
} else {
ListaPlayers = [[NSMutableArray alloc] initWithArray:players];
for(GKPlayer *player in ListaPlayers){
Opzioni[0].nick_pl2 = [[NSString stringWithFormat:@"%@", player.alias] UTF8String];
NSLog(@"Found player: %@", player.playerID);
Opzioni[0].subgame_status = "";
}
}
}];
}
Those methods are very small in lines of code and work perfectly with my template.
Using my template you can call it wherever you are as the .h is included in the entire project.
If i forget to say something or you need other, don't hesitate to ask.
Long life to Steve!