#ifndef __LOGIN_REGISTER_SCENE_H__
#define __LOGIN_REGISTER_SCENE_H__
#include "cocos2d.h"
#include "ui\CocosGUI.h"
#include "network/HttpClient.h"
using namespace cocos2d::network;
using namespace cocos2d::ui;
USING_NS_CC;
class LoginRegisterScene : public cocos2d::Scene {
public:
static cocos2d::Scene* createScene();
virtual bool init();
void loginButtonCallback(Ref *pSender);
void registerButtonCallback(Ref *pSender);
void onHttpRequestCompleted(HttpClient *sender, HttpResponse *response);
void onHttpRequestCompleted1(HttpClient *sender, HttpResponse *response);
// implement the "static create()" method manually
CREATE_FUNC(LoginRegisterScene);
Label *messageBox;
private:
TextField *usernameInput;
TextField *passwordInput;
};
#endif // !__LOGIN_REGISTER_SCENE_H__
#include "LoginRegisterScene.h"
#include "ui\CocosGUI.h"
#include "network\HttpClient.h"
#include "json\document.h"
#include "Utils.h"
USING_NS_CC;
using namespace cocos2d::network;
using namespace cocos2d::ui;
cocos2d::Scene * LoginRegisterScene::createScene() {
return LoginRegisterScene::create();
}
bool LoginRegisterScene::init() {
if (!Scene::init()) {
return false;
}
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
auto loginButton = MenuItemFont::create("Login", CC_CALLBACK_1(LoginRegisterScene::loginButtonCallback, this));
if (loginButton) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + loginButton->getContentSize().height / 2;
loginButton->setPosition(Vec2(x, y));
}
auto registerButton = MenuItemFont::create("Register", CC_CALLBACK_1(LoginRegisterScene::registerButtonCallback, this));
if (registerButton) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + registerButton->getContentSize().height / 2 + 100;
registerButton->setPosition(Vec2(x, y));
}
auto backButton = MenuItemFont::create("Back", [] (Ref* pSender) {
Director::getInstance()->popScene();
});
if (backButton) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + visibleSize.height - backButton->getContentSize().height / 2;
backButton->setPosition(Vec2(x, y));
}
auto menu = Menu::create(loginButton, registerButton, backButton, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
usernameInput = TextField::create("username", "arial", 24);
if (usernameInput) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + visibleSize.height - 100.0f;
usernameInput->setPosition(Vec2(x, y));
this->addChild(usernameInput, 1);
}
passwordInput = TextField::create("password", "arial", 24);
if (passwordInput) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + visibleSize.height - 130.0f;
passwordInput->setPosition(Vec2(x, y));
this->addChild(passwordInput, 1);
}
messageBox = Label::create("", "arial", 30);
if (messageBox) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + visibleSize.height - 200.0f;
messageBox->setPosition(Vec2(x, y));
this->addChild(messageBox, 1);
}
return true;
}
//登录函数
void LoginRegisterScene::loginButtonCallback(cocos2d::Ref * pSender) {
// Your code here
//对应着服务端的username和password,传入json格式的数据
std::string username = usernameInput->getStringValue();
std::string password = passwordInput->getStringValue();
std::string postData = "{\"username\":\"" + username + "\"," + "\"password\":\"" + password + "\"}";
//用post方式传输,根据ppt里面的提示,用auth
HttpRequest* request = new HttpRequest();
request->setUrl("http://127.0.0.1:8000/auth");
request->setRequestType(HttpRequest::Type::POST);
request->setResponseCallback(CC_CALLBACK_2(LoginRegisterScene::onHttpRequestCompleted, this));
request->setRequestData(postData.c_str(), strlen(postData.c_str()));
//这里就是使用Cookies的地方,只要加这一句就好,可以在报头看到
//在登录的时候加上cookies就可以,这样服务端就可以记录正在使用的客户
//作为切换用户的标识
cocos2d::network::HttpClient::getInstance()->enableCookies(NULL);
cocos2d::network::HttpClient::getInstance()->send(request);
request->release();
}
//登录的回调函数,主要看返回的状态
void LoginRegisterScene::onHttpRequestCompleted(HttpClient *sender, HttpResponse *response)
{
if (!response) {
usernameInput->setString("not 200");
return;
}
auto buffer = response->getResponseData();
rapidjson::Document doc;
doc.Parse(buffer->data(),buffer->size());
if (doc["status"] == true) {
this->messageBox->setString("Login OK");
}
else {
this->messageBox->setString(std::string("Login Failed\n") + doc["msg"].GetString());
}
}
//注册函数
void LoginRegisterScene::registerButtonCallback(Ref * pSender) {
// Your code here
//和登录函数差不多
std::string username = usernameInput->getStringValue();
std::string password = passwordInput->getStringValue();
std::string postData = "{\"username\":\"" + username + "\"," + "\"password\":\"" + password + "\"}";
//用Post传输方式,根据PPT里面的提示用users
HttpRequest* request = new HttpRequest();
request->setUrl("http://127.0.0.1:8000/users");
request->setRequestType(HttpRequest::Type::POST);
request->setResponseCallback(CC_CALLBACK_2(LoginRegisterScene::onHttpRequestCompleted1, this));
request->setRequestData(postData.c_str(), strlen(postData.c_str()));
cocos2d::network::HttpClient::getInstance()->send(request);
request->release();
}
//注册的回调函数,主要显示信息
void LoginRegisterScene::onHttpRequestCompleted1(HttpClient *sender, HttpResponse *response)
{
auto buffer = response->getResponseData();
rapidjson::Document doc;
doc.Parse(buffer->data(), buffer->size());
if (doc["status"] == true) {
this->messageBox->setString("Register OK");
}
else {
this->messageBox->setString(std::string("Register Failed\n") + doc["msg"].GetString());
}
}
#pragma once
#ifndef __USER_INFO_SCENE_H__
#define __USER_INFO_SCENE_H__
#include "cocos2d.h"
#include "ui\CocosGUI.h"
#include "network/HttpClient.h"
using namespace cocos2d::network;
USING_NS_CC;
using namespace cocos2d::ui;
class UsersInfoScene : public cocos2d::Scene{
public:
static cocos2d::Scene* createScene();
virtual bool init();
void getUserButtonCallback(Ref *pSender);
void onHttpRequestCompleted(HttpClient *sender, HttpResponse *response);
CREATE_FUNC(UsersInfoScene);
TextField *limitInput;
Label *messageBox;
};
#endif // !__USER_INFO_SCENE_H__
#include "UsersInfoScene.h"
#include "network\HttpClient.h"
#include "json\document.h"
#include "Utils.h"
using namespace cocos2d::network;
using namespace rapidjson;
cocos2d::Scene * UsersInfoScene::createScene() {
return UsersInfoScene::create();
}
bool UsersInfoScene::init() {
if (!Scene::init()) return false;
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
auto getUserButton = MenuItemFont::create("Get User", CC_CALLBACK_1(UsersInfoScene::getUserButtonCallback, this));
if (getUserButton) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + getUserButton->getContentSize().height / 2;
getUserButton->setPosition(Vec2(x, y));
}
auto backButton = MenuItemFont::create("Back", [](Ref* pSender) {
Director::getInstance()->popScene();
});
if (backButton) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + visibleSize.height - backButton->getContentSize().height / 2;
backButton->setPosition(Vec2(x, y));
}
auto menu = Menu::create(getUserButton, backButton, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
limitInput = TextField::create("limit", "arial", 24);
if (limitInput) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + visibleSize.height - 100.0f;
limitInput->setPosition(Vec2(x, y));
this->addChild(limitInput, 1);
}
messageBox = Label::create("", "arial", 30);
if (messageBox) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + visibleSize.height / 2;
messageBox->setPosition(Vec2(x, y));
this->addChild(messageBox, 1);
}
return true;
}
//得到用户信息的函数
void UsersInfoScene::getUserButtonCallback(Ref * pSender) {
// Your code here
std::string num = limitInput->getStringValue();
//根据PPT里面的提示,用users?limit=,传输方式用GET
HttpRequest* request = new HttpRequest();
request->setUrl("http://127.0.0.1:8000/users?limit=" + num);
request->setRequestType(HttpRequest::Type::GET);
request->setResponseCallback(CC_CALLBACK_2(UsersInfoScene::onHttpRequestCompleted, this));
cocos2d::network::HttpClient::getInstance()->send(request);
request->release();
}
//得到信息的回调函数,稍微有点复杂
void UsersInfoScene::onHttpRequestCompleted(HttpClient *sender, HttpResponse *response)
{
if (!response) {
return;
}
auto buffer = response->getResponseData();
rapidjson::Document doc;
doc.Parse(buffer->data(), buffer->size());
//首先是要用rapidjson解释库解析一下,得到doc这个数据结构
if (doc["status"] == true) {
std::string result;//为了将结果放入result中
for (int i = 0; i < doc["data"].Size(); i++) {//使用方式类似于vector,
result += "Username : ";
result += doc["data"][i]["username"].GetString();
result += "\nDeck : \n";
for (int j = 0; j < doc["data"][i]["deck"].Size(); j++) {
for (auto& m : doc["data"][i]["deck"][j].GetObjectW()) {//C++11标准的遍历
result == "\n";
//这边调一下缩进,似乎和\n放在一起不起作用,所以直接拿出来了
result += " ";
result += m.name.GetString();
result += ":";
//这边按照教程应该是直接m.value.GetInt但是会出乱码,所以将int再转成string再放到result里面
int a = m.value.GetInt();
CCString* ns = CCString::createWithFormat("%d", a);
std::string s = ns->_string;
result += s;
CCLOG("m.value.GetInt = %d", m.value.GetInt());
result += "\n";
}
result += " ---\n";
}
result += "---\n";
}
this->messageBox->setString(result);
}
else {
this->messageBox->setString(std::string("Info Failed\n") + doc["msg"].GetString());
}
}
#pragma once
#ifndef __MODIFY_USER_SCENE_H__
#define __MODIFY_USER_SCENE_H__
#include "cocos2d.h"
#include "ui\CocosGUI.h"
//必须要加这个库,以及引用名字空间,否则虽然没有红线,但是无法运行
#include "network\HttpClient.h"
using namespace cocos2d::network;
using namespace cocos2d::ui;
USING_NS_CC;
class ModifyUserScene : public cocos2d::Scene {
public:
static cocos2d::Scene* createScene();
virtual bool init();
void putDeckButtonCallback(Ref *pSender);
//为了点击回调
void onHttpRequestCompleted(HttpClient *sender, HttpResponse *response);
// implement the "static create()" method manually
CREATE_FUNC(ModifyUserScene);
Label *messageBox;
TextField *deckInput;
};
#endif
#include "ModifyUserScene.h"
#include "Utils.h"
#include "network\HttpClient.h"
#include "json\document.h"
using namespace cocos2d::network;
cocos2d::Scene * ModifyUserScene::createScene() {
return ModifyUserScene::create();
}
bool ModifyUserScene::init() {
if (!Scene::init()) return false;
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
auto postDeckButton = MenuItemFont::create("Post Deck", CC_CALLBACK_1(ModifyUserScene::putDeckButtonCallback, this));
if (postDeckButton) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + postDeckButton->getContentSize().height / 2;
postDeckButton->setPosition(Vec2(x, y));
}
auto backButton = MenuItemFont::create("Back", [](Ref* pSender) {
Director::getInstance()->popScene();
});
if (backButton) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + visibleSize.height - backButton->getContentSize().height / 2;
backButton->setPosition(Vec2(x, y));
}
auto menu = Menu::create(postDeckButton, backButton, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
deckInput = TextField::create("Deck json here", "arial", 24);
if (deckInput) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + visibleSize.height - 100.0f;
deckInput->setPosition(Vec2(x, y));
this->addChild(deckInput, 1);
}
messageBox = Label::create("", "arial", 30);
if (messageBox) {
float x = origin.x + visibleSize.width / 2;
float y = origin.y + visibleSize.height / 2;
messageBox->setPosition(Vec2(x, y));
this->addChild(messageBox, 1);
}
return true;
}
//改变卡组的函数
void ModifyUserScene::putDeckButtonCallback(Ref * pSender) {
// Your code here
//和之前的注册登录类似
std::string deck = deckInput->getStringValue();
std::string postData = "{\"deck\":" + deck + "}";
//根据PPT的内容,用put方式,users
HttpRequest* request = new HttpRequest();
request->setUrl("http://127.0.0.1:8000/users");
request->setRequestType(HttpRequest::Type::PUT);
request->setResponseCallback(CC_CALLBACK_2(ModifyUserScene::onHttpRequestCompleted, this));
request->setRequestData(postData.c_str(), strlen(postData .c_str()));
cocos2d::network::HttpClient::getInstance()->send(request);
request->release();
}
//改变卡组的回调函数,主要显示信息
void ModifyUserScene::onHttpRequestCompleted(HttpClient *sender, HttpResponse *response) {
auto buffer = response->getResponseData();
rapidjson::Document doc;
doc.Parse(buffer->data(), buffer->size());
if (doc["status"] == true) {
this->messageBox->setString("PUT OK");
}
else {
this->messageBox->setString(std::string("PUT Failed\n") + doc["msg"].GetString());
}
}
这个问题,在写的时候,visual studio 2018,不会加红线,所以看不出来报错,但是运行的时候就会出错,需要加头文件以及用对应的名字空间。#include "network/HttpClient.h"
using namespace cocos2d::network;
我大概看了一下往届是怎么用Cookies的,他们有一个Global.cpp
和Global.h
文件,用来根据传入的报头,生成一个值,然后在登录的时候传入这个值,这样在修改的时候,将这个值传入报头用来标识,等到我们这届直接在void LoginRegisterScene::loginButtonCallback(cocos2d::Ref * pSender)
这个函数里面加上cocos2d::network::HttpClient::getInstance()->enableCookies(NULL);
即可,直接自动生成,而不用手动添加了。
具体的详细的教程
代码以及视频演示