【玩轉cocos2d-x之三十三】遊戲嵌入Webview網頁

原創作品,轉載請標明:http://blog.csdn.net/jackystudio/article/details/17576995


手遊《我叫MT》一開始會彈出一個遊戲公告,有玩過的肯定都蠻熟悉的,這就是webview,就是一個網頁。由於webview和平臺相關,這裏就介紹下cocos2d-x如何嵌入andorid的webview控件,在cocos2d-x中顯示網頁。


1.Jni

Jni這裏我就不再多說了。可用參考wikipedia,或者微信飛機大戰的移植篇。通過Jni,可以實現在cocos2d-x中調用Android的API,當然也可以進行傳值。

2.Android使用webview

直接上代碼。主要是處理佈局和webview使用的問題。這裏採用代碼佈局。以下操作在android的主類(cocos2dxActivity)中處理

2.1.添加成員變量

整個佈局的結構是最底層一個FrameLayout,ImageView控件放置在FrameLayout上。然後之上是一個LinearLayout用來放置關閉按鈕,LinearLayout往下是Webview控件。

    static Test test  = null;//Test實例
    WebView m_webView;//WebView控件
    ImageView m_imageView;//ImageView控件
    FrameLayout m_webLayout;//FrameLayout佈局
    LinearLayout m_topLayout;//LinearLayout佈局
    Button m_backButton;//關閉按鈕

2.2.OnCreate中添加FrameLayout佈局

    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);
	}


2.3.返回實例

    public static Test getInstance() {
        Log.v("TestJacky","getInstance");
    	return test;
    }

2.4.顯示webview

    public void openWebview() {
    	Log.v("TestJacky", "openWebView");
    	this.runOnUiThread(new Runnable() {//在主線程裏添加別的控件
            public void run() {   
                //初始化webView
                m_webView = new WebView(test);
                //設置webView能夠執行javascript腳本
                m_webView.getSettings().setJavaScriptEnabled(true);            
                //設置可以支持縮放
                m_webView.getSettings().setSupportZoom(true);//設置出現縮放工具
                m_webView.getSettings().setBuiltInZoomControls(true);
                //載入URL
                m_webView.loadUrl("http://m.blog.csdn.net/blog/jackyvincefu/");
                //使頁面獲得焦點
                m_webView.requestFocus();
                //如果頁面中鏈接,如果希望點擊鏈接繼續在當前browser中響應
                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);
                //初始化線性佈局 裏面加按鈕和webView
                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();
                    }
                });
                //把image加到主佈局裏
                m_webLayout.addView(m_imageView);
                //把webView加入到線性佈局
                m_topLayout.addView(m_backButton);
                m_topLayout.addView(m_webView);                
                //再把線性佈局加入到主佈局
                m_webLayout.addView(m_topLayout);
            }
        });
    }

2.5.移除webview

    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();
    }

2.6.重寫返回鍵

    public boolean onKeyDown(int keyCoder,KeyEvent event)
    {
    	//如果網頁能回退則後退,如果不能後退移除WebView
    	if(m_webView.canGoBack() && keyCoder == KeyEvent.KEYCODE_BACK){
            m_webView.goBack();
        }else{
            removeWebView();
        }
        return false;      
    }

3.cocos2d-x使用Jni

這裏直接使用HelloWorld的示例,修改了close按鈕的回調函數。


3.1.jni頭文件

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#endif

3.2.Jni調用打開webview

void HelloWorld::menuCloseCallback(CCObject* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
	JniMethodInfo minfo;
	//getStaticMethodInfo,判斷Java靜態函數是否存在,並且把信息保存到minfo裏
	//參數1:JniMethodInfo
	//參數2:Java類包名+類名
	//參數3:Java函數名稱
	//參數4:函數參數類型和返回值類型
	bool isHave = JniHelper::getStaticMethodInfo(minfo,"com/jacky/test/Test","getInstance","()Lcom/jacky/test/Test;");
	jobject jobj;//存對象
	if (isHave) {
		//這裏的調用getInstance,返回Test類的對象。
		jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID);

		isHave = JniHelper::getMethodInfo(minfo,"com/jacky/test/Test","openWebview","()V");
		if (isHave) {
			//調用openWebview, 參數1:Test對象   參數2:方法ID
			minfo.env->CallVoidMethod(jobj, minfo.methodID);
		}
	}
#else
    CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
#endif
}


4.效果圖

爪機截屏的。






ps:這裏沒有處理多次打開webview的情況。可以採用Jni方法來通知cocos2d-x,也可以直接在主類中設置一個成員變量標誌位,調用openWebview時設置爲true,removeWebView時設置爲false,在調用openWebview時檢測這個標誌位來決定是否打開即可。

5.源碼下載

包含win32,android代碼,拿掉了android交叉編譯生成的obj,保留so和apk文件。
下載地址:http://download.csdn.net/detail/jackyvincefu/6770315

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章