前言:

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



第一步:构思


1.总体流程


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


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

封装成一个函数方便调用


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打开文件,将我们自己的信息写进去。

<?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>needtoloadp_w_picpaths</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秒后加载资源 。


//// 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__) */


//// 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);} //加载资源快捷方法2void 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);}


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


//// 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__) */


//// 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("p_w_picpath 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文件方法


看代码

//// 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 "needtoloadp_w_picpaths"#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__) */



//// 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; }}//变更plistbool 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("Needtoloadp_w_picpaths 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();}//获取关卡信息 根据keyfloat 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();}


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