开发游戏中用到从http 服务器下载文件的操作,所以要有个界面显示下载进度,同时联网采用curl库,因为下载是同步的操作,所以用了多线程

啥也不说,直接贴代码。我是采用ccbi做的页面,你也可以做一个标准的CCLayer,然后添加一个进度条的CCSprite。

////////////////////////////DownLoadScene.h/////////////////////////

#include "cocos2d.h"

#include "cocos-ext.h"

#include "jsoncpp.h"

#include "curl.h"

#include "pthread.h"

USING_NS_CC;

USING_NS_CC_EXT;

class DownLoadScene :publicCCLayer, publicCCBSelectorResolver, publicCCBMemberVariableAssigner,publicCCNodeLoaderListener

{

public:

CREATE_FUNC(DownLoadScene);

public:

virtual bool init();

virtual void onEnter();

virtual void onExit();

virtual ~DownLoadScene()

{

CC_SAFE_RELEASE_NULL(m_pSprite);

}

//CCBSelectorResolver

virtual SEL_MenuHandler onResolveCCBCCMenuItemSelector(CCObject * pTarget, const char* pSelectorName);

virtual SEL_CallFuncN onResolveCCBCCCallFuncSelector(CCObject * pTarget, const char* pSelectorName) { return NULL; };

virtual SEL_CCControlHandler onResolveCCBCCControlSelector(CCObject * pTarget, const char* pSelectorName);

//CCBMemberVariableAssigner

virtual bool onAssignCCBMemberVariable(CCObject* pTarget, const char* pMemberVariableName, CCNode* pNode);

virtual bool onAssignCCBCustomProperty(CCObject* pTarget, const char* pMemberVariableName, CCBValue* pCCBValue) { return false; };

void onNodeLoaded(cocos2d::CCNode *pNode, cocos2d::extension::CCNodeLoader *pNodeLoader);

void onHttpReqFinished(CCHttpClient* client, CCHttpResponse* response);

private:

CCSprite    *m_pSprite;//进度条的CCSprite,注意锚点要设置为0,0.5,方便我们做进度显示

void onTimer(float t);//进度条刷新函数

pthread_t pid;//由于curl下载是同步操作,无法更新,所以要加一个线程来显示

static void* updateInfo(void *r);//线程函数

};

class DownLoadSceneLoader : public CCLayerLoader{

public:

CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD( DownLoadSceneLoader, loader );

CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD( DownLoadScene);

};

////////////////////////////DownLoadScene.cpp/////////////////////////

//

//  DownLoadScene.cpp

//

//  Created by Leo on 13-9-12.

//

//

#include "DownLoadScene.h"

FILE           *s_pfileWrite;//下载时写文件的指针

CURL        *s_pCurl;//curl库

int             s_iFileSize;//总文件大小

int             s_iCurrentFileSize;//当前下载大小

CCSprite    *s_pSpriteLoading;//进度条的CCSprite的外部指针

int         s_iSpriteWidth;//进度条的宽度保存

boolDownLoadScene::init()

{

//////////////////////////////

// 1. super init first

if ( !CCLayer::init() )

{

returnfalse;

}

returntrue;

}

voidDownLoadScene::onEnter()

{

CCLayer::onEnter();

}

voidDownLoadScene::onExit()

{

CCLayer::onExit();

}

SEL_MenuHandler DownLoadScene::onResolveCCBCCMenuItemSelector(CCObject * pTarget, const char* pSelectorName)

{

returnNULL;

}

SEL_CCControlHandler DownLoadScene::onResolveCCBCCControlSelector(CCObject * pTarget, const char* pSelectorName)

{

returnNULL;

}

bool DownLoadScene::onAssignCCBMemberVariable(CCObject* pTarget, const char* pMemberVariableName, CCNode* pNode)

{

//这里是CCB的处理,如果没有用cocosbuilder做的界面可以忽略

CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "progress", CCSprite*, m_pSprite);

returnfalse;

}

//处理头信息,注意curl是一条一条的头信息发过来的,我们只关心里面的Content-Length获取总文件大小并保存到s_iFileSize中

size_t DownLoadHeadCallBack( char *ptr, size_t size,size_t nmemb, void *stream)

{

char buff[512] = {0};

string pketword = "Content-Length: ";

int i = 0;

if(NULL == ptr)

{

printf("packet read error! \r\n");

return size * nmemb;

}

while((ptr[i] == pketword[i])&&(ptr[i] != ' '))

{

i++;

}

if(ptr[i] == pketword[i])

{

//sscanf( (char*)ptr, "%*s%[^\r]", buff );//%s遇空格停止,加*则是忽略第一个读到的字符串

sscanf((char*)ptr, "%*[^ ] %[^\r\n]", buff);//第一段到空格结束前的内容都忽略掉,第二段从空格开始换行结束

CCLog("Size=%s\r\n",buff);

s_iFileSize = atoi(buff);

return size * nmemb;

}

else

{

return size * nmemb;

}

}

