我们的游戏辛辛苦苦的写了一周,如果不赚点貌似对不起自己,但是这个项目只是作为练手的项目,学习的目的大于赚钱的目的(根本就没有赚钱的目的),更何况游戏的创意是人家的,我们只是copy过来学习一下。所以从各种角度来说,我们都应该加入第三方SDK,既可以用来学习一下第三方SDK的接入技巧,同时如果能上线也可以赚一点(只能呵呵了)。本篇博客我们就来接入一下万普的广告平台,广告平台有很多家,大家可以根据自己的喜好选择,对于各个广告平台的优劣我还不了解(留给以后学习了),希望了解的哥们留个言共同探讨一下。

1、首先去万普注册一个账号,登录后台填写应用的名称,主要是为了获取APP_ID,然后下载他的SDK,这个SDK就是他写的一些库供我们调用的,所以要根据平台下载对应的SDK,我们只在Android下接入,那就下载Android平台的SDK。在下载下来的文档中有一个他们自己的Demo和接入手册,我们可以通过他们的手册来接入广告,我使用手册的时候感觉歧义不断,而且针对的是2.x的版本,所以只好再研究研究了。

2、将我们的项目导入到eclipse中,注意这里有坑,Cocos-x-3.0以后我们还需要导入项目路径cocos2d\cocos\platform\android\java下的库,不会导入的查看它的文档,最后的效果是这样的,在工程视图处明显是有俩个项目。

用3.0实现飞机大战——加入万普广告

3、接着我们就需要导入万普的SDK了,将Demo解压包中libs目录下的 AppOffer_2.1.1.jar 放入工程指定的 libs目录。将万普demo例子中src目录下的cn.waps.extend包放到我们的工程源码目录src下,最后的工程效果是这样的。

用3.0实现飞机大战——加入万普广告

4、打开AndroidManifest.xml文件,按照文档要求添加它所需要的权限,AndroidManifest.xml截图如下。

用3.0实现飞机大战——加入万普广告

5、做完了以上的初始化工作接下来我们就来写代码了,打开源码目录下的AppActivity.java文件,在3.0以后的Cocos目录下,这个文件只有一个类,里边的实现全部是空的,就连onCreate()函数也没有,既然没有我们就在这里添加onCreate()函数,在onCreate函数中完成广告接口的初始化和调用。

//用到的一些成员变量
	private static Handler handler;
	private static Context mContext;
	private String app_id = "0171a39202ff2653c82f4d7ec4cde53a";

	protected void onCreate(Bundle savedInstanceState) {
		//先调用父类的onCreate方法
		super.onCreate(savedInstanceState);

		//给成员变量赋值
		mContext = this;
		handler = new AdHandler();

		initAds();
	}

	public void initAds(){
		//初始化广告
		AppConnect.getInstance(app_id,"baidu",this);
		// 预加载插屏广告内容(仅在使用到插屏广告的情况,才需要添加)
		AppConnect.getInstance(this).initPopAd(this);
		// 预加载自定义广告内容(仅在使用了自定义广告、抽屉广告或迷你广告的情况,才需要添加)
		AppConnect.getInstance(this).initAdInfo();
	}

	protected void onStop(){
		//关闭广告
		AppConnect.getInstance(this).close();
	}

以上的代码是用来初始化广告的,学过java和Android的同学不需要我解释,只说涉及到广告的东西,在initAds()函数中我们完成了广告的初始化,其中app_id就是在友盟的后台获得的ID,而字符串"baidu"是app_pid,官方的说法是分发渠道的ID,关于各个渠道的ID请大家查看友盟提供的文档,我要在百度上线,所以这里的渠道写的就是百度。后俩句的代码说的很明白了,友盟提供给我们很多的广告类型,有些广告在使用的时候不需要我们预先加载,但是有些是不行的,比如插屏广告和迷你广告就必须先加载再调用,我用到了这俩种类型的广告,所以加载一下。最后在onStop里边关闭广告。这样的话整个广告的生命周期我们就理清楚了,接下来就是实现调用广告的接口了。

