【玩转cocos2d-x之三十三】游戏嵌入Webview网页
手游《我叫MT》一开始会弹出一个游戏公告,有玩过的肯定都蛮熟悉的,这就是webview,就是一个网页。由于webview和平台相关,这里就介绍下cocos2d-x如何嵌入andorid的webview控件,在cocos2d-x中显示网页。
Jni
Jni这里我就不再多说了。可用参考wikipedia,或者微信飞机大战的移植篇。通过Jni,可以实现在cocos2d-x中调用Android的API,当然也可以进行传值。
Android使用webview
直接上代码。主要是处理布局和webview使用的问题。这里采用代码布局。以下操作在android的主类(cocos2dxActivity)中处理。
添加成员变量
整个布局的结构是最底层一个FrameLayout,ImageView控件放置在FrameLayout上。然后之上是一个LinearLayout用来放置关闭按钮,LinearLayout往下是Webview控件。
成员变量1 2 3 4 5 6
| static Test test = null; WebView m_webView; ImageView m_imageView; FrameLayout m_webLayout; LinearLayout m_topLayout; Button m_backButton;
|
OnCreate中添加FrameLayout布局
添加FrameLayout布局1 2 3 4 5 6 7 8 9 10
| protected void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); test=this;
m_webLayout = new FrameLayout(this); FrameLayout.LayoutParams lytp = new FrameLayout.LayoutParams(800,640); lytp .gravity = Gravity.CENTER; addContentView(m_webLayout, lytp); }
|
返回实例
返回实例1 2 3 4
| public static Test getInstance() { Log.v("TestJacky","getInstance"); return test; }
|
显示webview
显示webview1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public void openWebview() { Log.v("TestJacky", "openWebView"); this.runOnUiThread(new Runnable() { public void run() { m_webView = new WebView(test); m_webView.getSettings().setJavaScriptEnabled(true); m_webView.getSettings().setSupportZoom(true); m_webView.getSettings().setBuiltInZoomControls(true); m_webView.loadUrl("http://m.blog.csdn.net/blog/jackyvincefu/"); m_webView.requestFocus(); m_webView.setWebViewClient(new WebViewClient(){ public boolean shouldOverrideUrlLoading(WebView view, String url) { if(url.indexOf("tel:")<0){ view.loadUrl(url); } return true; } }); m_imageView = new ImageView(test); m_imageView.setImageResource(R.drawable.bkgnd); m_imageView.setScaleType(ImageView.ScaleType.FIT_XY); m_topLayout = new LinearLayout(test); m_topLayout.setOrientation(LinearLayout.VERTICAL); m_backButton = new Button(test); m_backButton.setBackgroundResource(R.drawable.btn); LinearLayout.LayoutParams lypt=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); lypt.gravity=Gravity.RIGHT; m_backButton.setLayoutParams(lypt); m_backButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { removeWebView(); } }); m_webLayout.addView(m_imageView); m_topLayout.addView(m_backButton); m_topLayout.addView(m_webView); m_webLayout.addView(m_topLayout); } }); }
|
移除webview
移除webview1 2 3 4 5 6 7 8 9 10 11 12 13
| public void removeWebView() { m_webLayout.removeView(m_imageView); m_imageView.destroyDrawingCache(); m_webLayout.removeView(m_topLayout); m_topLayout.destroyDrawingCache(); m_topLayout.removeView(m_webView); m_webView.destroy(); m_topLayout.removeView(m_backButton); m_backButton.destroyDrawingCache(); }
|
重写返回键
重写返回键1 2 3 4 5 6 7 8 9 10
| public boolean onKeyDown(int keyCoder,KeyEvent event) { if(m_webView.canGoBack() && keyCoder == KeyEvent.KEYCODE_BACK){ m_webView.goBack(); }else{ removeWebView(); } return false; }
|
cocos2d-x使用Jni
这里直接使用HelloWorld的示例,修改了close按钮的回调函数。
jni头文件
jni头文件1 2 3 4
| #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include <jni.h> #include "platform/android/jni/JniHelper.h" #endif
|
Jni调用打开webview
Jni调用打开webview1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| void HelloWorld::menuCloseCallback(CCObject* pSender) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) JniMethodInfo minfo; bool isHave = JniHelper::getStaticMethodInfo(minfo,"com/jacky/test/Test","getInstance","()Lcom/jacky/test/Test;"); jobject jobj; if (isHave) { jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID); isHave = JniHelper::getMethodInfo(minfo,"com/jacky/test/Test","openWebview","()V"); if (isHave) { minfo.env->CallVoidMethod(jobj, minfo.methodID); } } #else CCDirector::sharedDirector()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0); #endif #endif }
|
效果图
爪机截屏的。
ps:这里没有处理多次打开webview的情况。可以采用Jni方法来通知cocos2d-x,也可以直接在主类中设置一个成员变量标志位,调用openWebview时设置为true,removeWebView时设置为false,在调用openWebview时检测这个标志位来决定是否打开即可。
源码下载
包含win32,android代码,拿掉了android交叉编译生成的obj,保留so和apk文件。
下载地址