How to call function in SomeViewController.mm from CCLayer.

Hi all,

After finishing game in cocos2dx 2.2.2, I’ve been trying to add AdMob to my game.

I was able to add subview in AppController.mm and I would like to animate ads.

Moves out of screen when game play starts and come back up when game play ends.

I wrote simple animation code and now I am wondering how I could call these functions from CCLayer.

AppController.h

@interface AppController : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    RootViewController    *viewController;
    GADBannerView * bannerView_;
}

AppController.mm

- (void) showAdView{
    NSLog(@"[AppController]: showAdView");
    [UIView animateWithDuration:1.0 animations:^ {
        
        CGRect screenRect = [[UIScreen mainScreen] bounds];
        CGFloat screenHeight = screenRect.size.height;
        // Final frame of ad should be docked to bottom of screen
        bannerView_.frame = CGRectMake(0,
                                       screenHeight-bannerView_.bounds.size.height,
                                       bannerView_.bounds.size.width,
                                       bannerView_.bounds.size.height);
    }];
}

I found some similar posts, and I think I am suppose to use something like SimpleAudioEngine. If so I must have objc.m objc.h cpp.mm cpp.h. I am uncertain what files to hustle with.

Can some one help me out here? I believe there must be simple solution but I am lost in translation.

Thank you!!!

Gene

For what I understood, you need a wrapper C++ class around a ObjectiveC object.
I used this approach for GameCenter, using this amazing post as an example:

Basically you create a C++ class (.h/.mm) in Classes and an Objective-C class (.h/.m) in the iOS folder of your project.

The C++ class is called like

MyClass *class = new MyClass();
class->showAdView();

This C++ version of showAdView is defined into MyClass.mm (.mm holds both C++ and Objective-C code) and should call something like

[[AppController shared] showAdView];

and return.
The trick is to write (in the Objective-C class .m) the shared method to get the shared instance of the Objective-C object you are looking for, something like:

+ (GameCenterIos*)shared
{
    @synchronized(self) {
        if (instance == nil) {
            instance = [[self alloc] init];
            [instance registerForAuthenticationNotification];
        }
    }
    return instance;
}

Take a look at the links, the guy who wrote those is way better than me :slight_smile:
Hope this helps! And feel free to correct me if I wrote anything wrong!

Davide Jones

@davidejones88

do you know how to hide and show admob banner in different scene?
I added codes to appcontroller.mm, but i would like to dynamically show the ad or not.

how to achieve it?

davidejones88 THank you!!!

I am digging these right now and soon to be available. Let me finish testing all and share code.

Thanks!!!

@getarobo

Hi getarobo, can’t wait to see your code…

Hi,.

@davidejones88
I finally got it work! Thank you davidejones88 again for pointer!

@fingeraction
GADBannerView inherits UIView and added to RootViewControleler through addSubview. So AdMob is independent from any CCLayer (if I am understanding it right, GADBannerView will be static and re-rendered not so often while cocos2dx view will be rendered often).
Here is my simple summary of how it added AdMob to RootViewControl.mm and how I used wrapper to call Objective C functions from CCScene.

Objective C : singleton class that handles adding animation and animating AdMob

// AdMobObject.m : use this to add, show, hide GADBannerView

#import "AdMobObject.h"
#import "RootViewController.h"
#import "GADBannerView.h"
@implementation AdMobObject
static AdMobObject* instance;
+ (AdMobObject *) shared{
    @synchronized(self){
        if( instance == nil ){
            instance = [[self alloc] init];
        }
    }
    return instance;
}
- (void) setViewController:(RootViewController *)vc{
    viewController = vc;
}
- (void) addAdMob{
    NSLog(@"----------addAdMob");
    bannerView_ = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerPortrait];
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenHeight = screenRect.size.height;
    [bannerView_ setFrame:CGRectMake(0,
                                     screenHeight - bannerView_.bounds.size.height ,
                                     bannerView_.bounds.size.width,
                                     bannerView_.bounds.size.height)];
    bannerView_.adUnitID = @"YOUR-ADMOB-ID";
    bannerView_.rootViewController = viewController;
    [viewController.view addSubview:bannerView_];
    GADRequest *request = [GADRequest request];
    // For testing
    request.testDevices = [NSArray arrayWithObjects:@"YOUR-DEVICE-ID", nil];
    [bannerView_ loadRequest:request];
}
- (void) showAdMob{
     // SHOW SOME THING
}
- (void) hideAdMob{
     // HIDE SOME THING
}
@end

