Recently I put out two games, The Chaotic Workshop and Pew Zoom Boom, which both have with a free ad supported version. There’s lots of support and examples for native code, but to get them working with MonoGame and Xamarin in C# took a bit of searching through Forums and trial and error to get it working across all platforms.
What I opted for was a single AdManager class which which encapsulated everything needed for loading and showing ads for any and all platforms.
Setting Up
First, since the ads would be shown overtop of the game view, it was required to set up the platform specific Views which would hold the ads themselves.
As you can see below, iOS is rather straightforward, but for Android, the constructor is a little more involved. We need to get the GameView, as well as create an AdContainer, and then place both of them into the original mainview. This AdContainer is for the BannerAd that we’ll add later.
[code language=”javascript”]
///
/// Initialise a new AdMob Ad Overlay. This is a Cross platform method which will run on both Android and iOS.
///
/// The host game to et the service container from
/// The location to place the add on the screen
public AdManager(Game Game, Vector2 location)
{
this.Game = Game;
#if __ANDROID__
//Interstitial Ads
mInterstitialAd = new InterstitialAd(Game.Activity);
// Get the Game View
GameView = (View)Game.Services.GetService(typeof(View));
// Create the Ad Container
AdContainer = new LinearLayout(Game.Activity)
{
Orientation = Orientation.Horizontal
};
AdContainer.SetGravity(GravityFlags.CenterHorizontal | GravityFlags.Bottom);
AdContainer.SetBackgroundColor(Android.Graphics.Color.Transparent); // Need on some devices, not sure why
//AdContainer.AddView(RewardedVideoAd);
// A layout to hold the ad container and game view
var mainLayout = new FrameLayout(Game.Activity);
mainLayout.AddView(GameView);
mainLayout.AddView(AdContainer);
Game.Activity.SetContentView(mainLayout);
#elif __IOS__
ViewController = Game.Services.GetService(typeof(UIViewController)) as UIViewController;
Location = new CGPoint(location.X, location.Y);
#endif
}
[/code]
Banner Ads
Banner ads are great because they provide ads while, if designed properly, shouldn’t impede the players enjoyment of the game.
Below here is how the Banner Ads are set up.
[code language=”javascript”]
///
/// Adds the banner.
///
/// Ad unit identifier.
/// Location.
public void InitBanner(string adUnitID, Vector2 Location)
{
#if __ANDROID__
// Must be here for Android
Location = Vector2.One;
// The actual ad view
var bannerAd = new AdView(Game.Activity)
{
AdUnitId = adUnitID,
AdSize = AdSize.SmartBanner,
};
// Load a New Ad
bannerAd.LoadAd(new AdRequest.Builder()
#if DEBUG
// Prevents generating real impressions while testing
.AddTestDevice(“DEADBEEF9A2078B6AC72133BB7E6E177”)
#endif
.Build());
// Add the banner view to the AdContainer.
AdContainer.AddView(bannerAd);
#elif __IOS__
this.Location = new CGPoint(Location.X, Location.Y);
// Setup your BannerAdView
AdViewBanner = new BannerView(size: AdSizeCons.Banner, origin: this.Location)
{
AdUnitID = adUnitID,
RootViewController = ViewController
};
// Setup Events
AdViewBanner.AdReceived += (object sender, EventArgs e) =>
{
if (!isAddOnScreen)
ViewController.View.AddSubview(AdViewBanner);
isAddOnScreen = true;
AdsAreBeingReceived = true;
};
AdViewBanner.ReceiveAdFailed += (object sender, BannerViewErrorEventArgs e) =>
{
Console.WriteLine(e.Error.DebugDescription);
};
Request request = Request.GetDefaultRequest();
#if DEBUG
request.TestDevices = new[] { “GAD_SIMULATOR_ID”, “kGADSimulatorID” };
#endif
// Load Ad
AdViewBanner.LoadRequest(request);
#endif
}
[/code]
Here we place the BannerAd as well as pass the Adunit ID from Admob.
Once we’ve set up the BannerAd Views for each platform, we need to then tell the banner ad view to load ads. This is done differently is each platform.
Note: it’s really important you use TestDevice IDs as well as Googles test adunit ID, so that you don’t pick up false impressions and also so AdMob doesn’t ban you! This method has seemed to be working for me, but double check on your own system.
There’s no need to call a Show() method or anything, it will start showing banner ads as soon as some are loaded.
Below you can see a version of the test ad working in Pew Zoom Boom on Android.
Interstitial Ads
Intersitital Ads are good to show during transitions in your game, such as between levels or during a game over. We use them in The Chaotic Workshop and Pew Zoom Boom at the end of every other level.
Initialising
First job is to Initialise the Interstitial Ads.
[code language=”javascript”]
///
/// Adds the initerstialel ad.
///
/// Ad unit identifier.
public void InitIniterstialelAd(string adUnitID)
{
this.AdUnitID = adUnitID;
#if __ANDROID__
try
{
mInterstitialAd.AdUnitId = adUnitID;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
mInterstitialAd.AdListener = new AdListener();
#elif __IOS__
// Intersitials must be re-instantiated each time
// the ad’s are loaded.
#endif
LoadIniterstialelAd();
}
[/code]
Note: for iOS this is handled very differently. Each time you show an Interstitial Ad, you need to instantiate the InterestitialAd object. Otherwise it will throw errors. The way i’ve set it up is this is done each time ‘LoadIniterstialelAd’ is called.
Loading
Much the same way banner ads are handled, here we create a request object and then load the ad. For Interstitial Ads though, you need to check if an ad has been loaded yet before showing it.
Note how we call ‘AdViewInterstitial = new Interstitial(this.AdUnitID);’ here for iOS. As I said before, you need to Re-instantiate the ‘Interstitial’ object each time you want to load an ad.
[code language=”javascript”]
public void LoadIniterstialelAd()
{
#if __ANDROID__
if (mInterstitialAd.IsLoaded==false)
{
var adRequest = new AdRequest.Builder()
#if DEBUG
.AddTestDevice(“DEADBEEF9A2078B6AC72133BB7E6E177”) // Prevents generating real impressions while testing
#endif
.Build();
mInterstitialAd.LoadAd(adRequest);
}
#elif __IOS__
Request request = Request.GetDefaultRequest();
#if DEBUG
request.TestDevices = new[] { “GAD_SIMULATOR_ID”, “kGADSimulatorID” };
#endif
if (AdViewInterstitial == null || AdViewInterstitial.HasBeenUsed == true)
{
Console.WriteLine(“Creating AdViewInterstitial”);
AdViewInterstitial = new Interstitial(this.AdUnitID);
AdViewInterstitial.AdReceived += (object sender, EventArgs e) =>
{
Console.WriteLine(“Add Recived”);
};
AdViewInterstitial.ScreenDismissed += delegate
{
Console.WriteLine(“Dissmised”);
Engine.Pause = false;
};
AdViewInterstitial.ReceiveAdFailed += (object sender, InterstitialDidFailToReceiveAdWithErrorEventArgs e) =>
{
Console.WriteLine(e.Error.DebugDescription);
};
AdViewInterstitial.LoadRequest(request);
}
#endif
}
[/code]
Showing The Ads
We’re now ready to show the ads. The Android Interstitial Ad object is instantiated in the constructor, and therefore the only check is for whether there is an ad loaded.
For iOS, since the ‘Interstitial’ object is re-instantiated each time we call it, we need to do a few more checks, but the method is essentially the same.
[code language=”javascript”]
///
/// Shows the initersial ad if there’s one loaded.
///
public void ShowInitersialAd()
{
#if __ANDROID__
if (mInterstitialAd.IsLoaded)
{
mInterstitialAd.Show();
}
#elif __IOS__
try
{
if (AdViewInterstitial != null)
{
if (AdViewInterstitial.IsReady)
{
UIViewController viewController = Game.Services.GetService(typeof(UIViewController)) as UIViewController;
AdViewInterstitial.PresentFromRootViewController(viewController);
}
}
}
catch
{
Console.WriteLine(“Error Showing Ad”);
}
#endif
[/code]
One other thing to be aware of, in Android, when the Interstitial Ads are shown, the game is paused, where as in iOS the game continues to run. It’s important to set up a method where the game is paused until the Interstitial Ad is closed.
Below here, you can see the test Interstitial Ad showing:
So there you go. You can get a copy of the full AdManager here.
If you like what you read, give me a follow, or keep up with me on Twitter.