【Cocos2d-x】可以显示在线图片的CCSprite

论坛 期权论坛 脚本     
匿名网站用户   2020-12-20 04:03   11   0


可以显示在线图片的CCSprite,使用HttpClient异步请求图片数据,当请求成功时,保存图片数据到本地,然后更新CCSprite的纹理,下载中时显示默认图片(可以设置默认图片)。


OnlineImageSprite.h

#ifndef __ONLINEIMAGESPRITE_H__
#define __ONLINEIMAGESPRITE_H__

#include "cocos2d.h"
USING_NS_CC;
#include "cocos-ext.h"
USING_NS_CC_EXT;

// 可以显示在线图片的CCSprite
class OnlineImageSprite:public CCSprite{

public:
 /*
  创建一个显示在线图片的Sprite
  * defaultImagePath  默认图片路径(当图片加载中时显示)
  * url        图片url
 */
 static OnlineImageSprite* create(const char* defaultImagePath, const char* url); 

 bool init(const char* defaultImagePath, const char* url);

 void onDownloadCompleted(CCHttpClient *sender, CCHttpResponse *response);
protected:
 // 下载图片
 void downloadImage(const char* url);
 // 获取图片路径
 std::string getImagePath(const char* url);
 // 图片是否存在
 bool isExist(const char* url);
 // 保存图片
 std::string saveImage(const std::string& data);
private:
 const char* m_url;
};

#endif


OnlineImageSprite.cpp

#include "OnlineImageSprite.h"
#include <string>
using namespace std;   

string&   replace_all(string&   str,const   string&   old_value,const   string&   new_value)   
{   
 while(true)   {   
  string::size_type   pos(0);   
  if(   (pos=str.find(old_value))!=string::npos   )   
   str.replace(pos,old_value.length(),new_value);   
  else   break;   
 }   
 return   str;   
}   
string&   replace_all_distinct(string&   str,const   string&   old_value,const   string&   new_value)   
{   
 for(string::size_type   pos(0);   pos!=string::npos;   pos+=new_value.length())   {   
  if(   (pos=str.find(old_value,pos))!=string::npos   )   
   str.replace(pos,old_value.length(),new_value);   
  else   break;   
 }   
 return   str;   
}   

OnlineImageSprite* OnlineImageSprite::create(const char* defaultImagePath, const char* url){
 OnlineImageSprite* pSprite = new OnlineImageSprite();
 if (pSprite && pSprite->init(defaultImagePath,url))
 {
  pSprite->autorelease();
  return pSprite;
 }
 CC_SAFE_DELETE(pSprite);
 return NULL;
}

bool OnlineImageSprite::init(const char* defaultImagePath, const char* url){
  
 m_url = url;
 CCTexture2D* pTexture = NULL;

 // 图片是否存在,如果不存在使用默认纹理并下载图片
 if (isExist(url))
 {
  const char* path = getImagePath(url).c_str();
  pTexture = CCTextureCache::sharedTextureCache()->addImage(path);
 }else{
  pTexture = CCTextureCache::sharedTextureCache()->addImage(defaultImagePath);
  // 下载图片
  downloadImage(url);
 }
 
 // 初始化
 if (CCSprite::initWithTexture(pTexture))
 {
  return true;
 } 
 return false;
}

//判断图片是否已经存在
bool OnlineImageSprite::isExist(const char* url){ 
 std::string path = getImagePath(url);
 return CCFileUtils::sharedFileUtils()->isFileExist(path);
}

//获取图片全路径
std::string OnlineImageSprite::getImagePath(const char* url){
 std::string urlStr = url;
 replace_all(urlStr,"/","");
 replace_all(urlStr,"\\","");
 replace_all(urlStr,":","");
 replace_all(urlStr,".","");
 return CCFileUtils::sharedFileUtils()->getWritablePath().append("/").append(urlStr);
}

// 下载图片
void OnlineImageSprite::downloadImage(const char* url){
 // 发起http请求,下载图片
 CCHttpRequest* request = new CCHttpRequest();
 request->setUrl(url);
 request->setRequestType(CCHttpRequest::kHttpGet);
 request->setResponseCallback(this, httpresponse_selector(OnlineImageSprite::onDownloadCompleted)); 
 CCHttpClient::getInstance()->send(request);
 request->release(); 
}

// 请求回调
void OnlineImageSprite::onDownloadCompleted(CCHttpClient *sender, CCHttpResponse *response){
 if (!response)
 {
  return;
 }
 // 返回码
 int statusCode = response->getResponseCode();
 char statusString[64] = {};
 sprintf(statusString, "HTTP Status Code: %d", statusCode); 
 CCLog("response code: %d", statusCode);

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

 // dump data
 std::vector<char> *buffer = response->getResponseData();
 std::string data (buffer->begin(),buffer->end());
 std::string path =saveImage(data);
 //如果保存图片成功,更新纹理
 if (path != "")
 {
  CCTexture2D* pTexture = CCTextureCache::sharedTextureCache()->addImage(path.c_str());
  if (pTexture)
  {
   setTexture(pTexture);
  }  
 }
}

// 保存图片
std::string OnlineImageSprite::saveImage(const std::string& data){
 
 std::string path = this->getImagePath(m_url); 
 FILE* file = fopen(path.c_str(), "wb");
 if (file)
 {
  // 1.buff
  // 2.每次写的字节数
  // 3.写多少次结束
  // 4.文件句柄
  fwrite(data.c_str(), 1,data.length(), file);
  fclose(file);
  return path;
 }
 return "";
}

使用示例:
//创建OnlineImageSpirte,参数:1.默认图片路径 2.在线图片的url
CCSprite* pSprite = OnlineImageSprite::create("HelloWorld.png","http://cc.cocimg.com/cocos2dx/image/logo.png");

//设置位置
pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

//添加到Layer
this->addChild(pSprite, 0);

项目地址:https://coding.net/u/linchaolong/p/OnlineImageSprite/git


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP