cocos2d-x网络编程 连接php服务器笔记3

上节服务器部分已经开发完,本节开始客户端部分开发,首先是UI制作。

UI制作

既然是登录验证那当然要有登录界面,UI起码也要像个游戏样子吧这里我不想用基本控件,就用cocostudio制作一个吧,cocostudio里有一个标准的登录界面如下:

cocos2d-x网格编程

为了图省事我用最新版的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工程,进行编码吧!

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;
}
直接编译运行就可以看到界面了,从代码看加载UI部分确实比以前cocos2d-x 3.1版简单好多。我们导出资源时导出了两个csb一个是MainScene.csb另一个是登录主体Login.csb,加载那个Login.csb是不是也行呢没试过。但这样当然是不行的,我们要取出用户名和密码输入框的内容,还要得到那几个Button控件,我们就在HelloWorldScene.h里声明这几个成员变量吧:
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); //注册点击
然后我们想办法取出csb里的控件,有两种方式一是根据tag取,一个是根据name取,官方给出了标准实现方法,如下: 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++)
	{
		//取出root下的一个孩子结点
		Node* child = dynamic_cast<Node*>(arrayRootChildren.at(i));
		if (child)
		{
			Node* res = seekNodeByTag(child, tag); //在child下递归查找tag结点
			if (res!=nullptr)
			{
				return res;  //找到了
			}
			
		}
		
	}
	return nullptr;
}
2.以名字name取出控件
//递归寻找在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;
}
好了有了工具函数了我们就可以取出控件了,在上面 bool HelloWorld::init()方法中在addChild(rootNode);下面加上下面代码:
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)); //注册按钮关联单击事件
OK这样就把控件取出了! 为了实验下是不是我们真的取出控件了写下列实验代码,在登录按钮响应事件里这样写:
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;
	}
}
写了switch一大堆但这些分支都是必要的,你要是不这样写会出现按钮按下执行点击代码,松开按钮又执行了一遍点击代码这些我们不希望看到的结果,好了编译运行点击下登录,那个红色的Result标签会提示我们"Click login btn" ,这样单机部分实验成功!





您的回应...

相关话题

查看全部

也许你感兴趣

换一批

热门标签

更多