上一篇我们搞定了中文显示和本地存储

而很多时候,本地存储是不够的

我们需要调用后台服务,在服务器端处理用户信息

本篇就用一个例子讲解如何完成HTTP请求

 

我们用Cocos2D-x编写游戏,实际上是在写游戏的客户端

当然如果是一个简单的单机游戏,只有客户端也就足够了

若需要与服务器交互

可以使用cocos2d::extension域下的CCHttpRequest建立HTTP请求

详细的官方示例在TestCpp工程下Classes/ExtensionsTest/NetworkTest文件夹下

(HttpClientTest.h和HttpClientTest.cpp两个文件)

看一看很容易理解

 

自己做了一个简单的示例

贴出代码如下

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"
#include "cocos-ext.h"

class HelloWorld : public cocos2d::CCLayer
{
public:
    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::CCScene* scene();    
    // a selector callback
    void menuCloseCallback(CCObject* pSender);
    //声明请求函数
    void getData();
    virtual ~HelloWorld();
    //声明响应回调函数
    void onHttpRequestCompleted(cocos2d::extension::CCHttpClient *sender, cocos2d::extension::CCHttpResponse *response);
    //声明label
    cocos2d::CCLabelTTF* pLabel;
    // implement the "static node()" method manually
    CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__
#include "HelloWorldScene.h"

USING_NS_CC;
USING_NS_CC_EXT;

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();
    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();
    // add layer as a child to scene
    scene->addChild(layer);
    // return the scene
    return scene;
}

HelloWorld::~HelloWorld()
{
    CCHttpClient::getInstance()->destroyInstance();
}
void HelloWorld::getData()  
{ 
    //新建一个CCHttpRequest对象 并设置请求url 该url返回一个字符串
    CCHttpRequest* request = new CCHttpRequest();
    request->setUrl("http://116.211.2.131/api/out/center/checkvalidcode");  
    request->setRequestType(CCHttpRequest::kHttpGet);
    //设置请求响应时的回调函数为onHttpRequestCompleted
    request->setResponseCallback(this, httpresponse_selector(HelloWorld::onHttpRequestCompleted));
    request->setTag("GET test1");
    CCHttpClient::getInstance()->send(request);
    request->release(); 
}  

void HelloWorld::onHttpRequestCompleted(CCHttpClient *sender, CCHttpResponse *response)
{
    //回调函数,处理请求的响应
    if (!response)
    {
        return;
    }   
    // You can get original request type from: response->request->reqType
    if (0 != strlen(response->getHttpRequest()->getTag())) 
    {
        CCLog("%s completed", response->getHttpRequest()->getTag());
    }

    int statusCode = response->getResponseCode();
    char statusString[64] = {};
    sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag());

    CCLog("response code: %d", statusCode);

    if (!response->isSucceed()) 
    {
        CCLog("response failed");
        CCLog("error buffer: %s", response->getErrorBuffer());
        return;
    }

    //获取返回的数据,并解析显示
    std::vector<char> *buffer = response->getResponseData();  
    int data_length =  buffer->size();  
    std::string res = "data is:";  
    for (int i = 0;i<data_length;++i)  
    {  
        res+=(*buffer)[i];  
    }  
    res+='\0';  
    CCLog("%s",res.c_str());
    //显示在label上
    pLabel->setString(res.c_str());
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayer::init() )
    {
        return false;
    }

    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();

    /////////////////////////////
    // 2. add a menu item with "X" image, which is clicked to quit the program
    //    you may modify it.

    // add a "close" icon to exit the progress. it's an autorelease object
    CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
        "CloseNormal.png",
        "CloseSelected.png",
        this,
        menu_selector(HelloWorld::menuCloseCallback));

    pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
        origin.y + pCloseItem->getContentSize().height/2));



    // create menu, it's an autorelease object
    CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
    pMenu->setPosition(CCPointZero);
    this->addChild(pMenu, 1);

    /////////////////////////////
    // 3. add your codes below...

    pLabel=CCLabelTTF::create("1","Arial",18);  
    ccColor3B c;  
    c.r=0;  
    c.g=0;  
    c.b=255;  
    pLabel->setColor(c);  
    pLabel->setPosition(ccp(origin.x + visibleSize.width/2,origin.y + visibleSize.height - pLabel->getContentSize().height));  
    addChild(pLabel,1);


    // add "HelloWorld" splash screen"
    CCSprite* pSprite = CCSprite::create("HelloWorld.png");

    // position the sprite on the center of the screen
    pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

    // add the sprite as a child to this layer
    this->addChild(pSprite, 0);

    //调用请求方法,测试是否能获取数据
    getData();

    return true;
}


void HelloWorld::menuCloseCallback(CCObject* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
    CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
#else
    CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
#endif
}

 

运行结果如图所示,我们请求的url返回了{"return_code:....."}这样一个json字符串

程序顺利读取了数据并显示在label上,正如我们看到的

使用这种方法,就可以实现最基本的网络操作,如从/向后台读/写信息

 

今天写的这一篇非常简略

也是这一段实在工作太忙了

希望可以坚持下去!