由于cocos2dx-2.2.6引擎中沒有提供WebView控件,只能通過與iOS和Android交互來顯示網(wǎng)頁熊户。
需求說明:在某個Layer中點擊打開網(wǎng)頁按鈕時萍膛,在指定位置加載指定大小的網(wǎng)頁(已經(jīng)加載過的顯示出來就行);點擊Layer中其他功能按鈕時嚷堡,隱藏網(wǎng)頁蝗罗;點擊關(guān)閉Layer按鈕時移除網(wǎng)頁。
由于我們的項目是按照1136x640尺寸來橫屏布局的,所以相關(guān)的(X, Y, W, H)也是相對于1136x640尺寸來說绿饵,iOS上需要根據(jù)實際屏幕尺寸來適配欠肾。但是,cocos2dx中坐標(biāo)系與iOS中坐標(biāo)系分別是這樣的:錨點A不一樣(默認(rèn)狀態(tài)下cocos2dx中一般控件在中心點拟赊,panel刺桃、layer在左下角,也可自定義)吸祟,也就是需要設(shè)置坐標(biāo)的點瑟慈,用來確定控件的位置。傳坐標(biāo)給iOS時屋匕,就按照iOS坐標(biāo)系來傳值:X值就是控件頂點(左上角)距離左邊的距離葛碧,Y值就是控件頂點(左上角)距離頂部的距離。
另外过吻,cocos2dx中采用 ?縮放比例scale = ? screenW/1136 ?與 screenH/640 中的小值进泼;那么在iOS中也采用這種適配方式。
kResolutionShowAll ? MIN(橫向比纤虽,縱向比) 拉伸 乳绕,會出現(xiàn)黑邊
kResolutionExactFit ? 橫向按橫向比拉伸,縱向按縱向比拉伸
利用Jni實現(xiàn)C++與iOS交互
Cocos2dx游戲端:
在JniCmd.h文件中逼纸,定義消息變量:
#define CMD_CTJ_OPEN_SMALL_WEB ? ? ? ? 20114 ? ? ? ? ? ? ? //打開內(nèi)嵌網(wǎng)頁
#define CMD_CTJ_CLOSE_SMALL_WEB ? ? ? 20115 ? ? ? ? ? ? ? //關(guān)閉(隱藏)內(nèi)嵌網(wǎng)頁
#define CMD_CTJ_REMOVE_SMALL_WEB? ? 20116? ? ? ? ? ? ? //移除內(nèi)嵌網(wǎng)頁
在JniSink.h文件中聲明方法:
// 打開內(nèi)嵌網(wǎng)頁:鏈接洋措,頂點坐標(biāo)x,y杰刽,網(wǎng)頁大小w菠发,h
void OpenSmallWeb(cocos2d::CCObject *pTarget, SEL_CallFuncJni pSEL_CallFuncJni,const char*szUrl,int iX, int iY, int iWidth, int iHeight );
// 關(guān)閉內(nèi)嵌網(wǎng)頁
void CloseSmallWeb();
// 移除內(nèi)嵌網(wǎng)頁
void removeSmallWeb();
在JniSink.cpp文件中實現(xiàn)方法:
void JniSink::OpenSmallWeb( cocos2d::CCObject *pTarget, SEL_CallFuncJni pSEL_CallFuncJni,const char*szUrl, int iX, int iY, int iWidth, int iHeight )
{
????????addJniRes(pTarget, pSEL_CallFuncJni);
????????char szBuf[240];
????????sprintf(szBuf, "%s,%d,%d,%d,%d",szUrl, iX, iY, iWidth, iHeight);
????????#if ( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
????????callJavaCommand(CMD_CTJ_OPEN_SMALL_WEB, szBuf);
????????#elif ( CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
????????ObjectCHelper::share()->cppCallOc(CMD_CTJ_OPEN_SMALL_WEB, szBuf);
????????#else
????????//javaCallback(CMD_CTJ_OPEN_SMALL_WEB, "1");
????????#endif
}
void JniSink::CloseSmallWeb()
{
????????#if ( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
????????callJavaCommand(CMD_CTJ_CLOSE_SMALL_WEB, NULL);
????????#elif ( CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
????????ObjectCHelper::share()->cppCallOc(CMD_CTJ_CLOSE_SMALL_WEB, NULL);
????????#else
????????#endif
}
void JniSink::removeSmallWeb()
{
????????#if ( CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
????????callJavaCommand(CMD_CTJ_REMOVE_SMALL_WEB, NULL);
????????#elif ( CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
????????ObjectCHelper::share()->cppCallOc(CMD_CTJ_REMOVE_SMALL_WEB, NULL);
????????#else
????????#endif
}
具體的Layer中調(diào)用:
JniSink::share()->OpenSmallWeb(this, callfuncjni_selector(NewInfoLayer::JniCallback), szURL, 305, 103, 718, 452);
JniSink::share()->CloseSmallWeb();
JniSink::share()->removeSmallWeb();
iOS端,自定義WebViewHeler單利類:
把UIWebView加到[UIApplication?sharedApplication].keyWindow.rootViewController.view上贺嫂,也可以直接加到[UIApplication?sharedApplication].keyWindow上
WebViewHeler.h文件
#import<Foundation/Foundation.h>
@interface WebViewHelper : NSObject
????????@property (nonatomic, strong) UIWebView *webView;
????????@property (nonatomic, assign) BOOL? bHidden;
????????+ (instancetype)sharedWebViewHelper;
????????- (void)loadWebViewWithParam:(NSString * )param;
????????- (void)removeVebView;
@end
WebViewHeler.mm文件(.mm結(jié)尾的文件滓鸠,可進(jìn)行cocos2dx與iOS混編)
+?(instancetype)sharedWebViewHelper{
????????static?id?instance?=?nil;
????????static?dispatch_once_t?onceToken;
????????dispatch_once(&onceToken,?^{
????????????????instance?=?[[self?alloc]?init];
????????});
????????return?instance;
}
-?(void)loadWebViewWithParam:(NSString * )param{
//?分割字符串
NSArray?*arr?=?[param?componentsSeparatedByString:@","];
//?獲取鏈接字符串
NSString?*httpStr?=?arr.firstObject;
NSLog(@"httpStr?%@",?httpStr);
//?獲取生成frame
//?參數(shù)傳的是5、5s的實際像素,是物理尺寸2倍
if?(arr.count?<?5)?{
?return;
}
//?改成單倍尺寸
CGFloat?x?=?[arr[1]?floatValue]/2;
CGFloat?y?=?[arr[2]?floatValue]/2;
CGFloat?width?=?[arr[3]?floatValue]/2;
CGFloat?height?=?[arr[4]?floatValue]/2;
CGFloat?scaleX?=?kScreenWidth?/?568.0f;
CGFloat?scaleY?=?kScreenHeight?/?320.0f;
// 防止橫屏狀態(tài)下涝婉,獲取的寬和高是豎屏狀態(tài)下的寬和高哥力,目的是確定 W > H
if?(kScreenWidth?<?kScreenHeight)?{
scaleX?=?kScreenHeight?/?568.0f;
scaleY?=?kScreenWidth??/?320.0f;
}
//如果游戲按照?MIN(橫向比,縱向比) 拉伸墩弯,則 width??x ???height ??y 分別為:
CGFloat?scale?=?scaleX?<?scaleY???scaleX?:?scaleY;
width?*=?scale;
x?*=?scale;
height?*=?scale;
y?*=?scale;
//如果游戲按照橫向縱向拉伸適配吩跋,則 width?x ??height ?y 分別為:
//width?*=?scaleX;
//x?*=?scaleX;
//height?*=?scaleY;
//y?*=?scaleY;
CGRect?newframe?=?CGRectMake(x,?y,??width,?height);
NSLog(@"width?=?[%f]??height?=?[%f]??x?=?[%f]?y?=?[%f]",?width,?height,?x,?y);
//?加載網(wǎng)頁
self.webView?=?[[UIWebView?alloc]?initWithFrame:newframe];
self.webView.backgroundColor?=?[UIColor?colorWithRed:50/256.0?green:57/256.0?blue:96/256.0?alpha:1];
self.webView.scalesPageToFit?=?YES;
self.webView.scrollView.bounces?=?NO;
self.webView.delegate?=self;
//?根據(jù)需要給webView 切圓角,這里采用貝塞爾曲線
self.webView?=?[self?clipCornerWithView:self.webView?andTopLeft:YES?andTopRight:YES?andBottomLeft:YES?andBottomRight:YES];
NSURLRequest?*urlRequest?=?[[NSURLRequest?alloc]?initWithURL:[NSURL?URLWithString:httpStr]];
//?添加webView到根視圖
[[UIApplication?sharedApplication].keyWindow.rootViewController.view?addSubview:self.webView];
//?開始請求
[self.webView?loadRequest:urlRequest];
self.webView.hidden?=?true;
self.bHidden?=?true;
//?測試本地
//????[self?loadLocalHtml:self.webView?fileName:httpStr];
}
#pragma?mark?-?WebView?Delegate
-?(void)webViewDidStartLoad:(UIWebView?*)webView{
????????if?(self.webView.isLoading)?{
? ? ? ? ? ? ? return;
????????}
????????NSLog(@"開始加載");
}
-?(void)webViewDidFinishLoad:(UIWebView?*)webView{
????????if?(self.bHidden?==?false)?{
????????????????return;
????????}
????????NSLog(@"加載完成");
????????self.bHidden?=?false;
????????self.webView.hidden?=?false;
????????// 告訴Cocos2dx 加載成功
????????ObjectCHelper::share()->ocCallCpp(CMD_CTJ_OPEN_SMALL_WEB,?"1");
}
-?(void)webView:(UIWebView?*)webView?didFailLoadWithError:(NSError?*)error{
????????NSLog(@"加載失敗");
????????// 告訴Cocos2dx 加載失敗
????????ObjectCHelper::share()->ocCallCpp(CMD_CTJ_OPEN_SMALL_WEB,?"0");
? ? ? ? ?// webView加載失敗后渔工,置為nil锌钮,重新加載時會重新創(chuàng)建?
????????self.webView?=?nil;
}
iOS中 處理OC與C++交互的類 ObjectCHelper.mm文件 調(diào)用OC方法
ObjectCHelper?*ObjectCHelper::g_pObjectCHelper?=?NULL;
ObjectCHelper?*ObjectCHelper::share(){??
? ? ?if?(g_pObjectCHelper?==?NULL)?{????????
????????????g_pObjectCHelper?=?new?ObjectCHelper;???
?????}????
? ? ? return?g_pObjectCHelper;
}
std::string?ObjectCHelper::cppCallOc(const?int?cmd,?const?char?*szParam){
?????????if?(CMD_CTJ_OPEN_SMALL_WEB==?cmd){
? ? ? ?????????if(szParam){
????????????????????????// webView存在就顯示出來,不存在就重新加載
????????????????????????if([WebViewHelper?sharedWebViewHelper].webView?){
????????????????????????????????[WebViewHelper?sharedWebViewHelper].webView.hidden?=?false;
????????????????????????????????ObjectCHelper::share()->ocCallCpp(CMD_CTJ_OPEN_SMALL_WEB,?"1");
????????????????????????}else{
????????????????????????????????NSString?*strList?=?[NSString?stringWithUTF8String:szParam];
????????????????????????????????[[WebViewHelper?sharedWebViewHelper]?loadWebViewWithParam:strList];
????????????????????????}
? ? ? ? ? ? ? ? }
????????}else?if?(CMD_CTJ_CLOSE_SMALL_WEB==?cmd){
????????????????????if([WebViewHelper?sharedWebViewHelper].webView?){
????????????????????????????[WebViewHelper?sharedWebViewHelper].webView.hidden?=?true;
????????????????????}
? ? ? ? ?}else?if?(CMD_CTJ_REMOVE_SMALL_WEB==?cmd){
????????????????[[WebViewHelper?sharedWebViewHelper]?removeVebView];
????????}
}
void?ObjectCHelper::ocCallCpp(const?int?cmd,?const?char?*szParam){
? ? ? ? JniSink::share()->javaCallback(cmd,?szParam);
}