6、为了让大家看清楚整个类,我把整个activity都贴上来了,调用广告的接口是函数showAdStatic,里边传入一个广告类型的ID,然后根据这个广告类型ID会调用handleMessage方法,关于Android的内容我了解的不多,就不误导大家了,大家只要清楚你做修改的时候在handleMessage中就好了,这个函数中的代码很简单应该去看一下。这样的话Android部分的代码我们就完成了,接下来要做的事情就是在c++代码层使用jni来调用showAdStatic函数。

public class AppActivity extends Cocos2dxActivity implements UpdatePointsNotifier{

	//用到的一些成员变量
	private static Handler handler;
	private static Context mContext;
	private String app_id = "0171a39202ff2653c82f4d7ec4cde53a";

	protected void onCreate(Bundle savedInstanceState) {
		//先调用父类的onCreate方法
		super.onCreate(savedInstanceState);

		//给成员变量赋值
		mContext = this;
		handler = new AdHandler();

		initAds();
	}

	public void initAds(){
		//初始化广告
		AppConnect.getInstance(app_id,"baidu",this);
		// 预加载插屏广告内容(仅在使用到插屏广告的情况,才需要添加)
		AppConnect.getInstance(this).initPopAd(this);
		// 预加载自定义广告内容(仅在使用了自定义广告、抽屉广告或迷你广告的情况,才需要添加)
		AppConnect.getInstance(this).initAdInfo();
	}

	protected void onStop(){
		//关闭广告
		AppConnect.getInstance(this).close();
	}

	@Override
	public void getUpdatePoints(String arg0, int arg1) {
	}

	@Override
	public void getUpdatePointsFailed(String arg0) {
	}

	// 向handler发送要展示Banner的消息
	public static void showAdStatic(int adTag) {
		Message msg = handler.obtainMessage();
		// 私有静态的整型变量,开发者请自行定义值
		msg.what = adTag;
		handler.sendMessage(msg);
	}

	class AdHandler extends Handler{
		public void handleMessage(Message msg) {
			switch (msg.what){
			case 0:
				// 显示推荐列表(综合)
				AppConnect.getInstance(mContext).showOffers(mContext);
				break;
			case 1:
				// 显示插屏广告
				// 判断插屏广告是否已初始化完成,用于确定是否能成功调用插屏广告
				boolean hasPopAd = AppConnect.getInstance(mContext).hasPopAd(mContext);
				if (hasPopAd) {
					AppConnect.getInstance(mContext).showPopAd(mContext);
				}
				break;
			case 2:
				// 显示推荐列表(软件)
				AppConnect.getInstance(mContext).showAppOffers(mContext);
				break;
			case 3:
				// 显示推荐列表(游戏)
				AppConnect.getInstance(mContext).showGameOffers(mContext);
				break;
			case 4:
				// 获取全部自定义广告数据
				break;
			case 5:
				// 获取一条自定义广告数据
				AdInfo adInfo = AppConnect.getInstance(mContext).getAdInfo();
				AppDetail.getInstanct().showAdDetail(mContext, adInfo); break;
			case 6:
				// 消费虚拟货币.
				AppConnect.getInstance(mContext).spendPoints(10,AppActivity.this);
				break;
			case 7:
				// 奖励虚拟货币
				AppConnect.getInstance(mContext).awardPoints(10,AppActivity.this);
				break;
			case 8:
				// 显示自家应用列表
				AppConnect.getInstance(mContext).showMore(mContext);
				break;
			case 9:
				// 根据指定的应用app_id展示其详情
				AppConnect.getInstance(mContext).showMore(mContext,app_id);
				break;
			case 10:
				// 调用功能广告接口(使用浏览器接口)
				String uriStr = "http://www.baidu.com"; AppConnect.getInstance(mContext).showBrowser(mContext,uriStr);
				break;
			case 11:
				// 用户反馈
				AppConnect.getInstance(mContext).showFeedback(mContext);
				break;
			case 12:
				// 退屏广告
				QuitPopAd.getInstance().show(mContext);
				break;
			case 13:
				// banner
				AppConnect.getInstance(mContext).showBannerAd(mContext,getBannerAd());
				break;
			case 14:
				// 迷你广告
				AppConnect.getInstance(mContext).showMiniAd(mContext,getMiniAd(), 10);
				break;
			}
		}

