图片的下载

        cocos2d-X 网络动态下载资源图片       

        分类:            Cocos2d-X 2313人阅读 评论(5) 收藏 举报

游戏中经常会把一些资源放在服务器,玩家玩到的时候再动态下载,缓存,显示。

下面介绍下主要实现逻辑。

1.游戏初始化的时候,登陆服务器, 服务器返回一些基本信息,包含外部资源图片的网络地址。

2. 网络请求图片下载

  
  
  1. void HttpDownload::onMenuPostBinaryTestClicked(cocos2d::CCObject *sender , char * setUrl_ , char * childpath , char * filename)
  2. {
  3. CCHttpRequest* request = new CCHttpRequest();
  4. if (this->container)
  5. {
  6. this->observerID = CCImageNotificationCenter::sharedNotificationCenter()->addObserver(filename,container,useMask);
  7. }
  8. std::string url_ = "";
  9. url_ += setUrl_;
  10. url_+=childpath;
  11. url_+= filename;
  12. this->filename_ = filename;
  13. request->setUrl(url_.c_str());
  14. request->setRequestType(CCHttpRequest::kHttpGet);
  15. request->setResponseCallback(this, callfuncND_selector(HttpDownload::onHttpRequestCompleted));

  16. request->setTag("GET PIC");
  17. CCHttpClient::getInstance()->send(request);
  18. request->release();
  19. }

3.网络返回图片文件,保存,通知动态加载显示部分--图片下载完成

  
  
  1. void HttpDownload::onHttpRequestCompleted(cocos2d::CCNode *sender, void *data)
  2. CCHttpResponse *response = (CCHttpResponse*)data;
  3. if (!response)
  4. {
  5. return;
  6. }
  7. // You can get original request type from: response->request->reqType
  8. if (0 != strlen(response->getHttpRequest()->getTag()))
  9. {
  10. CCLOG("%s completed", response->getHttpRequest()->getTag());
  11. }
  12. int statusCode = response->getResponseCode();
  13. char statusString[64] = {};
  14. sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag());
  15. CCLOG("response code: %d", statusCode);
  16. if (!response->isSucceed())
  17. {
  18. CCLOG("response failed");
  19. CCLOG("error buffer: %s", response->getErrorBuffer());
  20. return;
  21. }
  22. // dump data
  23. std::vector<char> *buffer = response->getResponseData();
  24. std::string path = CCFileUtils::sharedFileUtils()->getWriteablePath();
  25. std::string bufffff(buffer->begin(),buffer->end());
  26. //保存到本地文件
  27. path+=this->filename_;
  28. CCLOG("path: %s",path.c_str());
  29. FILE *fp = fopen(path.c_str(), "wb+");
  30. fwrite(bufffff.c_str(), 1,buffer->size(), fp);
  31. fclose(fp);
  32. //传入container的下载请求会添加侦听,待下载完毕自动添加到container上
  33. if (this->container)
  34. {
  35. // container 是一个CCLayer ,用来显示动态加载的资源
  36. CCImageNotificationCenter::sharedNotificationCenter()->postNotification(this->observerID.getCString());
  37. }
  38. }

4.专门负责动态加载资源的消息监听,并且当接到文件下载完成的消息后,回调显示该图片

  
  
  1. CCString CCImageNotificationCenter::addObserver(const char *imageName,CCLayer* layer,bool useMask)
  2. {
  3. CCString* observerIDstr = CCString::createWithFormat("%d",m_observerID);
  4. m_notificationCenter.addObserver(this, callfuncO_selector(CCImageNotificationCenter::imageLoaded), observerIDstr->getCString(), new imgstruct(imageName, observerIDstr->getCString(), layer, useMask));
  5. m_observerID++;
  6. return observerIDstr->getCString();
  7. }
  8. void CCImageNotificationCenter::removeObserver(const char *name)
  9. {
  10. m_notificationCenter.removeObserver(this, name);
  11. }
  12. void CCImageNotificationCenter::postNotification(const char *name, CCObject *object)
  13. {
  14. m_notificationCenter.postNotification(name, object);
  15. }
  16. void CCImageNotificationCenter::imageLoaded(imgstruct* img)
  17. {
  18. CCLOG("imageLoaded success,imageName:%s",img->imageName.c_str());
  19. CCSprite* sprite = GOEUtilies::getSpriteFromWriteablePath(img->imageName.c_str());
  20. CCLOG("got sprite 0x%X", sprite);
  21. if (img->useMask)
  22. {
  23. img->layer->addChild(GOEUtilies::createMaskedSprite(sprite,"mask.png"));
  24. }
  25. else{
  26. float scale_ = (float) img->layer->getContentSize().width / (float)sprite->getContentSize().width;
  27. sprite->setAnchorPoint(ccp(0,0));
  28. sprite->setScale( scale_ );
  29. img->layer->addChild(sprite);
  30. }
  31. this->removeObserver(img->observerId.c_str());
  32. img->release();
  33. }

5.以后再显示该图片,则从本地SD卡缓存中读取文件,有判断方法

  
  
  1. CCSprite* GOEUtilies::getSpriteFromWriteablePath(const char* name){
  2. std::string path = CCFileUtils::sharedFileUtils()->getWriteablePath();
  3. path+=name;
  4. FILE* fp = fopen(path.c_str(),"rb");
  5. if (!fp)
  6. {
  7. return NULL;
  8. }
  9. fseek(fp,0,SEEK_END);
  10. int len = ftell(fp);
  11. fseek(fp,0,SEEK_SET);
  12. char* buf = (char*)malloc(len);
  13. fread(buf,len,1,fp);
  14. fclose(fp);
  15. CCImage* img = new CCImage;
  16. img->initWithImageData(buf,len);
  17. free(buf);
  18. cocos2d::CCTexture2D* texture = new cocos2d::CCTexture2D();
  19. bool isImg = texture->initWithImage(img);
  20. img->release();
  21. if (!isImg)
  22. {
  23. delete texture;
  24. return CCSprite::create("50black.png");//加载资源并非图片时返回的默认图
  25. }
  26. CCSprite* sprite = CCSprite::createWithTexture(texture);
  27. texture->release();
  28. return sprite;
  29. }

总结,该逻辑实现后,可以动态加载网络资源,并缓存本地,什么时候加载完成自动显示,并且可以同时进行多张图片的显示缓存,效果很好。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值