cocos2d-x 菜鸟编塔防 05 预加载资源

前言:

前面几篇文章很基本的实验了一下塔防游戏的编写,但试想一下一个塔防游戏,关卡中会有很多的信息,包括敌人的总波数,敌人的种类,塔的限制种类等,于是我将这些信息写在一个plist文件中,当然这个plist文件中不仅仅包括关卡的信息,还包括了一些需要提前加载的图片地址,用一个loading的层提前加载这些图片并装进内存。



第一步:构思


1.总体流程


首先我们构思一下整体的流程,像这样


这样的思路就是,根据用户选择的关卡,比如,第一大关的第一小关,关卡编号就是“1-1“,根据这个编号加上点字符串 就变成文件名,如:Level_01_01.plist,前面再加点路径什么的就行了。

封装成一个函数方便调用


1
2
3
4
5
6
const  char  getLevelInfoPath( int  numlevel01, int  numlevel02)
{
     CCString * pString  = CCString ::createWithFormat( "values/Level_%d_%d.plist" ,numlevel01,numlevel02);
//获得const *char
     return  pString->getCString();
}


2.plist文件内容


之后我们再想想这个plist中需要包含什么信息,像预加载图片地址,敌人总波数,每波多少个敌人等

像这样




3.plist文件编写


想好了plist文件中都有什么后就开始编写plist文件了,先搜索一下电脑中的plist文件,找一个文件内容比较少得复制黏贴一下,修改文件名并用xcode打开文件,将我们自己的信息写进去。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<? xml  version = "1.0"  encoding = "UTF-8" ?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
< plist  version = "1.0" >
< dict >
     < key >levelparameter</ key >
     < dict >
         < key >New item</ key >
         < string ></ string >
     </ dict >
     < key >needtoloadimages</ key >
     < dict >
         < key >4</ key >
         < string >loadingHMenu/111.plist</ string >
         < key >3</ key >
         < string >levelselectone/themescene2-hd.plist</ string >
         < key >2</ key >
         < string >levelselectone/stages_bg-hd.plist</ string >
         < key >1</ key >
         < string >Hmenu/mainscene1-hd.plist</ string >
     </ dict >
</ dict >
</ plist >


像这样写一下,用xcode编写着会方便一点。


第二步:代码的编写


1.资源场景代码编写

首先我先编写了一个场景基类,功能很简单,就是通过类的init函数(初始化函数)加载背景,加载进度条,之后启动一个定时器,过0.5秒后加载资源 。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//
//  LoadSceneBase.h
//  TDgame05
//
//  Created by Za aa on 13-6-4.
//
//
#ifndef __TDgame05__LoadSceneBase__
#define __TDgame05__LoadSceneBase__
#include "cocos2d.h"
USING_NS_CC;
class  LoadSceneBase :  public  CCLayer
{
                                                                                          
public :
     LoadSceneBase();
     ~LoadSceneBase();
     //--1.0--初始化
     bool  init();              
                                                                                              
     //生成背景和logo等
     virtual  void  addBackGround(){};
                                                                                          
     //添加一个progress
     virtual  CCProgressTimer * addProgress(){};
                                                                                          
     //将需要加载的资源放在这个函数中,倍update调用.别忘了切换场景啊
     virtual  void  loadResources();
                                                                                          
     //启动加载资源
     void  update( float  dt);
                                                                                          
