为Cocos2d-x增加带Button回调的系统级消息框(MessageBox)

前端之家收集整理的这篇文章主要介绍了为Cocos2d-x增加带Button回调的系统级消息框(MessageBox)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。


目标: 当点击系统消息框中的 "ok" 按钮时,可执行一段我们自己任意指定的c++代码...

实现: 修改(或添加)代码如下,


----------------------------------------------
platform/CCCommon.h

#include <functional>

// 回调类型
typedef std::function<void()> Message@R_301_460@_Callback;

// 带回调的消息框
void CC_DLL Message@R_301_460@(const char * msg,const char * title,const Message@R_301_460@_Callback & callback);


----------------------------------------------
platform/ios/CCCommon.mm

// 消息框代理
@interface Message@R_301_460@_Delegate : NSObject <UIAlertViewDelegate>
{
    Message@R_301_460@_Callback mCallback;
}
- (id)initWithCallback:(const Message@R_301_460@_Callback &)callback;
@end

@implementation Message@R_301_460@_Delegate
- (id)initWithCallback:(const Message@R_301_460@_Callback &)callback;
{
    if (self = [super init])
    {
        mCallback = callback; // 备份对象
    }
    
    return(self);
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    [alertView setDelegate: nil];
    [self autorelease];
    
    mCallback(); // 回调
}
@end

void Message@R_301_460@(const char * msg,const Message@R_301_460@_Callback & callback)
{
    Message@R_301_460@_Delegate * modalDelegate = [[Message@R_301_460@_Delegate alloc] initWithCallback: callback];
    
    NSString * tmpTitle = (title) ? [NSString stringWithUTF8String : title] : nil;
    NSString * tmpMsg = (msg) ? [NSString stringWithUTF8String : msg] : nil;
    UIAlertView * message@R_301_460@ = [[UIAlertView alloc] initWithTitle: tmpTitle
                                                          message: tmpMsg
                                                         delegate: modalDelegate
                                                cancelButtonTitle: @"OK"
                                                otherButtonTitles: nil];
    [message@R_301_460@ autorelease];
    [message@R_301_460@ show];
}


----------------------------------------------

platform/android/CCCommon.cpp

void Message@R_301_460@(const char * msg,const char * title)
{
    showDialogJNI(msg,title,0); // 回调地址为0 则不回调
}

void Message@R_301_460@(const char * msg,const Message@R_301_460@_Callback & callback)
{
    Message@R_301_460@_Callback * Callback = new Message@R_301_460@_Callback(); // 待回调后 delete
    *Callback = callback;                                       // 备份对象
    
    showDialogJNI(msg,(long long)Callback); // 将地址作为64位整型传给Java(防止日后将c++代码编译为64位版本)
}

extern "C"
{
    // 供Java回调
    JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxHandler_onDialogButtonClicked(JNIEnv* env,jobject thiz,jlong callback)
    {
        if (0 != callback)
        {
            Message@R_301_460@_Callback * Callback = (Message@R_301_460@_Callback *)callback;
            (*Callback)(); // 回调之
            
            delete Callback; // 删除对象
        }
    }
}


----------------------------------------------

Java_org_cocos2dx_lib_Cocos2dxHelper.h

extern void showDialogJNI(const char * pszMsg,const char * pszTitle,long long pCallback);


----------------------------------------------
Java_org_cocos2dx_lib_Cocos2dxHelper.cpp

void showDialogJNI(const char * pszMsg,long long pCallback)
{
    if (!pszMsg)
    {
        return;
    }

    JniMethodInfo t;
    if (JniHelper::getStaticMethodInfo(t,CLASS_NAME,"showDialog","(Ljava/lang/String;Ljava/lang/String;J)V")) // **
    {
        jstring stringArg1;

        if (!pszTitle)
        {
            stringArg1 = t.env->NewStringUTF("");
        }
        else
        {
            stringArg1 = t.env->NewStringUTF(pszTitle);
        }

        jstring stringArg2 = t.env->NewStringUTF(pszMsg);
        t.env->CallStaticVoidMethod(t.classID,t.methodID,stringArg1,stringArg2,pCallback); // 调用Java

        t.env->DeleteLocalRef(stringArg1);
        t.env->DeleteLocalRef(stringArg2);
        t.env->DeleteLocalRef(t.classID);
    }
}


----------------------------------------------

Cocos2dxHelper.java

@H_404_117@public class Cocos2dxHelper { private static void showDialog(final String pTitle,final String pMessage,final long pCallback) // 供c++调用 { Cocos2dxHelper.sCocos2dxHelperListener.showDialog(pTitle,pMessage,pCallback); } public static interface Cocos2dxHelperListener // 此接口由Cocos2dxActivity实现 { public void showDialog(final String pTitle,final long pCallback); } }


----------------------------------------------
Cocos2dxActivity.java

@H_404_117@public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelperListener { @Override public void showDialog(final String pTitle,final long pCallback) { Message msg = new Message(); msg.what = Cocos2dxHandler.HANDLER_SHOW_DIALOG; msg.obj = new Cocos2dxHandler.DialogMessage(pTitle,pCallback); this.mHandler.sendMessage(msg); } }


----------------------------------------------
Cocos2dxHandler.java

@H_404_117@public class Cocos2dxHandler extends Handler { private static LinkedList<DialogData> sDialogDataList = null; // c++ 回调 public static native void onDialogButtonClicked(long callback); private void showDialog(Message msg) { Cocos2dxActivity theActivity = this.mActivity.get(); DialogMessage dialogMessage = (DialogMessage)msg.obj; AlertDialog alertDialog = new AlertDialog.Builder(theActivity) .setCancelable(false) .setTitle(dialogMessage.titile) .setMessage(dialogMessage.message) .setPositiveButton("Ok",new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog,int which) { if (null != sDialogDataList) { Iterator<DialogData> listItr = sDialogDataList.iterator(); while (listItr.hasNext()) // 遍历list找dialog { DialogData dialogData = listItr.next(); if (dialogData.dialog == dialog) { onDialogButtonClicked(dialogData.callback); // 回调c++ listItr.remove(); // 移除 break; } } } } }) .create(); if (null == sDialogDataList) // 初始化list { sDialogDataList = new LinkedList<DialogData>(); } DialogData dialogData = new DialogData(alertDialog,dialogMessage.callback); // Dialog与callback绑定 sDialogDataList.addFirst(dialogData); // 存入list (后弹出的对话框 会先被点击 所以放在list头部 便于查询) alertDialog.show(); } private static class DialogData // dialog及对应的callback { public DialogInterface dialog; public long callback; public DialogData(DialogInterface dialog,long callback) { this.dialog = dialog; this.callback = callback; } } public static class DialogMessage { public String titile; public String message; public long callback; public DialogMessage(String title,String message,long callback) { this.titile = title; this.message = message; this.callback = callback; } } }


----------------------------------------------
调用实例

cocos2d::Message@R_301_460@("连接服务器失败","通知",[this]()
    {
        if (GGlobal::GLoginSocket->ConnectLoginServer()) // 重新请求连接
        {
            this->mTimeUsed = 0.0f;
        }
    }
);


----------------------------------------------

以上源代码文件在不同版本的cocos2d-x中可能路径略微有差别,可自行搜索定位,目前只实现了Android和iOS版,仅供参考.

猜你在找的Cocos2d-x相关文章