//AdMobObject.h

#import <Foundation/Foundation.h>
@class RootViewController;
@class GADBannerView;
@interface AdMobObject : NSObject{
    RootViewController * viewController;
    GADBannerView * bannerView_;
}
- (void) setViewController:(RootViewController*)vc;
- (void) addAdMob;
- (void) showAdMob;
- (void) hideAdMob;
@end

Objective C++
// AdMobObjectCPP.mm : wrapper class that will call Objective-C functions

#include "AdMobObjectCPP.h"
#include "AdMobObject.h"
namespace gene  {
    void AdMobObjectCPP::showAdMob(){
        [[AdMobObject shared] showAdMob];
    }
    void AdMobObjectCPP::hideAdMob(){
        [[AdMobObject shared] hideAdMob];
    }
}

C Header
// AdMobObjectCPP.h

namespace  gene {
    class AdMobObjectCPP{
    public:
        void showAdMob();
        void hideAdMob();
    };
}

YourScene.cpp

...
//when you want to hide ad
gene::AdMobObjectCPP * admob = new gene::AdMobObjectCPP();
admob->hideAdMob();
...

I hope this helps!

GG

@getarobo
Very well done! This code could be very useful to many people! Thanks for sharing with us :slight_smile:

@getarobo

Hi getarobo, thanks for sharing.

I am interested with how to implement those two functions. Could you please advise?

- (void) showAdMob{
     // SHOW SOME THING
}
- (void) hideAdMob{
     // HIDE SOME THING
}

I got the error saying:

Must set the rootViewController property of GADBannerView before calling loadRequest

when I used your above code to implement mine.

@getarobo

just wondering where did you call this method?

- (void) setViewController:(RootViewController *)vc{
    viewController = vc;
}

@davidejones88

:frowning: Finally there are no error in console, but…ad banner never show…

unless I put the codes in Appcontroller.mm, but in that case, I couldn’t change the position of the banner.

sad…stuck on this almost a week now.

@cocos2dx wrote:

@getarobo

Hi getarobo, thanks for sharing.

I am interested with how to implement those two functions. Could you please advise?

- (void) showAdMob{
     // SHOW SOME THING
}
- (void) hideAdMob{
     // HIDE SOME THING
}

This will animate(linear move) AdMob to bottom of the screen

- (void) showAdMob{
   NSLog(@"[AppController]: showAdView");
   [UIView animateWithDuration:1.0 animations:^ {
       CGRect screenRect = [[UIScreen mainScreen] bounds];
       CGFloat screenHeight = screenRect.size.height;
       // Final frame of ad should be docked to bottom of screenqq
       bannerView_.frame = CGRectMake(0,
                                      screenHeight-bannerView_.bounds.size.height,
                                      bannerView_.bounds.size.width,
                                      bannerView_.bounds.size.height);
   }];
}

@cocos2dx wrote:

@getarobo

just wondering where did you call this method?

- (void) setViewController:(RootViewController *)vc{
    viewController = vc;
}

At AppController.mm, in function (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

add right before cocos2d::CCApplication::sharedApplication()->run();
Make sure your viewController is initialized before you initialize AdMobObject

// adMob
   adMobObject_ = [AdMobObject shared];
   [adMobObject_ setViewController:viewController];
   [adMobObject_ addAdMob];

Hope this helps :slight_smile:

GG

@getarobo

You are my hero… Thanks.