     //加载资源快捷方法
     void  loadingPVR( const  char  * plist);
     //加载资源快捷方法2
     void  loadingPVRs( const  char  * plist,...);
                                                                                          
public :
     //进度条
     CCProgressTimer * _pross;
};
#endif /* defined(__TDgame05__LoadSceneBase__) */


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//
//  LoadSceneBase.cpp
//  TDgame05
//
//  Created by Za aa on 13-6-4.
//
//
#include "LoadSceneBase.h"
LoadSceneBase::LoadSceneBase():_pross(NULL)
{
}
LoadSceneBase::~LoadSceneBase()
{
}
  bool  LoadSceneBase::init()
{
     bool  bRet =  false ;
     do
     {
         CC_BREAK_IF(! CCLayer::init());
         //生成背景和logo等
          addBackGround();
                                                                                        
         //添加进度条
         _pross =    addProgress();
         if  (_pross!= NULL)
             this ->addChild(_pross);
         //0.5秒后加载资源
         this ->scheduleOnce(schedule_selector(LoadSceneBase::update),0.5f);
         bRet =  true ;
     while  (0);
                                                                                        
     return  bRet;
}
void  LoadSceneBase::loadResources()
{
     loadingPVRs( "111" , "222" );
     //TODO: 切换场景
}
void  LoadSceneBase::update( float  dt)
{
     loadResources();
}
void  LoadSceneBase::loadingPVR( const  char  * plist)
{
     CCTexture2D::PVRImagesHavePremultipliedAlpha( true );
     CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile(plist);
}
  //加载资源快捷方法2
void  LoadSceneBase::loadingPVRs( const  char  * plist,...)
{
     //进度条
     float  t_loading ;
     //------------获取个数--------------
     int  num= 0 ;
     //需先定义参数列表变量
     va_list  argp;
     //初始化,使用argp指向可变参数的第一个参数,
     va_start (argp, plist);
     //其后省略的参数是根据函数第一个参数的偏移量来获得
     while  ( true )
     {
                                                                                            
         if ( va_arg (argp,  const  char  *)== NULL)
             break ;
         num++;
                                                                                            
     }
     //结束可变参数获取
     va_end (argp);
     //-------------进行装载-------
                                                                                        
     //加载头一个资源
     t_loading = 100.0f*1/(num+1);
     _pross->setPercentage(t_loading);
     loadingPVR(plist);
                                                                                        
     va_list  argp2;
     va_start (argp2,plist);
                                                                                        
     for  ( int  i=1; i<=num; i++)
     {
         //修改进度条
         t_loading = 100.0f*(i+1)/(num+1);
         _pross->setPercentage(t_loading);
         loadingPVR( va_arg (argp2,  const  char  *));
     }
     va_end (argp2);
}


之后继承这个类,并实现几个虚方法


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//
//  LoadingGameScene.h
//  TDgame05
//
//  Created by Za aa on 13-6-3.
// NOTE: 创建一个加载游戏的界面,这个界面会向内存中加载一些资源
//
#ifndef __TDgame05__LoadingGameScene__
#define __TDgame05__LoadingGameScene__
#include "cocos2d.h"
#include "../global/LoadSceneBase.h"
class  LoadingGameScene : public  LoadSceneBase
{
public :
     //创建一个create函数调用父类init
     CREATE_FUNC(LoadingGameScene);
                                                                                  
     //生的一个CCScene
     static  CCScene * CreateLoadingGameScene();
                                                                                  
     //父类方法。添加背景
     void  addBackGround();
                                                                                  
     //父类方法,添加一个进度条
     CCProgressTimer *addProgress();
                                                                                  
     //父类方法,在这个方法中加载资源
     void  loadResources();
};
#endif /* defined(__TDgame05__LoadingGameScene__) */


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//
//  LoadingGameScene.cpp
//  TDgame05
//
//  Created by Za aa on 13-6-3.
//
//
#include "LoadingGameScene.h"
#include "../LoadLevelinfo/LoadLevelinfo.h"
void  LoadingGameScene::addBackGround()
{
    //添加背景和logo等
}
CCProgressTimer * LoadingGameScene::addProgress()
{
     //添加一个进度条并返回
                                                                             
      return  NULL;
}
/*---------------------------------------
  加载所需的资源,
  可以通过loadPVR(),或者loadPVRs()函数加载资源
  -----------------------------------------*/
void  LoadingGameScene::loadResources()
{
     //--you need to remove : loadlevelinfo 测试--
     LoadLevelinfo *info = LoadLevelinfo::createLoadLevelinfo( "values/Level_01_01.plist" );
     CCLog( "image 01 path is :%s" ,info->f_GetLoadingImages(1));
     //--
}
CCScene* LoadingGameScene::CreateLoadingGameScene()
{
     // 'scene' is an autorelease object
     CCScene *scene = CCScene::create();
                                                                               
     // 'layer' is an autorelease object
     LoadingGameScene *layer = LoadingGameScene::create();
                                                                               
     // add layer as a child to scene
     scene->addChild(layer);
                                                                               
     // return the scene
     return  scene;
}


其中loadresources函数中的LoadLevelinfo封装了读取plist文件的方法,马上就说是怎么遍的


2.封装读取plist文件方法


看代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//
//  LoadLevelinfo.h
//  TDgame05
//
//  Created by Za aa on 13-6-17.
//
//
#ifndef __TDgame05__LoadLevelinfo__
#define __TDgame05__LoadLevelinfo__
#include "cocos2d.h"
using  namespace  cocos2d;
#define NEEDTOLOADIMAGES "needtoloadimages"
#define LEVELPARAMETER "levelparameter"
class  LoadLevelinfo:  public  CCObject
{
public :
     //构造函数
     LoadLevelinfo();
     ~LoadLevelinfo();
     static  LoadLevelinfo * createLoadLevelinfo( const  char  *plistpath);
     //变更plist
     bool  f_SetPlist( const  char  * plistpath);
                    
     //获取关卡信息 根据key
     float  f_GetLevelInfo( const  char  * key);
     //获得tmx瓦片地图文件路径
     const  char  * f_GetLevelTmxPath( const  char  * key);
     /*
     获取预加载图片的容器
     读取的plist格式是这个样子滴
     <key>4</key>
     <string>loadingHMenu/111.plist</string>
     <key>3</key>
     <string>levelselectone/themescene2-hd.plist</string>
     <key>2</key>
     <string>levelselectone/stages_bg-hd.plist</string>
     <key>1</key>
     <string>Hmenu/mainscene1-hd.plist</string>
     */
     const  char   * f_GetLoadingImages( int  key);
                    
                    
     //清空已经读取的字符串
     void  f_ClearAll();
     /* data */
private :
     //保存关卡需要预加载的图片
     CCDictionary * s_NeedToLoadImages;
                    
     //保存关卡的相关的数值信息
     CCDictionary * s_LevelParameter;
                    
private :
                    
};
#endif /* defined(__TDgame05__LoadLevelinfo__) */



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//
//  LoadLevelinfo.cpp
//  TDgame05
//
//  Created by Za aa on 13-6-17.
//
//
#include "LoadLevelinfo.h"
LoadLevelinfo::LoadLevelinfo()
{
}
LoadLevelinfo::~LoadLevelinfo()
{
                
     //TODO: 安全删除s_arr
     //f_ClearAll();
    // CC_SAFE_RELEASE(s_LevelParameter);
    // CC_SAFE_RELEASE(s_NeedToLoadImages);
}
LoadLevelinfo *LoadLevelinfo::createLoadLevelinfo( const  char  *plistpath)
{
     LoadLevelinfo *pRet =  new  LoadLevelinfo();
     if  (pRet && pRet->f_SetPlist(plistpath))
     {
         pRet->autorelease();
         return  pRet;
     }
     else
     {
         delete  pRet;
         pRet = NULL;
         return  NULL;
     }
}
//变更plist
bool  LoadLevelinfo::f_SetPlist( const  char  *plistpath)
{
     bool  bRet =  false ;
     do
     {
         /* code */
        // if (s_LevelParameter != NULL && s_NeedToLoadImages != NULL)
            // f_ClearAll();
         //创建一个实力
         CCDictionary *ccd = CCDictionary::createWithContentsOfFile(plistpath);
         CC_BREAK_IF(!ccd);
         //进入关卡所需加载图片资源的节点
         s_NeedToLoadImages =  dynamic_cast <CCDictionary *>(ccd->objectForKey(NEEDTOLOADIMAGES));
         CC_BREAK_IF(!s_NeedToLoadImages);
         //进入关卡所需信息节点
         s_LevelParameter =  dynamic_cast <CCDictionary *>(ccd->objectForKey(LEVELPARAMETER));
         CC_BREAK_IF(!s_LevelParameter);
         //You need to remove : 输出调试信息
         CCLog( "Needtoloadimages count is : %d" , s_NeedToLoadImages->count());
         CCLog( "levelparameter count is : %d" , s_LevelParameter->count());
         bRet =  true ;
     }
     while  (0 /* condition */ );
     return  bRet;
}
//清空已经读取的字符串
void  LoadLevelinfo::f_ClearAll()
{
     s_NeedToLoadImages->removeAllObjects();
     s_LevelParameter->removeAllObjects();
}
//获取关卡信息 根据key
float  LoadLevelinfo::f_GetLevelInfo( const  char  *key)
{
    CCString * temp =    dynamic_cast <CCString*>(s_LevelParameter->objectForKey(key));
     return  temp->floatValue();
}
const  char  * LoadLevelinfo::f_GetLevelTmxPath( const  char  * key)
{
     CCString * temp =    dynamic_cast <CCString*>(s_LevelParameter->objectForKey(key));
     return  temp->getCString();
                
}
//获取预加载图片的容器
const  char   *LoadLevelinfo::f_GetLoadingImages( int  key)
{
     CCString * pString  = CCString ::createWithFormat( "%d" ,key);
     CCString * temp =    dynamic_cast <CCString*>(s_NeedToLoadImages->objectForKey(pString->getCString()));
     return  temp->getCString();
}

基本上这样就可以了,改动一点点就能用了



本文出自 “远在南非” 博客,请务必保留此出处http://farsa.blog.51cto.com/6172595/1239343

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值