//写入文件操作,同时记录当前写的大小

size_t DownLoadWriteCallBack(void *ptr, size_t size, size_t nmemb, void *stream)

{

int written = fwrite(ptr, size, nmemb, (FILE *)s_pfileWrite);

CCLog("size download=%ld",size*nmemb);

s_iCurrentFileSize+=size*nmemb;

CCLog("test = %d  %f",s_iSpriteWidth,(float)((float)s_iCurrentFileSize/(float)s_iFileSize));

s_pSpriteLoading->setTextureRect(CCRectMake(0, 0, s_iSpriteWidth*(float)((float)s_iCurrentFileSize/(float)s_iFileSize), s_pSpriteLoading->getContentSize().height));

return written;

}

//刷新进度条,这里用切割Texture的方式做的进度显示

void DownLoadScene::onTimer(float t)

{

CCLog("size download=%d",s_iCurrentFileSize);

CCLog("test = %d  %f",s_iSpriteWidth,(float)((float)s_iCurrentFileSize/(float)s_iFileSize));

s_pSpriteLoading->setTextureRect(CCRectMake(0, 0, s_iSpriteWidth*(float)((float)s_iCurrentFileSize/(float)s_iFileSize), s_pSpriteLoading->getContentSize().height));

}

//线程函数,联网下载文件,用http的post方式请求

void* DownLoadScene::updateInfo(void* args){

s_pCurl = curl_easy_init();

if (!s_pCurl)

return NULL;

Json::Value root;

Json::FastWriter writer;

root["bv"]=true;

//设置文件下载路径

std::string pszPath = CCFileUtils::sharedFileUtils()->getWritablePath()+"data.zip";

if((s_pfileWrite=fopen(pszPath.c_str(),"w+"))==NULL)

{

curl_easy_cleanup(s_pCurl);

exit(1);

}

std::string rUrl = URL_PARSE;

rUrl+="/v/dup";//设置url

curl_easy_setopt(s_pCurl, CURLOPT_TIMEOUT, 10);//设置超时时间

curl_easy_setopt(s_pCurl, CURLOPT_POSTFIELDS, writer.write(root).c_str());//设置post数据

curl_easy_setopt(s_pCurl, CURLOPT_URL, rUrl.c_str());//设置URL

curl_easy_setopt(s_pCurl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);//设置URL的版本

curl_easy_setopt(s_pCurl, CURLOPT_WRITEDATA, &s_pfileWrite);//设置写数据的文件指针

curl_easy_setopt(s_pCurl, CURLOPT_WRITEHEADER,NULL);//设置写头文件的指针,这里要设置为NULL,否则有问题

curl_easy_setopt(s_pCurl, CURLOPT_WRITEFUNCTION, DownLoadWriteCallBack);//设置数据写回调

curl_easy_setopt(s_pCurl, CURLOPT_HEADERFUNCTION, DownLoadHeadCallBack);//设置头数据写回调

curl_easy_setopt(s_pCurl, CURLOPT_VERBOSE, true);//打开联网log,发布的时候可以关闭

curl_easy_perform(s_pCurl);//联网请求,会停留在这里直到完成

curl_easy_cleanup(s_pCurl);//关闭CURL

fclose(s_pfileWrite);//关闭文件句柄

curl_global_cleanup();//清除curl

returnNULL;

}

voidDownLoadScene::onNodeLoaded(cocos2d::CCNode *pNode, cocos2d::extension::CCNodeLoader *pNodeLoader)

{

s_iCurrentFileSize =0;

s_iFileSize=1;

s_pSpriteLoading = m_pSprite;

s_iSpriteWidth = s_pSpriteLoading->getContentSize().width;

schedule(schedule_selector(DownLoadScene::onTimer), 1);

m_pSprite->setTextureRect(CCRectMake(0, 0, m_pSprite->getContentSize().width*(s_iCurrentFileSize/s_iFileSize), m_pSprite->getContentSize().height));

pthread_create(&pid,NULL,updateInfo,NULL); //开启新线程

}

