这里提到的是游戏登录部分,分为两个部分,
一:UI方面的搭建:
主要为EidBox控件提供用户输入ID 和passwarld 功能,其他界面背景,logo,button等琐碎控件,总体难度较低;
二:客服之间的通信:
主要为 帐号的登录与注册,其他功能如(密码找回,邮箱验证等受制于时间与此游戏的要求暂不添加)这里采用C++与JAVA之间的jni通信,,虽然服务方提供了cocos2dx开发包,但本人在实践中遇到较多错误,另外较java原生开发包开发文档,实例教程少,所以这里采用java与C++ JNI的方式进行通迅;
UI最终效果图:
由于是游戏起始界面这里就命名为StartUI
StartUI.h 相关控件代码如下
CCSprite*Login1BG;//登陆框背景 CCSprite*Login2BG;//注册框背景 CCEditBox * IdBox;//登陆框账号输入控件 CCEditBox *PassworldBox;//登陆框密码输入控件 CCEditBox * IdBox_Register;//注册框账号输入控件 CCEditBox *PassworldBox1_Register;//注册框密码输入控件 CCEditBox *PassworldBox2_Register;//注册框密码验证控件
这里我模仿的是war 铁链上升/下降来改变显示登陆框及注册框的,登陆框放下时用户可以输入账号密码,服务器通过验证成功即可进入游戏;注册框放下时输入账号,密码,验证密码,服务器通过验证成功即可进入游戏;
想必关于界面背景、人物,logo、按钮菜单等元素的添加方法较为简单,这里就不再做叙述
问题一:输入框如何接收用户的输入呢?
解决方法:
//开始进入编辑 virtual void editBoxEditingDidBegin(cocos2d::extension::CCEditBox* editBox); //结束编辑 virtual void editBoxEditingDidEnd(cocos2d::extension::CCEditBox* editBox); //编辑框文本改变 virtual void editBoxTextChanged(cocos2d::extension::CCEditBox* editBox,const std::string& text); //当触发return后的回调函数 virtual void editBoxReturn(cocos2d::extension::CCEditBox* editBox);
CCScale9Sprite * sacel9SprY=CCScale9Sprite::create("00.png);
IdBox_Register = CCEditBox::create(CCSizeMake(207,38),sacel9SprY);
//设置文字大小 IdBox_Register->setFontSize(30); // 获取编辑框内的文字
IdBox_Register->setFontColor(ccc3(255,255,255)); 当编辑框中没有任何字符的提示 IdBox_Register->setPlaceHolder("输入账号"); CCLOG("PlaceHolder:%s",IdBox_Register->getPlaceHolder()); // 最大输入文本长度 IdBox_Register->setMaxLength(7); //设置输入模式,这里设置为普通明文输入 IdBox_Register->setInputFlag(kEditBoxInputFlagSensitive); // 设置return类型 IdBox_Register->setReturnType(kKeyboardReturnTypeDone); IdBox_Register->setPosition(ccp(510,240)); // 设置编辑框内的文字 IdBox_Register->setText(""); Login2BG-> addChild(IdBox_Register,10);
很明显的可以看出这是账号输入框的定义方法,除此外还需要用到相关函数,否则输入框无法响应用户输入行为
// 开始进入编辑 void StartUI:: editBoxEditingDidBegin(cocos2d::extension::CCEditBox*editBox) { } //结束编辑 void StartUI:: editBoxEditingDidEnd(cocos2d::extension::CCEditBox* editBox) { } //编辑框文本改变 void StartUI:: editBoxTextChanged(cocos2d::extension::CCEditBox* editBox,const std::string& text) { } //当触发return后的回调函数 void StartUI:: editBoxReturn(cocos2d::extension::CCEditBox* editBox) { }由于游戏不需要相关函数内的触发事件,这里只须调用即可
IdBox->getText()
问题二:如何把用户输入的数据传给服务器,以及注册/登陆成功后返回相关数据呢?
解决方案:这里运用了少量jni的知识:流程为:cocos2dx->java->sever->java->cocos2dx
下面是StartUI.cpp 相关的代码
void StartUI::Login2RegisterClicked(CCObject *pSender) { JniMethodInfo jnifo; bool isHave=JniHelper::getStaticMethodInfo(jnifo,"com/cxxy/SacredTerritory/SacredTerritory","initUtil","()Ljava/lang/Object;"); jobject jobj; if(isHave) { jobj = jnifo.env->CallStaticObjectMethod(jnifo.classID,jnifo.methodID); } CCLog("正确获取到了 jobj"); //获取方法信息 isHave=JniHelper::getMethodInfo(jnifo,"initUtiler","([Ljava/lang/String;)V"); if(isHave) { jclass str_cls = jnifo.env->FindClass("java/lang/String"); jstring str1 = jnifo.env->NewStringUTF("a");//标识数据无意义,供java判断传入数据类型 jstring str2 = jnifo.env->NewStringUTF(IdBox_Register->getText()); jstring str3 = jnifo.env->NewStringUTF(PassworldBox2_Register->getText()); jobjectArray arrs = jnifo.env->NewObjectArray(3,str_cls,0); jnifo.env->SetObjectArrayElement(arrs,str1); jnifo.env->SetObjectArrayElement(arrs,1,str2); jnifo.env->SetObjectArrayElement(arrs,2,str3); jnifo.env->CallVoidMethod(jobj,jnifo.methodID,arrs); } CCLog("jni执行完毕"); }
public void initUtiler(String[] str) { BmobUser bu = new BmobUser(); bu.setUsername(str[1]); bu.setPassword(str[2]); bu.signUp(this,new SaveListener() { @Override public void onSuccess() { // TODO Auto-generated method stub IsRegister("SUCCESS");//注册成功返回函数 } @Override public void onFailure(int code,String msg) { // TODO Auto-generated method stub IsRegister("WRONG");//注册失败返回函数 } }); }
这里的IsRegister()函数要在java文件中提前声明,此函数负责把数据传给cocos2dx
private static native void IsRegister(String IsLogins);
最后在cocos2dx项目文件中要同命名此函数,作为c++方面的数据处理,判断是否注册,登陆成功
#include "cocos2d.h" #include <jni.h> #include "platform/android/jni/JniHelper.h" #include "jnier.h" #include "Start/StartUI.h" #define CLASS_NAME "com/cxxy/SacredTerritory/SacredTerritory" #include "string" using namespace cocos2d; extern "C" { void Java_com_cxxy_SacredTerritory_SacredTerritory_IsLogin(JNIEnv* env,jobject thiz,jstring LoginBackMessage) { std::string strLoginBackMessage = env->GetStringUTFChars(LoginBackMessage,NULL); if(strLoginBackMessage=="SUCCESS") ShowMessageDialog("温馨提示","登录成功",false); CCLog("登录成功"); if(strLoginBackMessage=="WRONG") ShowMessageDialog("温馨提示","登录失败",false); CCLog("登录失败"); }
最后我们注册一个用户,就可以看到返回结果了,当然里面的信息框,是我在java中调用的,这里不做叙述