Tutorial: Cocos Creator and Google Ads

Tutorial: Cocos Creator and Google Ads

This tutorial helps to quickly add Google ads into your game.

Reference documents

Please refer to the following documents before proceeding:

Some important points

  1. Android mobile games utilizing AdMob and listed on the Google Play Store earn advertising revenue.
  2. Banner advertisements are displayed in specified scenarios (such as the game homepage or custom clearance page).
  3. Incentive video advertisements are displayed in designated scenes (such as the use of props).
  4. The detection of whether the incentive video advertisement is completed, and judged whether to give players props and other rewards according to whether the advertising revenue is obtained.

Publishing with an Android project

First, Review the Publish to Native documentation.

Second, change build.gradle to add Maven with the following code:

allprojects {
    repositories {
        google()
        jcenter()
        flatDir {
            dirs 'libs'
        }
        maven {
            url "https://maven.google.com"
        }
    }
}

Third, change build.gradle to add the an implementation:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
    implementation fileTree(dir: "/Applications/CocosCreator.app/Contents/Resources/cocos2d-x/cocos/platform/android/java/libs", include: ['*.jar'])
    implementation project(':libcocos2dx')
    implementation 'com.google.android.gms:play-services-ads:17.1.1'
}

Fourth, change AndroidManifest.xml to add an ADMOB_APP_ID:

<manifest>
    <application>
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-3940256099942544~3347511713"/>
    </application>
</manifest>

Fifth, change AppActivity.java to initialize Mobile Ads:

package org.cocos2dx.javascript;

import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;

import android.os.Bundle;

import android.content.Intent;
import android.content.res.Configuration;

public class AppActivity extends Cocos2dxActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Workaround in https://stackoverflow.com/questions/16283079/re-launch-of-activity-on-home-button-but-only-the-first-time/16447508
        if (!isTaskRoot()) {
            return;
        }

        // DO OTHER INITIALIZATION BELOW
        SDKWrapper.getInstance().init(this);

        //Initialize advertising management
        AdManage.getInstance().init(this);
    }
    
    @Override
    public Cocos2dxGLSurfaceView onCreateView() {
        Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
        // TestCpp should create stencil buffer
        glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
        SDKWrapper.getInstance().setGLSurfaceView(glSurfaceView, this);

        return glSurfaceView;
    }

    @Override
    protected void onResume() {
        super.onResume();
        SDKWrapper.getInstance().onResume();
        AdManage.getInstance().onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        SDKWrapper.getInstance().onPause();
        AdManage.getInstance().onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        SDKWrapper.getInstance().onDestroy();
        AdManage.getInstance().onDestroy();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        SDKWrapper.getInstance().onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        SDKWrapper.getInstance().onNewIntent(intent);
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        SDKWrapper.getInstance().onRestart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        SDKWrapper.getInstance().onStop();
    }
        
    @Override
    public void onBackPressed() {
        SDKWrapper.getInstance().onBackPressed();
        super.onBackPressed();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        SDKWrapper.getInstance().onConfigurationChanged(newConfig);
        super.onConfigurationChanged(newConfig);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        SDKWrapper.getInstance().onRestoreInstanceState(savedInstanceState);
        super.onRestoreInstanceState(savedInstanceState);
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        SDKWrapper.getInstance().onSaveInstanceState(outState);
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onStart() {
        SDKWrapper.getInstance().onStart();
        super.onStart();
    }
}

Sixth, use the following class, AdManage.java to implement the core advertising code:

package org.cocos2dx.javascript;

import android.content.Context;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.reward.RewardItem;
import com.google.android.gms.ads.reward.RewardedVideoAd;
import com.google.android.gms.ads.reward.RewardedVideoAdListener;

public class AdManage  implements RewardedVideoAdListener  {
    private static final String AD_BANNER_UNIT_ID = "ca-app-pub-3940256099942544/6300978111"; // Banner ID
    private static final String AD_VIDEO_ID = "ca-app-pub-3940256099942544/5224354917"; // Incentive Video Advertising ID
    private static final String APP_ID = "ca-app-pub-3940256099942544~3347511713"; // app ID

    private Context mainActive = null;
    private static AdManage mInstace = null;

    private AdView mAdView;
    private LinearLayout bannerLayout;

    private RewardedVideoAd rewardedVideoAd;

    private static boolean isVideoRewarded = false;
    private static boolean isVideoClose = false;

    public static AdManage getInstance() {
        if (null == mInstace) {
            mInstace = new AdManage();
        }
        return mInstace;
    }

    public void init(Context context) {
        this.mainActive = context;

        // Initialize the advertising SDK.
        MobileAds.initialize(context, APP_ID);

        // Preload rewarded video ads
        rewardedVideoAd = MobileAds.getRewardedVideoAdInstance(context);
        rewardedVideoAd.setRewardedVideoAdListener(this);
        loadRewardedVideoAd();

        // Preload banner ads
        loadBannerAd();
    }