		//添加互动广告
		private LinearLayout getBannerAd(){
			// 互动广告
			LinearLayout adBannerLayout = new LinearLayout(mContext);
			adBannerLayout.setOrientation(LinearLayout.VERTICAL);
			FrameLayout.LayoutParams lp_banner = new FrameLayout.LayoutParams(
			FrameLayout.LayoutParams.FILL_PARENT,
			FrameLayout.LayoutParams.WRAP_CONTENT);
			// 设置adBannerLayout的悬浮位置,具体的位置开发者根据需要设置
			lp_banner.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
			AppActivity.this.addContentView(adBannerLayout, lp_banner);

			LinearLayout bannerLayout = new LinearLayout(mContext);
			adBannerLayout.addView(bannerLayout);

			return bannerLayout;
		}

		//添加迷你广告
		private LinearLayout getMiniAd(){
			LinearLayout adMiniLayout = new LinearLayout(mContext);
			adMiniLayout.setOrientation(LinearLayout.VERTICAL);
			FrameLayout.LayoutParams lp_mini = new FrameLayout.LayoutParams(
			FrameLayout.LayoutParams.FILL_PARENT,
			FrameLayout.LayoutParams.WRAP_CONTENT);
			// 设置adMiniLayout的悬浮位置,具体的位置开发者根据需要设置
			lp_mini.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
			AppActivity.this.addContentView(adMiniLayout, lp_mini);
			LinearLayout miniLayout = new LinearLayout(mContext);
			adMiniLayout.addView(miniLayout);

			return miniLayout;
		}
	}
}

7、回到c++代码层,我们新建文件WapsAd.h和WapsAd.cpp,在这里我们写一个接口根据指定的广告ID值来调用不同类型的广告。用到的技术主要是jni,关于代码如果理解如果你懂jni的话应该是很简单的,不懂的童鞋如果仅仅是为了实现功能可以搬来我的使用,如果想刨根问底请看我关于jni的博客。本人自认为写的很详细了,看完了以后对以下的代码绝对理解。

//
//  WapsAd.h
//  Plane
//
//  Created by gaohuang on
//
//

#ifndef __Plane__WapsAd__
#define __Plane__WapsAd__

#include <cocos2d.h>
using namespace cocos2d;

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

#include "platform/android/jni/JniHelper.h"
#include <jni.h>

#endif

class WapsAd
{
public:
    WapsAd();
    virtual ~WapsAd();
    //通过JNI调用JAVA静态函数,实现展示AD
    static void showAd(int adTag);

};

#endif /* defined(__Plane__WapsAd__) */
//
//  WapsAd.cpp
//  Plane
//
//  Created by gaohuang on
//
//
#include "WapsAd.h"

WapsAd::WapsAd(){}

WapsAd::~WapsAd(){}

void WapsAd::showAd(int adTag)
{

    //判断当前是否为Android平台 JniMethodInfo showAd;
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    JniMethodInfo minfo;
    bool isHave = JniHelper::getStaticMethodInfo(minfo,"org/cocos2dx/cpp/AppActivity","showAdStatic", "(I)V");
    if(!isHave)
    {
        CCLog("jni:showAdStatic is null");
    }
    else
    {
        //调用此函数
        minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID,adTag);
    }
#endif
}

8、现在是万事具备只差调用了,我们在自己认为合理的地方调用WapsAd::showAd(14),里边的参数就是广告类型的ID(在调用的类里边记住包含WapsAd头文件)。首页我不准备显示广告内容,在分数榜处我显示一个迷你广告,在关于作者的地方我显示一个banner广告,在游戏结束的时候我显示一个插屏广告,最后的效果如图所示。

用3.0实现飞机大战——加入万普广告 用3.0实现飞机大战——加入万普广告 用3.0实现飞机大战——加入万普广告 用3.0实现飞机大战——加入万普广告 用3.0实现飞机大战——加入万普广告代码已经放到了GitHub上,大家可以到GitHub上下载。关于广告不同的应用市场要求不一样,加了广告上某些市场是上不去的,加的广告太多对用户体验又不好,这里只是学一下技术,对于设计慢慢斟酌吧!