Game Center can't find existing turn-based matches - iphone

I'm writing a turn-based iPhone game and I can't seem to find my own games.
I have three accounts trying to matchmake in my game - one on my iPhone 5, and two different Game Center test accounts created in the iPhone simulator which I switch between all playing my game through the Game Center sandbox. Unfortunately, they never find eachother and always create new games on their own. How can I fix it so they will ALWAYS find an existing match, if there is one available, and only create a new game if there are NO open games?

I'm assuming you are using GKTurnBasedMatchmakerViewController to find matches and doing something similar to this:
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
GKTurnBasedMatchmakerViewController *mmvc = [[GKTurnBasedMatchmakerViewController alloc] initWithMatchRequest:request];
mmvc.turnBasedMatchmakerDelegate = self;
[self presentViewController:mmvc animated:YES completion:nil];
In your delegate method you can do this to figure out if this was a brand new game or if you're joining an existing game:
- (void)turnBasedMatchmakerViewController:(GKTurnBasedMatchmakerViewController *)viewController didFindMatch:(GKTurnBasedMatch *)match {
int numberOfParticipants = [match.participants count];
// check the number of valid participant ids to find out if you need to know if this is a "new" game or not.
....
For match making to pair up a user with an existing game, the opponent player must have "completed" their turn by calling this method on GKTurnedBasedMatch:
- (void)endTurnWithNextParticipants:(NSArray *)nextParticipants turnTimeout:(NSTimeInterval)timeout matchData:(NSData*)matchData completionHandler:(void(^)(NSError *error))completionHandler;

Related

Real Time Game Center game disconnects (possibly because of network timeout)

So, I'm writing a very simple real time game center 2-player game; however, the problem is I keep getting disconnected.
The game works as follows: Each player has a text field on their device. They each enter text in the field and press enter. When both people have inputted text, the game progresses.
Now, when the users are actively playing the game (inputting text every 10 seconds or so), the game works just fine and a user has never been disconnected. However, when the game remains inactive (the user just sits and stares at the app screen) for about 30 seconds or more, at least one player gets disconnected.
I'm pretty confident that my Internet is solid and both devices appear to be connected to the Internet (via wifi).
I know this is a very vague question, I was just wondering if anyone has any ideas related to the symptoms in bold above.
EDIT:
Here's how I initialize the matchrequest and the match. However, I'm having no trouble initializing or starting the match. The only problem is when a player goes idle for some length of time
//toInvite may be nil
- (void) createMatchWithPlayersToInvite: (NSArray *) toInvite
{
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = 2;
request.maxPlayers = 2;
request.playersToInvite = toInvite;
GKMatchmakerViewController *mmvc = [[GKMatchmakerViewController alloc] initWithMatchRequest:request];
self.myMatchmakerVC = mmvc;
mmvc.hosted = NO;
mmvc.matchmakerDelegate = self;
[self presentViewController:mmvc animated:YES completion:nil];
}
- (void)matchmakerViewController:(GKMatchmakerViewController *)viewController didFindMatch:(GKMatch *)match
{
[self dismissViewControllerAnimated:YES completion:nil];
self.myMatch = match;
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.currentMatch = self.myMatch;
if (!self.matchStarted && match.expectedPlayerCount == 0)
{
self.matchStarted = YES;
[self performSegueWithIdentifier:#"gameSegue" sender:self];
}
}
EDIT 2:
So, I've discovered that if I set a timer and send messages across the network (with [self.myMatch sendDataToAllPlayers:data withDataMode:GKMatchSendDataReliable error:&error]) every 1 second, the program works just fine. Does anyone have idea why this is or how I can fix my issue without resorting to a hacked together NSTimer?
Other notes:
1) My AppDelegate has not been changed
Looks like you have a clear hypothesis here, i.e. that Game Center connections are closed after 30 seconds idle time. I would not be surprised if this is the case. Other games almost certainly will send data within such an interval, and you may be triggering a timeout condition. To test this hypothesis and fix the problem at the same time, I would send a short blind text every five or ten seconds.

Game Center Integration for iPhone game?

Im a beginner for developing IOS applications mainly games. I have the game completed and have submitted it to the app store. In the mere future I want to submit an update which will include game center, primarily leader boards for scores (all time, monthly, weekly, and today). I'm having trouble understanding how to integrate the completed game with game-center. Another part that is unclear to me is what do I write in the code and how does gamekit framework know which number (score) to submit to game center. If anyone could provide detailed information I'd greatly appreciate it. Thanks!
here you have a sample project
http://developer.apple.com/library/ios/#samplecode/GKTapper/Introduction/Intro.html
To send the score you have this function, score is the score, category is the name of the leaderboard you configure on itunes connect.
- (void) reportScore: (int64_t) score forCategory: (NSString*) category {
GKScore *myScoreValue = [[[GKScore alloc] initWithCategory:category] autorelease];
myScoreValue.value = score;
[myScoreValue reportScoreWithCompletionHandler:^(NSError *error){
if(error != nil){
NSLog(#"Score Submission Failed");
} else {
NSLog(#"Score Submitted");
}
}];
}
You have to use this function to send the score when your player is killed, you don't have to track if it has been the highest, but you can track if it's greater than 0;
This tutorial uses the sample project functions in his own project, take a look, it includes sending points and achivements
http://maniacdev.com/2011/05/tutorial-game-center-basics-leaderboards-and-achievements/
Game Center is available since iOS SDK 4.1
1) Open the Xcode Help.
2) On the top you should see a navigation bar, which should say "Documentation" section and move your mouse to where it says "iOS 5.1 Library"(in my case).
3) Now, move your mouse over "Networking & Internet" and click on it.
4) You now should have a list of available APIs.
After that just look around for the APIs you want, like Leaderboards, and achievements.
According to your requirements you should look for things like GKLeaderboards, and anything else you are interested in. Those documentations should link to other documentations you would need. You can find the GKLeaderboards documentation on web
Edit: The game which you developed would be showing some score to the player after each instance of the Game. Post that score to the function - (void) reportScore: (int64_t) score forCategory: (NSString*) category eg. [self.gameCenterManager reportScore:yourscore forCategory: #"yourgamecategory"];
For the GameCenterManager.h and GameCenterManager.m from this link
update score to game center use this routine.
- (void) reportScore: (int64_t) score :(NSString*) YOUR_LeaderBoard_ID
{
GKScore *scoreReporter = [[GKScore alloc] initWithCategory:YOUR_LeaderBoard_ID];
scoreReporter.value = score;
scoreReporter.context = 0;
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil)
{
IsConnectFail = true;
}else{
IsConnectFail = false;
}
}];
}

