上节服务器部分已经开发完,本节开始客户端部分开发,首先是UI制作。
既然是登录验证那当然要有登录界面,UI起码也要像个游戏样子吧这里我不想用基本控件,就用cocostudio制作一个吧,cocostudio里有一个标准的登录界面如下:
为了图省事我用最新版的Cocos制作的(v2.2.8)当然你直接用cocostudio1.6导出json文件也可以,但是没有这样方便。如果你第一次使用,想用它来建立VS2012的 C++工程需要先在商店里下载一个Cocos Framework v3.6. 我们启动cocos->新建项目LoginDemo,在模板里选择登陆示例,它就自动打开cocostudio显示出这个界面了。在cocostudio我们要把一些重要控件命个命字,好在程序里使用,如用户名输入框改成txtUser,如下图:
其他的重要控件还有密码输入框命名为txtPass, 登录Login按钮改名为btnLogin, 登出按钮LoginOut没什么用不管,我们再加个注册按钮btnRegister,再加个显示登录成功与否的结果标签txtResult 类型为Text, 这一切作好后就可以发布资源了,选择“项目”->“发布与打包” 发布类型为“Visual Studio工程”如下图:
旁边的设置按钮点进去设置数据格式为 csb格式,发布内容为发布资源与项目文件,如下图:
好了点击确定发布吧,这样UI制作就算完成了,我们就到之前项目创建的路径可以打开VS工程,进行编码吧!
首先我们不要急着想如何联网,因为网络一向是个易出错的玩艺,为了不打击我们的自信心还是先把单机部分跑起来吧,说白了就是能把登录界面显示出来,但Cocos+VS已经帮我们完成了我们可以一句代码不用写,自动生成的代码如下:
bool HelloWorld::init(){ ////////////////////////////// // 1. super init first if ( !Layer::init() ) { return false; } auto rootNode = CSLoader::createNode("MainScene.csb"); addChild(rootNode); return true;}
private: cocos2d::ui::TextField* txtUser; //用户名输入框 cocos2d::ui::TextField* txtPass; //密码 cocos2d::ui::Text* lblResult; //结果标签 cocos2d::ui::Button* btnRegister; //注册按钮 cocos2d::ui::Button* btnLogin; //登录按钮 void onBtnLoginClicked(cocos2d::Ref *pSender, cocos2d::ui::Widget::TouchEventType type); //登录点击 void onBtnRegClicked(cocos2d::Ref *pSender, cocos2d::ui::Widget::TouchEventType type); //注册点击
1.以递归方式根据tag取出我们想要的控件:
Node* HelloWorld::seekNodeByTag(Node* root, int tag){ if (!root) { return nullptr; } if (root->getTag()==tag) { return root; } //获取root下所有的孩子 const auto& arrayRootChildren = root->getChildren(); ssize_t length = arrayRootChildren.size(); for (ssize_t i=0; i<length i node child="dynamic_cast<Node*">(arrayRootChildren.at(i)); if (child) { Node* res = seekNodeByTag(child, tag); //在child下递归查找tag结点 if (res!=nullptr) { return res; //找到了 } } } return nullptr;}</length>
//递归寻找在root根下以Name标记的结点Node* HelloWorld::seekNodeByName(cocos2d::Node* root, const std::string& name){ if (!root) { return nullptr; } if (root->getName() == name) { return root; } //获取root下所有的孩子 const auto& arrayRootChildren = root->getChildren(); for (auto& subWidget : arrayRootChildren) { //取出root下的一个孩子结点 Node* child = dynamic_cast<node>(subWidget); if (child) { Node* res = seekNodeByName(child, name); //在child下递归寻找name名字结点 if (res != nullptr) { return res; //找到了,就返回它 } } } return nullptr;}</node>
txtUser = dynamic_cast<textfield>(this->seekNodeByName(rootNode, "txtUser")); txtPass = dynamic_cast<textfield>(this->seekNodeByName(rootNode, "txtPass")); lblResult = dynamic_cast<text>(this->seekNodeByName(rootNode, "txtResult")); btnLogin = dynamic_cast<button>(this->seekNodeByName(rootNode, "btnLogin"));; btnRegister = dynamic_cast<button>(this->seekNodeByName(rootNode, "btnRegister")); lblResult->setString(""); btnLogin->addTouchEventListener(CC_CALLBACK_2(HelloWorld::onBtnLoginClicked, this)); //登录按钮关联单击事件 btnRegister->addTouchEventListener(CC_CALLBACK_2(HelloWorld::onBtnRegClicked, this)); //注册按钮关联单击事件</button></button></text></textfield></textfield>
为了实验下是不是我们真的取出控件了写下列实验代码,在登录按钮响应事件里这样写:
void HelloWorld::onBtnLoginClicked(cocos2d::Ref *pSender, cocos2d::ui::Widget::TouchEventType type){ switch (type) { case cocos2d::ui::Widget::TouchEventType::BEGAN: break; case cocos2d::ui::Widget::TouchEventType::MOVED: break; case cocos2d::ui::Widget::TouchEventType::ENDED: { if(txtUser->getString()=="") //用户名为空提示 { lblResult->setString("User is empty"); break; } if (txtPass->getString()=="") //密码框为空提示 { lblResult->setString("Pass is empty"); break; } lblResult->setString("click login btn"); //提示用户点击了登录 } break; case cocos2d::ui::Widget::TouchEventType::CANCELED: break; default: break; }}