Integrate Gamecenter in cocos2d game - cocos2d-iphone

Is there any one who knows how to integrate game center in Cocos2d.
Please tell me steps so i can integrate that in my Game.

UPDATE:
I created my own Helper Class that works with all kind of Apps (also Cocos2D 1 & 2+)
https://github.com/alexblunck/ABGameKitHelper
Hi I suggest you use GKHelper Class from Steffen Itterheim! I uploaded the GKHelper.h / GKHelper.m for you: http://www.cl.ly/7ReW
Then follow these instructions:
//0.0 Add GameKit Framework to Project (Ask If you don't know how to do this ;) )
//0. Change "[window addSubview: viewController.view];" in the AppDelegate.m to:
//Do this if you're using any release of cocos2D after 0.99.5:
window.rootViewController = viewController;
//1. Add Gamekithelper.h / .m to project
//2. Include following delegate in given header:
<GameKitHelperProtocol>
//3. Add Delegate Methods to .m
//4. Add GameKitHelper to "Scene":
GameKitHelper *gkHelper = [GameKitHelper sharedGameKitHelper];
gkHelper.delegate = self;
[gkHelper authenticateLocalPlayer];
//Adding score to leaderboard:
GameKitHelper *gkHelper = [GameKitHelper sharedGameKitHelper];
[gkHelper submitScore:scoreValue category:#"LeaderboardID"];
//Adding achievement completion:
GameKitHelper *gkHelper = [GameKitHelper sharedGameKitHelper];
[gkHelper reportAchievementWithID:#"AchievementID" percentComplete:100];
These are the delegate Methods that need to be added mentioned in Step #3:
#pragma mark GameKitHelper delegate methods
-(void) onLocalPlayerAuthenticationChanged
{
GKLocalPlayer* localPlayer = [GKLocalPlayer localPlayer];
CCLOG(#"LocalPlayer isAuthenticated changed to: %#", localPlayer.authenticated ? #"YES" : #"NO");
if (localPlayer.authenticated)
{
GameKitHelper* gkHelper = [GameKitHelper sharedGameKitHelper];
[gkHelper getLocalPlayerFriends];
//[gkHelper resetAchievements];
}
}
-(void) onFriendListReceived:(NSArray*)friends
{
CCLOG(#"onFriendListReceived: %#", [friends description]);
GameKitHelper* gkHelper = [GameKitHelper sharedGameKitHelper];
[gkHelper getPlayerInfo:friends];
}
-(void) onPlayerInfoReceived:(NSArray*)players
{
CCLOG(#"onPlayerInfoReceived: %#", [players description]);
}
-(void) onScoresSubmitted:(bool)success
{
CCLOG(#"onScoresSubmitted: %#", success ? #"YES" : #"NO");
}
-(void) onScoresReceived:(NSArray*)scores
{
CCLOG(#"onScoresReceived: %#", [scores description]);
GameKitHelper* gkHelper = [GameKitHelper sharedGameKitHelper];
[gkHelper showAchievements];
}
-(void) onAchievementReported:(GKAchievement*)achievement
{
CCLOG(#"onAchievementReported: %#", achievement);
}
-(void) onAchievementsLoaded:(NSDictionary*)achievements
{
CCLOG(#"onLocalPlayerAchievementsLoaded: %#", [achievements description]);
}
-(void) onResetAchievements:(bool)success
{
CCLOG(#"onResetAchievements: %#", success ? #"YES" : #"NO");
}
-(void) onLeaderboardViewDismissed
{
CCLOG(#"onLeaderboardViewDismissed");
GameKitHelper* gkHelper = [GameKitHelper sharedGameKitHelper];
[gkHelper retrieveTopTenAllTimeGlobalScores];
}
-(void) onAchievementsViewDismissed
{
CCLOG(#"onAchievementsViewDismissed");
}
-(void) onReceivedMatchmakingActivity:(NSInteger)activity
{
CCLOG(#"receivedMatchmakingActivity: %i", activity);
}
-(void) onMatchFound:(GKMatch*)match
{
CCLOG(#"onMatchFound: %#", match);
}
-(void) onPlayersAddedToMatch:(bool)success
{
CCLOG(#"onPlayersAddedToMatch: %#", success ? #"YES" : #"NO");
}
-(void) onMatchmakingViewDismissed
{
CCLOG(#"onMatchmakingViewDismissed");
}
-(void) onMatchmakingViewError
{
CCLOG(#"onMatchmakingViewError");
}
-(void) onPlayerConnected:(NSString*)playerID
{
CCLOG(#"onPlayerConnected: %#", playerID);
}
-(void) onPlayerDisconnected:(NSString*)playerID
{
CCLOG(#"onPlayerDisconnected: %#", playerID);
}
-(void) onStartMatch
{
CCLOG(#"onStartMatch");
}
-(void) onReceivedData:(NSData*)data fromPlayer:(NSString*)playerID
{
CCLOG(#"onReceivedData: %# fromPlayer: %#", data, playerID);
}

You can go through with GamKit framework . Game center is very powerful for managing your online game and game score as well . with game center there are two types of game you can create
1: Real time matches (Real time Car racing)
2: Turn Base Matches (Online card game )
I am sharing with you link of RaywenderLich :
Real time match : http://www.raywenderlich.com/3276/game-center-tutorial-for-ios-how-to-make-a-simple-multiplayer-game-part-12
Turn Based Match http://www.raywenderlich.com/5480/beginning-turn-based-gaming-with-ios-5-part-1

Although Alexander Blunck's answer is reasonable, for earlier versions of iOS (such as 3.2) the following line will fault, which is not what you want.
window.rootViewController = viewController;
If you are going to use Steffen's code (ugh) then you might want to add a method to set the ui view controller directly rather than having it assume it can be grabbed via UIApplication.

Related

how to get result from .m function to .mm class Objective-C mixed with Qt

I have Qt application, I'm calling UIImagePickerController to get file path for movie the user selected. So I have static functions in Objective-C which call functions from .m file, when user selects movie I can read selected path in another .m function. Question is, how to get this filePath into some Objective-C class where I can call another Qt classes (like Singleton) and pass this result to proper class ?
Objective-C CL_image_call.mm
#include "cl_image_call.h"
#include "cl_image_func.h"
myCLImageClass* CL_image_obj=NULL;
int CL_ImageCCall::CL_objectiveC_Call() {
//Objective C code calling.....
if( CL_image_obj==NULL ) {
//Allocating the new object for the objective C class we created
CL_image_obj=[[myCLImageClass alloc]init];
}
return 1;
}
void CL_ImageCCall::CL_openMedia() {
[CL_image_obj openMedia];
}
CL_image_call.h
#include <QImage>
#include <QString>
#include <QDebug>
#include <stdio.h>
#include "my_singleton.h"
class CL_ImageCCall
{
public:
static int CL_objectiveC_Call();
static void CL_openMedia();
};
CL_image_func.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <UIKit/UIKit.h>
#import <MobileCoreServices/MobileCoreServices.h>
#interface myCLImageClass:NSObject
-(void)openMedia;
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info;
#end
CL_image_func.m
#import "cl_image_func.h"
#interface QIOSViewController : UIViewController
#end
#implementation myCLImageClass
UIImagePickerController *picker=NULL;
UIViewController *viewController=NULL;
NSString *f_path;
-(void)openMedia {
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
viewController = (UIViewController *)([keyWindow rootViewController]);
if (!viewController)
return;
if([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypePhotoLibrary]) {
picker= [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeMovie, nil];
[viewController presentViewController:picker animated:YES completion:NULL];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [docDirPath stringByAppendingPathComponent:#"movie.mov"];
NSLog (#"File Path = %#", filePath);
//filePath is what I need to pass to the rest of my app
[viewController dismissViewControllerAnimated:YES completion:nil];
}
So in CL_image_call.h I have my "my_singleton" where I can reach my whole app, but how to get filePath to this class ?
Best Regards
Marek
Here is the code to export media:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *docDirPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [docDirPath stringByAppendingPathComponent:#"movie.mov"];
NSLog (#"File Path = %#", filePath);
//filePath is what I need to pass to the rest of my app
NSURL *inputURL = [info objectForKey:UIImagePickerControllerMediaURL];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
// config the session, maybe some option is not what you need, just config by what you need
AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset
presetName:AVAssetExportPresetMediumQuality];
session.outputURL = [NSURL fileURLWithPath:filePath];
session.outputFileType = AVFileTypeMPEG4;
session.shouldOptimizeForNetworkUse = YES;
[session exportAsynchronouslyWithCompletionHandler:^(void)
{
// do a completion handler
}];
[viewController dismissViewControllerAnimated:YES completion:nil];
}
Then you can visit the output by the filePath, and use when you need.
I have modified code with your suggestion and it does what it should. I'm settings moviePath inside my Qt classes and then I call Objective-C code with this path
NSString *f_path;
//Your objective c code here....
-(void)openMedia:(NSString*)moviePath {
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
f_path=moviePath.copy;
viewController = (UIViewController *)([keyWindow rootViewController]);
if (!viewController)
return;
if([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypePhotoLibrary]) {
picker= [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
picker.mediaTypes = [NSArray arrayWithObjects:(NSString *)kUTTypeMovie, nil];
[viewController presentViewController:picker animated:YES completion:NULL];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *inputURL = [info objectForKey:UIImagePickerControllerMediaURL];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
// config the session, maybe some option is not what you need, just config by what you need
AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset
presetName:AVAssetExportPresetMediumQuality];
session.outputURL = [NSURL fileURLWithPath:f_path];
session.outputFileType = AVFileTypeMPEG4;
session.shouldOptimizeForNetworkUse = YES;
[session exportAsynchronouslyWithCompletionHandler:^(void)
{
// do a completion handler
NSLog (#"export complete = %#", f_path);
}];
[viewController dismissViewControllerAnimated:YES completion:nil];
}
with some trick I can view this movie inside Qt app. One thing that is missing:
I need to know somehow that session has been completed, to refresh file path for MediaPlayer. How can I notify my base class CL_ImageCCall about that. Or actually maybe another Objective-C++ class where I can actually mix Qt and Objective-C ?
Best Regards and thanks for Your help
Marek

Cocos2d animation resume

I've added iAP in cocos2d following the ray tutorials (but changed a few things to fit cocos2d) but after I make a transaction the console log says 2013-08-19 16:32:12.626 Game[2483:907] Buying *product* ...
2013-08-19 16:32:13.208 Game[2483:907] cocos2d: animation stopped
2013-08-19 16:32:16.690 Game[2483:907] completeTransaction...
2013-08-19 16:32:16.725 Game[2483:907] User defaults for *product* are YES
So I know the transaction works, but the game never resumes it just freezes. Is there a way to resume the game after the transaction? [[CCDirector sharedDirector]resume] doesn't work so I think it may have to do with UIAlert View. Any help? Here is my iAPHelper.mm:
#import "IAPHelper.h"
#import <StoreKit/StoreKit.h>
NSString *const IAPHelperProductPurchasedNotification
#"IAPHelperProductPurchasedNotification";
#interface IAPHelper () <SKProductsRequestDelegate, SKPaymentTransactionObserver>
#end
#implementation IAPHelper {
SKProductsRequest * _productsRequest;
RequestProductsCompletionHandler _completionHandler;
NSSet * _productIdentifiers;
NSMutableSet * _purchasedProductIdentifiers;
}
- (id)initWithProductIdentifiers:(NSSet *)productIdentifiers {
if ((self = [super init])) {
// Store product identifiers
_productIdentifiers = productIdentifiers;
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
// Check for previously purchased products
_purchasedProductIdentifiers = [NSMutableSet set];
for (NSString * productIdentifier in _productIdentifiers) {
BOOL productPurchased = [[NSUserDefaults standardUserDefaults] boolForKey:productIdentifier];
if (productPurchased) {
[_purchasedProductIdentifiers addObject:productIdentifier];
NSLog(#"Previously purchased: %#", productIdentifier);
} else {
NSLog(#"Not purchased: %#", productIdentifier);
}
}
}
return self;
}
- (void)requestProductsWithCompletionHandler:(RequestProductsCompletionHandler)completionHandler {
_completionHandler = [completionHandler copy];
_productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:_productIdentifiers];
_productsRequest.delegate = self;
[_productsRequest start];
}
#pragma mark - SKProductsRequestDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
NSLog(#"Loaded list of products...");
_productsRequest = nil;
NSArray * skProducts = response.products;
for (SKProduct * skProduct in skProducts) {
NSLog(#"Found product: %# %# %0.2f",
skProduct.productIdentifier,
skProduct.localizedTitle,
skProduct.price.floatValue);
}
_completionHandler(YES, skProducts);
_completionHandler = nil;
}
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {
NSLog(#"Failed to load list of products.");
_productsRequest = nil;
_completionHandler(NO, nil);
_completionHandler = nil;
}
- (BOOL)productPurchased:(NSString *)productIdentifier {
return [_purchasedProductIdentifiers containsObject:productIdentifier];
}
- (void)buyProduct:(SKProduct *)product {
NSLog(#"Buying %#...", product.productIdentifier);
SKPayment * payment = [SKPayment paymentWithProduct:product];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
{
for (SKPaymentTransaction * transaction in transactions) {
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchased:
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
default:
break;
}
};
}
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
NSLog(#"completeTransaction...");
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {
NSLog(#"restoreTransaction...");
[self provideContentForProductIdentifier:transaction.originalTransaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
- (void)failedTransaction:(SKPaymentTransaction *)transaction {
NSLog(#"failedTransaction...");
if (transaction.error.code != SKErrorPaymentCancelled)
{
NSLog(#"Transaction error: %#", transaction.error.localizedDescription);
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
- (void)provideContentForProductIdentifier:(NSString *)productIdentifier {
[_purchasedProductIdentifiers addObject:productIdentifier];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:productIdentifier];
[[NSUserDefaults standardUserDefaults] synchronize];
[[NSNotificationCenter defaultCenter] postNotificationName:IAPHelperProductPurchasedNotification object:productIdentifier userInfo:nil];
NSLog(#"User defaults for %# are YES", productIdentifier);
}
- (void)restoreCompletedTransactions {
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
}
#end
Before you popup your alert view try running...
[[CCDirector sharedDirector] stopAnimation];
When you get a response back from the user in the alertview callback or transaction completion run...
[[CCDirector sharedDirector] startAnimation];
Cocos doesn't often play well with UIKit/Cocoa callbacks so you need to pause rendering while they do their thing. We have similar behaviour for when the app goes into background/foreground in the app delegate...
-(void) applicationDidEnterBackground:(UIApplication*)application {
[[CCDirector sharedDirector] stopAnimation];
}
-(void) applicationWillEnterForeground:(UIApplication *)application {
[[CCDirector sharedDirector] startAnimation];
}
-(void)applicationDidBecomeActive:(UIApplication *)application {
[[CCDirector sharedDirector] resume];
}
Seems we use resume inside the applicationDidBecomeActive. Can't recall the full logic there but that has seemed to work for a bunch of our projects.

implement SLComposeViewController into Cocos2d

i can't seem to get the SLComposeViewController to come from a button on a cocos2D layer. If you could see anything that would stop this working please tell. Any help would be appreciated: N.B. viewController is a UIViewController
-(void)sceneSelect
{
NSString *message = [NSString stringWithFormat:#"Twitter Message"];
NSString *serviceType = [NSString stringWithFormat:#"SLServiceTypeTwitter"];
if ([SLComposeViewController isAvailableForServiceType:serviceType])
{
SLComposeViewController *tweetController = [SLComposeViewController composeViewControllerForServiceType:serviceType];
[tweetController setInitialText:message];
tweetController.completionHandler = ^(SLComposeViewControllerResult result){
if (result == SLComposeViewControllerResultDone){
//NSLog call
}
else if (result == SLComposeViewControllerResultCancelled){
//NSLog call
}
[viewController dismissViewControllerAnimated: YES completion: nil];
};
[[[CCDirector sharedDirector]openGLView]addSubview:viewController.view];
[viewController presentViewController:tweetController animated:YES completion:nil];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Twitter" message:#"Twitter not working" delegate:nil cancelButtonTitle:#"Dismiss" otherButtonTitles:nil];
[alertView show];
}
}
Cocos2d 2.0 then use navigation controller in AppDelegate
AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
[[app navController] presentModalViewController:tweetController animated:YES];
HERE IS MY FULL TWITTER CODE: http://pastebin.com/hpRRJM1n

Swipe Gesture used in application

I have issue regarding using swipe gesture.
Problem is that I want to perform both right and left swipe while holding click changing direction to left-right.
Can I use CCTouch methods for this condition? If yes then how can i use this? Is there another way to do this?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
...
[self createSwipeRecognizerView];
return YES;
}
-(void) createSwipeRecognizerView {
//NSLog(#"Creating Swipe Recognizer");
UIGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(screenDidswipe)];
// swipeRightOnTable is the callback method in my case
swipeRecognizer = (UISwipeGestureRecognizer *)recognizer;
// select swipe direction
swipeRecognizer.direction = UISwipeGestureRecognizerDirectionUp;
[self.navController.view addGestureRecognizer:recognizer];
recognizer.delegate = self;
[recognizer release];
}
-(BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if([[MyGame sharedGameObject].layer isKindOfClass:[MyGameScreen class]])
return YES;
return NO;
}
-(void) screenDidswipe
{
MyGame *sGame = [MyGame sharedGameObject];
if([sGame.layer isKindOfClass:[MyGameScreen class]])
{
[(MyGameScreen*)(sGame.layer) screenDidswipe];
}
}

TabBarController, overwriting shouldSelectViewController to do a segue

Hi Im trying to change the tabcontroller flow, so when a user is not loged in just take him to the login view instead the settings one. My controller extends TabBarController and I set the delegate as
self.tabBarController.delegate=self;
My Code is:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
if (login) {
LoginViewController *loginViewController = [[LoginViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:loginViewController];
[tabBarController presentViewController:loginViewController animated:YES completion:nil];
return NO;
} else {
return YES;
}
I never manage to do the navigation it gives an excetion :
ion 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <UITabBarController: 0x6a72220>.
I also tried to show the login in as a modal but it only shows a black screen:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
if (YES) {
LoginViewController *loginViewController = [[LoginViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:loginViewController];
[tabBarController presentModalViewController:navController animated:YES];
return NO;
} else {
return YES;
}
}
Can anybody help Me!!!! please!!!!
Well I manage to fix the black modal screen (still cant d a segue that is not modal).
The problem was that as I am using storyboard I have to load the view from story board as follows.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *navController = [storyboard instantiateViewControllerWithIdentifier:#"login"];
[navController setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:navController animated:YES];
That made the trick :)