Detect when GameCenter UI is displayed

I'm trying to integrate my game with Game Center and encountered this problem:
When user is authenticated for a first time, Game Center shows its UI for setting up the profile.
My problem is that I can not detect when this windows is shown - I want to pause my game at that moment and not play any sounds.
viewWillDisapper, viewDidDisapper in UIViewController are not called, neither are any of AppDelegate methods are called at this time.
I think I know how detect alert views (using changing key window notification), but that Account windows still is not detected there.
Is there any way to do this?
Building on executor21's answer here, I put this together which seems to do the trick in early testing. You can probably adapt it into something less fragile. It is built on the premise that the Game Center notification gets its own window, and it has exactly one subview of type GKGameEventView:
+(BOOL)isGameCenterNotificationUp
{
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *win in windows)
{
NSArray *winSubViews = [win subviews];
if([winSubViews count] == 1)
{
Class gcNotificationClass = NSClassFromString(#"GKGameEventView");
if(gcNotificationClass && ([[winSubViews objectAtIndex:0] isKindOfClass:gcNotificationClass]))
{
return YES;
}
}
}
return NO;
}

Accessing the front facing camera. iPhone/iPod 4

Hey I was wondering how I can access the front facing camera. Maybe there's some guide for it?
But I don't want all buttons etc. I just want to access the from facing camera, I don't ant the button to take a photo or anything like that.
You can access the front facing camera like:
picker.cameraDevice = UIImagePickerControllerCameraDeviceFront;
Check out the UIImagePickerController Class Reference
Just set the cameraDevice property of UIImagePickerController to UIImagePickerControllerCameraDeviceFront. But you should check if the device is available.
You should initiate an AVCaptureSession and specify which AVCaptureDevice to use ( AVCaptureDevicePositionFront in your case).
Start looking for the AVCaptureSession documentation and you should have a better understanding of what to do.
Well, what "Khushbu Shah" said is right. however actually the isCameraDeviceAvailable is available only ios 4 and above. Just to ensure that you opened the front camera only if it is there, the right code block to be used is as follows.
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.delegate = self;
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
ipc.sourceType = UIImagePickerControllerSourceTypeCamera;
if([UIImagePickerController respondsToSelector:#selector(isCameraDeviceAvailable:)])
{ //check if iphone 4 and above
if([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront])
{
ipc.cameraDevice=UIImagePickerControllerCameraDeviceFront;
}
}
}
[ipc release];
First thing you need to do is to detect if your device has got front-facing camera. For that you need to iterate through the video devices.
Try this method of UIImagePickerController:
+ (BOOL)isCameraDeviceAvailable:(UIImagePickerControllerCameraDevice)cameraDevice
This is a class method and UIImagePickerControllerCameraDevice can take two values:
- UIImagePickerControllerCameraDeviceRear
- UIImagePickerControllerCameraDeviceFront
Example code:
if( [UIImagePickerController isCameraDeviceAvailable: UIImagePickerControllerCameraDeviceFront]){
// do something
}

Unlock Achievement - GameCenter iPhone

I am trying to unlock an achievement in the game i am making for the iPhone but being rather unsuccessful.
From Apples own GKTapper project sample demonstrating Game Center code I have copied the GameCenterManager.h and .m and the AppSpecificValues.h files into my project. I have successfully got loading the achievements and leaderboards for viewing.
However I can't work out or get right how to actually unlock an achievement. Could some point out how using this or without the GameCenterManager how can I unlock an achievement please?
Thanks.
- (void) reportAchievementIdentifier: (NSString*) identifier percentComplete: (float) percent
{
GKAchievement *achievement = [[[GKAchievement alloc] initWithIdentifier: identifier] autorelease];
if (achievement)
{
achievement.percentComplete = percent;
[achievement reportAchievementWithCompletionHandler:^(NSError *error)
{
if (error != nil)
{
// Retain the achievement object and try again later (not shown).
}
}];
}
}
Call this method like this:
[self reportAchievementIdentifier:indentifier percentComplete:percent];
If you want to just unlock the achievement call this:
[self reportAchievementIdentifier:indentifier percentComplete:100.0];
You can use the float for calculate the percent of the achievement, and if the user reaches the 100 the achievement gets unlocked.
You can also do this:
[self reportAchievementIdentifier:indentifier percentComplete:((actualpoints/neededPoints)*100.0)];
neededPoints means the points you need for unlock this achievement. For example:
actualPoints = 300;
neededPoints = 600;
It calculates: 300/600 = 0.5 * 100 = 50%
Btw, the "completed" property isn't always set to YES if you set percentComplete=100, at least not within the same session. I spent a while debugging why my game awarded achievements several times even when percentComplete got set to 100.