cocos2d-x 制作资源下载页面
开发游戏中用到从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 制作资源下载页面的更多相关文章
- cocos2d-x jsbinding 资源下载实现
cocos2dx没有直接给出资源下载的api,可能是因为资源的管理每个项目的需求不太一样,所以完整的资源下载功能需要我们自己去实现. 资源下载分为两部分,一部分是资源请求,另一部分是资源文件写入.资源 ...
- VS2012的安装项目只能用InstallShield Limited Edition[附资源下载]
以前版本的Visual Stuido中安装项目都可以使用微软自家的Visual Studio Installer,但是到了VS2012这一切都变了,只能用InstallShield Limited E ...
- WordPress独立下载页面与演示插件:xydown
我的博客是个资源分享的网站,所以需要提供下载,之前一直是在内容里直接添加个下载链接,感觉不是很美观,而且也麻烦,所以今天找了下看看有没有可以用的下载插件 xydown,这是一款可以独立下载页面与演示的 ...
- OSGI嵌入tomcat应用服务器(gem-web)——资源下载
Gem-Web官网介绍: 官网地址:https://www.eclipse.org/gemini/web/download/milestones.php 1.1. 官方正式发布版 https://ww ...
- 《Android Studio开发实战 从零基础到App上线》资源下载和内容勘误
转载于:https://blog.csdn.net/aqi00/article/details/73065392 资源下载 下面是<Android Studio开发实战 从零基础到App上线&g ...
- 全球DEM数据资源下载
想找有海底地形的全球DEM数据作为三维地球展示用,发现很多都是只有陆地DEM而不带海底的,而且还需要通过Web页面进行选择然后数据下载. 找到一个学校的Ftp可以直接下载数据集,特别是这篇文章几乎汇集 ...
- 【转载】salesforce 零基础开发入门学习(一)Salesforce功能介绍,IDE配置以及资源下载
salesforce 零基础开发入门学习(一)Salesforce功能介绍,IDE配置以及资源下载 目前国内已经有很多公司做salesforce,但是国内相关的资料确是少之又少.上个月末跳槽去了新 ...
- 对HTTP请求接口资源下载时间过长的问题分析
问题描述 我司某产品线有指定业务接口customQuery在线上环境中,与首页一起打开时下载数据的时间明显过长(平均可以达到2s) 注: "与首页一起打开" 的含义是指用户进入WE ...
- JS判断是否是微信页面,判断手机操作系统(ios或android)并跳转到不同下载页面
JS判断客户端是否是iOS或者Android 参考:http://caibaojian.com/browser-ios-or-android.html function is_weixin() { v ...
随机推荐
- 小小换行符乱谈(文本文件vs二进制文件)
使用 C 语言的 fopen 打开文件时,可以指定的 mode 有 12 个,其中 6 个包含 "b" 使用 C++ 的 fstream 打开文件时,可用的模式组合有 24 个( ...
- CMake 简单介绍
CMake特点 CMake需要用户用CMake规范的语法编写CMake脚本,该语法简单易用,入门极其顺手 原生支持 C/C++/Fortran/Java 的相依性的自动分析功能,免除了程序员对代码依赖 ...
- Bosch 英语面试准备分享
上周从一个朋友那里了解到长沙一家德国外企Bosch在招人,看了下只有MES工程师是对编程经验有要求的,抱着试一试的态度,就投了简历. 没想到对方周一就给我回电话,希望我好好准备一下英语面试,过段时间去 ...
- UVA 10652 Board Wrapping(凸包)
The small sawmill in Mission, British Columbia, hasdeveloped a brand new way of packaging boards for ...
- 周根项《一分钟速算》全集播放&下载地址
点击图片就可以观看 ↓↓↓↓↓↓↓↓ 第1章:指算法 周根项<一分钟速算>第1章:指算法 第一节 对手的认识 周根项<一分钟速算>第1章:指算法 第二节 个位数比十位数大1乘以 ...
- 一行JavaScript代码获取页面中的所有超链接地址
因为我喜欢收集Web开发类的网址,平时对网址就很敏感. 我总结了一下我收集网址的几个阶段: 1.纯手工阶段,傻傻的阶段. 在这个阶段,主要是收集一些在页面中展现出来的网址,就是说,如果网址出现在HTM ...
- UltraEdit for mac 3.2.0.10免费破解版下载!!
http://www.mactech.cn/a/108.html UltraEdit for mac 3.2.0.10破解版下载地址 看很多朋友不知道算号器的使用方法,分享如下: 1. 解压Ultra ...
- WPF: 针对Windows 8优化菜单栏和工具栏
原文 WPF: 针对Windows 8优化菜单栏和工具栏 目录 1. 关于菜单图标大小 2. 关于IsEnabled和工具栏图标 3. 针对.NET 3.x的菜单栏和工具栏外观 返回目录 1. 关于菜 ...
- php __autoload使用
官方介绍: void __autoload ( string $class ) 你可以通过定义这个函数来启用类的自动加载. 转载一篇文章: PHP autoload机制详解 (1) autoload机 ...
- 《白手起家Win32SDK应用程序》(完整版+目录)
<白手起家Win32SDK应用程序> 目 录 <白手起家Win32SDK应用程序> 第一篇.预备知识 第二篇.创建Win32工程和主函数 第三篇.增加一个回调函数 第四篇.注册 ...