    /*
       Load google banner ads
     */
    public void loadBannerAd() {
        bannerLayout = new LinearLayout(this.mainActive);
        bannerLayout.setOrientation(LinearLayout.VERTICAL);

        // Create a banner ad. The ad size and ad unit ID must be set before calling loadAd.
        mAdView = new AdView(this.mainActive);
        mAdView.setAdSize(AdSize.SMART_BANNER);
        mAdView.setAdUnitId(AD_BANNER_UNIT_ID);

        // Create an ad request.
        AdRequest.Builder adRequestBuilder = new AdRequest.Builder();

        // Optionally populate the ad request builder.
        adRequestBuilder.addTestDevice(AdRequest.DEVICE_ID_EMULATOR);

        // Add the AdView to the view hierarchy.
        bannerLayout.addView(mAdView);

        // Start loading the ad.
        mAdView.loadAd(adRequestBuilder.build());

        AppActivity activity = (AppActivity)this.mainActive;
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
        params.gravity=Gravity.BOTTOM;
        activity.addContentView(bannerLayout,params);
        bannerLayout.setVisibility(View.INVISIBLE);

    }

    /*
       Show google banner ad
     */
    public static void showBannerAd(){
        AppActivity mActivity = (AppActivity)AdManage.getInstance().mainActive;
        // Make sure to operate on the UI thread
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                AdManage.getInstance().bannerLayout.setVisibility(View.VISIBLE);
            }
        });
    }

    /*
       Hide google banner ads
     */
    public static void hideBannerAd(){
        AppActivity mActivity = (AppActivity)AdManage.getInstance().mainActive;
        // Make sure to operate on the UI thread
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                AdManage.getInstance().bannerLayout.setVisibility(View.INVISIBLE);
            }
        });
    }

    /*
    Preload google video ads
     */
    public void loadRewardedVideoAd() {
        if (!rewardedVideoAd.isLoaded()) {
            rewardedVideoAd.loadAd(AD_VIDEO_ID, new AdRequest.Builder().build());
        }
    }

    /*
    Show video ads
     */
    public static void showRewardedVideo() {
        AdManage.getInstance().isVideoRewarded = false;
        AdManage.getInstance().isVideoClose = false;

        AppActivity mActivity = (AppActivity)AdManage.getInstance().mainActive;
        // Make sure to operate on the UI thread
        mActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (AdManage.getInstance().rewardedVideoAd.isLoaded()) {
                    AdManage.getInstance().rewardedVideoAd.show();
                }
            }
        });
    }

    @Override
    public void onRewardedVideoAdLeftApplication() {
        Toast.makeText(this.mainActive, "onRewardedVideoAdLeftApplication", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onRewardedVideoAdClosed() {
        AdManage.getInstance().isVideoClose = true;
        // Preload the next video ad
        loadRewardedVideoAd();
    }

    @Override
    public void onRewardedVideoAdFailedToLoad(int errorCode) {
    }

    @Override
    public void onRewardedVideoAdLoaded() {
    }

    @Override
    public void onRewardedVideoAdOpened() {
    }

    @Override
    public void onRewarded(RewardItem reward) {
        AdManage.getInstance().isVideoRewarded = true;
    }

    @Override
    public void onRewardedVideoStarted() {
    }

    @Override
    public void onRewardedVideoCompleted() {
    }

    // Used for cocos to monitor the completion of video 
    // advertisement playback
    public static boolean videoRewardedListener(){
        return AdManage.getInstance().isVideoRewarded;
    }

    // Used for cocos monitoring video ad playback to close
    public static boolean videoCloseListener(){
        return AdManage.getInstance().isVideoClose;
    }

    public void onResume() {
        mAdView.resume();
        rewardedVideoAd.resume(this.mainActive);
    }

    public void onPause() {
        mAdView.pause();
        rewardedVideoAd.pause(this.mainActive);
    }

    public void onDestroy() {
        mAdView.destroy();
        rewardedVideoAd.destroy(this.mainActive);
    }
}

Seventh, we need to get JavaScript and Java working together. Because the methods of playing and closing video ads are written Java and Cocos Creator supports JavaScript, it is necessary to allow these very different languages to work together. This can be done in a single line of code:

jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AdManage", "showRewardedVideo", "()V");

Precautions

  • In this tutorial, for the convenience of testing, the Advertising ID and Application ID are test IDs provided by Google. Remember to change these values to your own before publishing.
  • If you want to use Android Studio to run Cocos Creator packaged and compiled project files, try not to move the original directory, otherwise it is prone to a variety running errors.

Conclusion

We hope that you enjoyed this tutorial.

2 Likes