cocos2d-x 制作资源下载页面的更多相关文章

  1. cocos2d-x jsbinding 资源下载实现

    cocos2dx没有直接给出资源下载的api,可能是因为资源的管理每个项目的需求不太一样,所以完整的资源下载功能需要我们自己去实现. 资源下载分为两部分,一部分是资源请求,另一部分是资源文件写入.资源 ...

  2. VS2012的安装项目只能用InstallShield Limited Edition[附资源下载]

    以前版本的Visual Stuido中安装项目都可以使用微软自家的Visual Studio Installer,但是到了VS2012这一切都变了,只能用InstallShield Limited E ...

  3. WordPress独立下载页面与演示插件:xydown

    我的博客是个资源分享的网站,所以需要提供下载,之前一直是在内容里直接添加个下载链接,感觉不是很美观,而且也麻烦,所以今天找了下看看有没有可以用的下载插件 xydown,这是一款可以独立下载页面与演示的 ...

  4. OSGI嵌入tomcat应用服务器(gem-web)——资源下载

    Gem-Web官网介绍: 官网地址:https://www.eclipse.org/gemini/web/download/milestones.php 1.1. 官方正式发布版 https://ww ...

  5. 《Android Studio开发实战 从零基础到App上线》资源下载和内容勘误

    转载于:https://blog.csdn.net/aqi00/article/details/73065392 资源下载 下面是<Android Studio开发实战 从零基础到App上线&g ...

  6. 全球DEM数据资源下载

    想找有海底地形的全球DEM数据作为三维地球展示用,发现很多都是只有陆地DEM而不带海底的,而且还需要通过Web页面进行选择然后数据下载. 找到一个学校的Ftp可以直接下载数据集,特别是这篇文章几乎汇集 ...

  7. 【转载】salesforce 零基础开发入门学习(一)Salesforce功能介绍,IDE配置以及资源下载

    salesforce 零基础开发入门学习(一)Salesforce功能介绍,IDE配置以及资源下载   目前国内已经有很多公司做salesforce,但是国内相关的资料确是少之又少.上个月末跳槽去了新 ...

  8. 对HTTP请求接口资源下载时间过长的问题分析

    问题描述 我司某产品线有指定业务接口customQuery在线上环境中,与首页一起打开时下载数据的时间明显过长(平均可以达到2s) 注: "与首页一起打开" 的含义是指用户进入WE ...

  9. JS判断是否是微信页面,判断手机操作系统(ios或android)并跳转到不同下载页面

    JS判断客户端是否是iOS或者Android 参考:http://caibaojian.com/browser-ios-or-android.html function is_weixin() { v ...

随机推荐

  1. 用SQL实现统计报表中的"小计"与"合计"的方法详解

    本篇文章是对使用SQL实现统计报表中的"小计"与"合计"的方法进行了详细的分析介绍,需要的朋友参考下   客户提出需求,针对某一列分组加上小计,合计汇总.网上找 ...

  2. 查找最小的k个元素

    题目:输入n个整数,输出其中最小的k个. 例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 两种思路,无非就是时间与空间的妥协. 限制空间的时候要对原数组进行排序, ...

  3. Windows failed to start.界面下修复win8引导

    首先要保证 系统本身是没有问题的 不是在装机的时候出现这种情况 那么可以按照以下方法来进行 首先要在另外一台电脑上将win8刻进u盘 启动时以u盘为第一启动项启动 进入win8装机界面 点击左下角的修 ...

  4. CSS块元素与内联元素(转)

    为什么<a><span>这种标签定义width,height等CSS属性时会发现完全不生效? 因为它们不是容器,它们是内联元素,不是块元素 CSS 块元素与内联元素 关键字: ...

  5. Flash中用AS3做的游戏,导出apk安装到手机上滤镜效果出不来为什么?

    主要原因是,导出apk文件时渲染模式设置成了GPU.改掉就行了.

  6. opencv kmeans 图像分割

    利用kmeans算法,将彩色图像的像素点作为样本,rgb值作为样本的属性, 对图像所有的像素点进行分类,从而实现对图像中目标的分割. c++代码(openCV 2.4.11) Scalar color ...

  7. win32下利用python操作printer

    在win32下操作printer:   1)import win32print   2) 获得默认打印机名:          >>> win32print.GetDefaultPr ...

  8. 【集训笔记】二分图及其应用【HDOJ1068【HDOJ1150【HDOJ1151

    匈牙利算法样例程序 格式说明 输入格式: 第1行3个整数,V1,V2的节点数目n1,n2,G的边数m 第2-m+1行,每行两个整数t1,t2,代表V1中编号为t1的点和V2中编号为t2的点之间有边相连 ...

  9. Android自定义组合控件:UIScrollLayout(支持界面滑动及左右菜单滑动)

    一.前言: 我之前很早的时候,写过一篇<左右滑出菜单>的文章: http://blog.csdn.net/qingye_love/article/details/8776650 用的是对V ...

  10. VC++在对话框中加入属性页

    当一个基于对话框的程序中有相当多的控件时,你一定会想到使用属性页来将这些控件分类放置.本文针对这种方法来讨论几种可能实现的方案. 方案一本方案的例子请见源代码打包文件中的Property1部分 在对话 ...