cocos2dx客户端应用的设计框架的一个应用思路。
1、帧缓存
(1)帧加载
缓存需要的帧数据到内存。封装了cocos2dx的帧缓存
(2)帧访问
2、资源管理和加载
(1)加载场景
(2)加载层
(3)层和场景访问
3、场景基类
场景创建
4、层封装基类
处理界面编辑器的ui初始化,及其使用的封装
5、网络上下文通信资源
(1)连接逻辑服务器socket
(2)连接网关socket
(3)连接下载socket
6、服务器选择
选择服务器层的接口(服务器选择面板管理层)
7、主场景
(1)主场景内容和跳转接口
(2)主场景注册消息回调
注册层上的空间的消息回调函数
8、层和精灵使用
(1)npc视图
怪物精灵附带的资源
(2)角色战斗效果层(3)研究所层
1、帧缓存
(1)帧加载
缓存需要的帧数据到内存。封装了cocos2dx的帧缓存
uiFrameCache::uiFrameCache()
{
frame_cache = cocos2d::CCSpriteFrameCache::sharedSpriteFrameCache();
}
从配置文件里把需要加载的资源都加载到缓存里
bool uiFrameCache::load(TiXmlElement* pNode)
{
if (pNode){
TiXmlNode* pChild = pNode->FirstChild("symbols");
while( pChild ){
TiXmlElement* pEle = pChild->ToElement();
std::string name = pEle->Attribute("name");
std::string file = pEle->Attribute("file");
int type = 0;
pEle->Attribute("type",&type);
if ( 1 == type){
loadFrameFromFile(name.c_str(),file.c_str());
}
else{
if(file.length() == 0)
{
LOG_ERR("plist文件不能为空");
}
else
{
res_map.insert(std::pair<std::string,std::string>(name,file));
frame_cache->addSpriteFramesWithFile(file.c_str());
}
}
pChild = pChild->NextSibling();
}
}
return true;
}
cocos2d::CCSpriteFrame* uiFrameCache::spriteFrameByName(const char *pszName){
CCSpriteFrame* tmpSpritFrame = frame_cache->spriteFrameByName(pszName);
ASSERT_RES_LOG(tmpSpritFrame,pszName);
return tmpSpritFrame;
}
bool uiFrameCache::loadFrameFromFile(const char* pszName,const char* pszFile)
{
CCTexture2D* texture = CCTextureCache::sharedTextureCache()->addImage(pszFile);
if (texture){
CCSize size = texture->getContentSize();
CCRect rect(0,0,size.width,size.height);
CCSpriteFrame* frame = CCSpriteFrame::createWithTexture(texture,rect);
frame_cache->addSpriteFrame(frame,pszName);
return true;
}
return false;
}
(2)帧访问
cocos2d::CCSpriteFrame* UiPageManager::spriteFrameByName(const char *pszName)
{
assert(pszName);
cocos2d::CCSpriteFrame* frame = frame_cache.spriteFrameByName(pszName);
ASSERT_LOG(frame, (std::string("找不到plist中的图片: ")+pszName).c_str());
return frame;
}
2、资源管理和加载
(1)加载场景
SceneBase* UiPageManager::loadScene(const char* path)
{
assert(path);
std::string dstPath = uiResUtils::sharedResUtils()->getUILayoutPath() + std::string(path);
int len = 0;
unsigned char* data = CCFileUtils::sharedFileUtils()->getFileData(dstPath.c_str(), "rb", (unsigned long *)(&len));
TiXmlDocument doc;
if( !doc.LoadFile((char*)data,len, TIXML_ENCODING_UTF8) ){
CC_SAFE_DELETE_ARRAY(data);
LOG_ERR("XML 格式出错, 请检查XML内容!");
return false;
}
CC_SAFE_DELETE_ARRAY(data);
TiXmlNode* pRoot = doc.FirstChild();
if (pRoot){
TiXmlNode* pRes = pRoot->FirstChild("symbollib");
ASSERT_LOG(pRes, "XML中找不到symbollib节点,可能XML头没有去掉");
if (pRes){
frame_cache.load(pRes->ToElement());
}
TiXmlNode * pScene = pRoot->FirstChild("scene");
ASSERT_LOG(pScene, "XML中找不到scene节点,可能XML头没有去掉");
if (pScene){
TiXmlElement* pEle = pScene->ToElement();
std::string name = pEle->Attribute("name");
SceneBase* scene = SceneBase::create();
if (scene){
scene->Init(m_CreateFunc, pEle);
scene_mgr.insert(std::pair<std::string,SceneBase*>(path,scene));
return scene;
}
}
}
return NULL;
}
(2)加载层
LayerBase* UiPageManager::loadLayer(const char* path)
{
assert(path);
int len = 0;
std::string dstPath = uiResUtils::sharedResUtils()->getUILayoutPath() + std::string(path);
unsigned char* data = CCFileUtils::sharedFileUtils()->getFileData(dstPath.c_str(), "rb", (unsigned long *)(&len));
TiXmlDocument doc;
if( !doc.LoadFile((char*)data,len) ){
CC_SAFE_DELETE_ARRAY(data);
return NULL;
}
CC_SAFE_DELETE_ARRAY(data);
TiXmlNode* pRoot = doc.FirstChild();
if (pRoot){
TiXmlNode* pRes = pRoot->FirstChild("symbollib");
if (pRes){
frame_cache.load(pRes->ToElement());
}
TiXmlElement* pSceneElement = (TiXmlElement*)pRoot->FirstChild("scene");
assert(pSceneElement);
TiXmlElement* pLayerElement = (TiXmlElement*)pSceneElement->FirstChild("layer");
if(pLayerElement){
const char* name = pLayerElement->Attribute( "name" );
LayerBase* pLayer = m_CreateFunc( name );
pLayer->autorelease();
assert(pLayer);
layer_mgr.insert(std::pair<std::string,LayerBase*>(name,pLayer));
pLayer->Init( pLayerElement );
return pLayer;
}
}
return NULL;
}
(3)层和场景访问
SceneBase* UiPageManager::getScene(const char* pszName)
{
assert(pszName);
SceneMap::iterator iter = scene_mgr.find(pszName);
if ( iter != scene_mgr.end()){
return iter->second;
}
return NULL;
}
LayerBase* UiPageManager::getLayer(const char* pszName)
{
assert(pszName);
LayerMap::iterator iter = layer_mgr.find(pszName);
if ( iter != layer_mgr.end()){
return iter->second;
}
return NULL;
}
3、场景基类
场景创建
SceneBase::SceneBase(void)
{
setAnchorPoint( CCPoint( 0.0f, 0.0f ) );//
}
SceneBase::~SceneBase()
{
}
SceneBase *SceneBase::create()
{
SceneBase *pRet = new SceneBase();
if (pRet && pRet->init())
{
pRet->autorelease();
return pRet;
}
else
{
CC_SAFE_DELETE(pRet);
return NULL;
}
}
void SceneBase::Init( CREATE_LAYER_FUNC func, TiXmlElement* pEle )
{
TiXmlElement* pchild = (TiXmlElement*)pEle->FirstChild();
while( pchild ) {
if ( strcmp( pchild->Value(), "layer" ) == 0 ) {
const char* name = pchild->Attribute( "name" );
LayerBase* pLayer = func( name );//根据名字创建具体的层
pLayer->Init( pchild );
m_Objects.addObject( pLayer );
addChild( pLayer );
pLayer->sortAllChildren();//Sorts the children array once before drawing, instead of every time when a child is added or reordered
pLayer->release(); // FIXME 手动回收,因为addObject这些操作已经把引用增加了1
} else {
LOG_ERR("scene节点下有不可识别的节点");
}
pchild = (TiXmlElement*)pchild->NextSibling();
}
}
void SceneBase::onEnter()
{
CCScene::onEnter();
}
void SceneBase::runThisTest()
{
}
4、层封装基类
处理界面编辑器的ui初始化,及其使用的封装
class LayerBase : public CCLayer
{
public:
LayerBase( void );
virtual ~LayerBase( void );
virtual CCObject* FindControl( int key );
virtual CCRect* FindPlaceHolder(int key);
virtual void Init( TiXmlElement* pXmlEle );
virtual cocos2d::CCNode* InitControls( TiXmlElement* pEle );
......
typedef std::map<int,CCRect>RectMap;
typedef std::pair<int,CCRect>RectPair;
protected:
CCDictionary m_Dict;//存储所有控件
RectMap m_placeholder_dict;//存储所有占位符
int m_iControlCount;//控件计数器
};
初始化界面控件
cocos2d::CCNode* LayerBase::InitControls( TiXmlElement* pEle )
{
const char* type = pEle->Value();
float x, y, width, height;
CCSprite * pSelectSprite = NULL, * pNormalSprite = NULL;
UiPageManager* pPageMgr = g_uiPageManager;
int id;
pEle->QueryIntAttribute( "id", &id );
// better for dynamic create
if ( strcmp( type, "Static" ) == 0 ) {//静态图
pEle->QueryFloatAttribute( "x", &x );
pEle->QueryFloatAttribute( "y", &y );
pEle->QueryFloatAttribute( "width", &width );
pEle->QueryFloatAttribute( "height", &height );
CCSize size = CCDirector::sharedDirector()->getWinSize();
x += width * 0.5f;
y -= height * 0.5f;
const char* image = pEle->Attribute( "normal" );
if(image)
{
CCSpriteFrame *tex = pPageMgr->spriteFrameByName( image );//由帧缓存里获取图资源
if(tex)
{
CCSprite* pSprite = CCSprite::createWithSpriteFrame(tex);
if(pSprite)
{
pSprite->setPosition( CCPoint( x, y ) );
CCSize size = tex->getOriginalSize();
pSprite->setScaleX( width / size.width );//设置比例
pSprite->setScaleY( height / size.height );
pSprite->ignoreAnchorPointForPosition(false);
addChild( pSprite );
InitControl( id, pSprite );
m_Dict.setObject( pSprite, id );
return pSprite;
}
}
}
}
else if ( strcmp( type, "Button" ) == 0 ) {//设置按钮
pEle->QueryFloatAttribute( "x", &x );
pEle->QueryFloatAttribute( "y", &y );
pEle->QueryFloatAttribute( "width", &width );
pEle->QueryFloatAttribute( "height", &height );
CCSize size = CCDirector::sharedDirector()->getWinSize();
x += width * 0.5f;
y -= height * 0.5f;
const char* image = pEle->Attribute( "normal" );
CCSize orignSize;
//一般情况的图
if(image)
{
CCSpriteFrame* pFrame = pPageMgr->spriteFrameByName( image );
if(pFrame)
{
orignSize = pFrame->getOriginalSize();
CCSpriteFrame *tex = pPageMgr->spriteFrameByName( image );
if(tex)
{
pNormalSprite = CCSprite::createWithSpriteFrame(tex);
if(pNormalSprite)
{
pNormalSprite->setPosition( CCPoint( 0, 0 ) );
CCRect rc = pNormalSprite->getTextureRect();
pNormalSprite->setScaleX( 1.0f );
pNormalSprite->setScaleY( 1.0f );
pNormalSprite->ignoreAnchorPointForPosition(false);
}
}
}
}
//选中情况下的图
if(image)
{
image = pEle->Attribute( "select" );
CCSpriteFrame *tex = pPageMgr->spriteFrameByName( image );
if(tex)
{
pSelectSprite = CCSprite::createWithSpriteFrame( tex );
if(pSelectSprite)
{
pSelectSprite->setPosition( CCPoint( 0, 0 ) );
CCRect rc = pSelectSprite->getTextureRect();
pSelectSprite->setScaleX( 1.0f );
pSelectSprite->setScaleY( 1.0f );
pSelectSprite->ignoreAnchorPointForPosition(false);
}
}
}
if(pNormalSprite && pSelectSprite)//按钮的弹起和放开
{
//创建菜单选项按钮
CCMenuItemSprite* pMenuItem = CCMenuItemSprite::create( pNormalSprite, pSelectSprite );
//获取纹理的大小并拉伸到配置的大小
CCRect rc = pNormalSprite->getTextureRect();
pMenuItem->setPosition( CCPoint( 0, 0 ) );
pMenuItem->setScaleX( width / orignSize.width );
pMenuItem->setScaleY( height / orignSize.height );
//添加按钮到菜单,再把菜单添加到层上
CCMenu* toggleMenu = CCMenu::createWithItem(pMenuItem);
toggleMenu->setPosition( CCPoint( x, y ) );
//初始化控件的响应事件
InitControl( id, pMenuItem );
m_Dict.setObject( pMenuItem, id );
addChild( toggleMenu );
}
}
else if ( strcmp( type, "ButtonToggle" ) == NULL ) {//设置会弹起的按钮
}
//设置标签
else if ( strcmp( type, "Label" ) == 0 ) {
。。。
}
else if ( strcmp( type, "List" ) == 0 ) {//设置列表控件
。。。
}
else if ( strcmp( type, "Edit" ) == 0 ) {//设置编辑框控件
...
}
else if ( strcmp( type, "Placeholder" ) == 0 ) {//设置占位符控件
。。。
}
return NULL;
}
5、网络上下文通信资源
class GameContex : public cocos2d::CCObject
{
public:
GameContex();
~GameContex();
static GameContex* instance();
(1)连接逻辑服务器socket
// 游戏逻辑专用socket
inline SocketChannel* GetLogicSocketChannel() {return m_logic_channel;}
// 游戏逻辑专用socket(发送消息)
inline void SendLogicMsg(NetOutPacket *msg, bool auto_delete = true)
{m_logic_channel->Send(msg, auto_delete);}
// 游戏逻辑专用socket(连接)
inline bool ConnectLogicServer(const char *address, unsigned short port)
{return m_logic_channel->Connect(address, port);}
(2)连接网关socket
// 大区专用socket
inline SocketChannel* GetGateSocketChannel() {return m_gate_channel;}
// 大区专用socket(发送消息)
inline void SendGateMsg(NetOutPacket *msg, bool auto_delete = true)
{m_gate_channel->Send(msg, auto_delete);}
// 大区专用socket(连接)
inline bool ConnectGateServer(const char *address, unsigned short port)
{return m_gate_channel->Connect(address, port);}
(3)连接下载socket
// 下载专用socket
inline SocketChannel* GetDownloadSocketChannel() {return m_download_channel;}
// 下载专用socket(发送消息)
inline void SendDownloadMsg(NetOutPacket *msg, bool auto_delete = true)
{m_download_channel->Send(msg, auto_delete);}
// 下载专用socket(连接)
inline bool ConnectDownloadServer(const char *address, unsigned short port)
{return m_download_channel->Connect(address, port);}
private:
SocketManager *m_socket_mgr;
SocketChannel *m_logic_channel; // 游戏逻辑专用socket通道
SocketChannel *m_gate_channel; // 大区专用socket通道
SocketChannel *m_download_channel; // 下载专用socket通道
SocketHandler *m_socket_handler;
};
#define g_GameContext GameContex::instance()
#define g_LogicSocket g_GameContext->GetLogicSocketChannel()
#define g_GateSocket g_GameContext->GetGateSocketChannel()
#define g_DownloadSocket g_GameContext->GetDownloadSocketChannel()
6、服务器选择
选择服务器层的接口(服务器选择面板管理层)
class RobotServerLayer : public LayerBase {
CC_SYNTHESIZE_RETAIN(CCArray*, m_pServerArray, ServerArray);
/// 帐号Id
CC_SYNTHESIZE(int, accountID, AccountID);
/// 当前页码
CC_SYNTHESIZE(int, currentPageNum, CurrentPageNum);
/// 总页数
CC_SYNTHESIZE(int, totalPageNum, totalPageNum);
/// 只有NO的时候button才响应事件
CC_SYNTHESIZE(bool, bButtonStatus, ButtonStatus);
/// 游戏服务器列表背景
CC_SYNTHESIZE_RETAIN(CCSprite*, serverImage, ServerImage);
/// 保持服务器列表的数组
CC_SYNTHESIZE_RETAIN(CCArray *, m_pServersArray, ServersArray);
/// 保持Game服务器列表的数组
CC_SYNTHESIZE_RETAIN(CCArray *, gameServerArray, GameServerArray);
/// 上次登录服务器ID
CC_SYNTHESIZE(int, lastSigninId, LastSigninId);
/// 各大区服务器显示区域
CC_SYNTHESIZE_RETAIN(CCArray*, m_pRegionServerBoards, RegionServerBoards);
/// 各大区显示菜单
CC_SYNTHESIZE_RETAIN(CCMenu*, regionMenu, RegionMenu);
CC_SYNTHESIZE_RETAIN(CCMenuItemSprite*, selectedItem, SelectedItem);
CC_SYNTHESIZE(int, staticTag, StaticTag);
// 服务器gete的菜单
CC_SYNTHESIZE_RETAIN(CCMenu *, serverGatesMenu,ServerGatesMenu);
/// 初始化场景
public:
static CCScene* scene();
RobotServerLayer();
~RobotServerLayer();
/// 返回游戏服务器Socket实例
//static SocketHandle* sharedRobotServer();
/// 返回Gate服务器Socket实例
// static SocketHandle* sharedGateServer();
/// 返回选择服务器类实例
static RobotServerLayer* sharedGameServer();
/// 设定游戏服务器(换线后设定)
//static void setRobotServer(SocketHandle* socket);
/// 设定Gate服务器(自动选择服务器后)
//static void setGateServer(SocketHandle *pSocket);
/// 备份玩家选择的服务器
static void setSelectServer(ServerBean *_server);
/// 返回玩家选择的服务器
static ServerBean* getSelectServer();
// 添加一个服务器到该层:
// @serverName 服务器名
// @IP 服务器Ip
// @port 服务器端口
// @Num 该服务器当前在线人数
// @tag 标识第几个服务器的Tag
// @serverId 标识第几个服务器的
// @status 服务器状态
void addNewServer(const char* serverName, const char* serverIP,int serverPort, int serverPlayers, int tag, int serverId, int status, int region);
// 添加一个服务器到该层:
// @serverName 服务器名
// @IP 服务器Ip
// @port 服务器端口
// @Num 该服务器当前在线人数
// @tag 标识第几个服务器的Tag
// @serverId 标识第几个服务器的
// @status 服务器状态
void addNewServer(const char* serverName, const char* serverIP,int serverPort, int serverPlayers, int tag, int serverId,int status);
// 添加一个服务器到该层:
// @serverName 服务器名
// @IP 服务器Ip
// @port 服务器端口
// @Num 该服务器当前在线人数
// @tag 标识第几个服务器的Tag
// @startPoint 开始位置
// @serverId 服务器Id
// @status 服务器状态
void addNewServer(const char* serverName, const char* serverIP, int serverPort, int serverPlayers, int tag, CCPoint startPoint, int serverId, int status);
// 添加一个服务器到该层:
// @serverName 服务器名
// @IP 服务器Ip
// @port 服务器端口
// @Num 该服务器当前在线人数
// @tag 标识第几个服务器的Tag
// @startPoint 开始位置
// @serverId 服务器Id
// @status 服务器状态
void addNewServer(const char* serverName, const char* serverIP, int serverPort, int serverPlayers,int tag, CCPoint startPoint,int serverId,int status, int nodeTag);
// 根据服务器状态设置‘推荐’或‘火爆’等状态
void getStatusWithStatusId(int status, cocos2d::CCNode *node);
// 自动选择游戏服务器线路
void addNewGameServers(CCArray* servers);
/// 根据区域找出区域内的服务器
CCArray* getServersByRegion(int region);
/// 直线动画,根据服务器个数和ItemTag
void moveMenuWithServerCount(int count, CCMenuItemSprite *item);
private:
void RhandledRecommendedServers(CCObject* notification);
void handledLatestLoginServer(CCObject* notification);
/** 返回主界面 */
void back(CCObject* pSender);
void selectedRegion(CCObject* sender);
};
7、主场景
(1)主场景内容和跳转接口
class MainSceneLayer : public LayerBase
{
public:
MainSceneLayer();
~MainSceneLayer();
void InitControl( int Id, cocos2d::CCNode* pItem );
static bool isTranscript( void );
static void setIsTranscrip(bool _isTranscript);
static CCScene* scene( void );
static MainSceneLayer* instance( void );
//static MainSceneLayer* create();
bool init(void);
// 添加滚动元素到layer
void addSpriteToLayer( void );
// 初始化右边的按钮
void initRightButtons( void );
void enterGuildSystem( void );
void activityEvent( void );
//初始化界面
void initBaseView( void );
// 进入副本地图选择界面
void enterTranscriptMapLayer( void );
......
void OnSetting(CCObject* pSender);
// 研究所入口
void OnInstituteClicked(CCObject *pSender);
//广场入口
void OnSpareList( CCObject* pSender );
//聊天入口
void OnChatShow( CCObject* pSender );
void OnShopMall(CCObject* pSender);
void OnAcitivity(CCObject* pSender);
// 排行榜入口
void OnRanking(CCObject *pSender);
void OnTask(CCObject *pSender);
private:
AppDelegate *rw;
// 用来存放左右滑动的精灵
CCArray *spritesArray;
CCArray *moveArray;
//保持精灵位置的精灵
CCArray *rectArray;
//选择的精灵的号码
int number;
//选中的是否是目标精灵
bool isSelect;
CCPoint beginPoint;
CCPoint movePoint;
// 按下带旋转效果的精灵
CCSprite *RotationSprite;
//左边工具栏
CCMenu *leftMenu;
//是否显示工具栏
bool isShowMenu;
//是否有弹出框
bool isShowBox;
// 按钮的状态 只有当状态为NO的时候按钮才有效
bool status;
......
};
(2)主场景注册消息回调
注册层上的空间的消息回调函数
void MainSceneLayer::InitControl( int controlId, cocos2d::CCNode* pItem )
{
pItem->setTag(1);
pItem->getChildByTag(1);
switch( controlId ) {
case 4: //空间id
{
((CCMenuItem*)pItem)->setTarget( this, menu_selector(MainSceneLayer::hallEvent));
}
break;
case 5:
((CCMenuItem*)pItem)->setTarget( this, menu_selector(MainSceneLayer::OnInstituteClicked) );
break;
......
case 20:
break;
case 8:
((CCMenuItem*)pItem)->setTarget( this, menu_selector(MainSceneLayer::OnTask));
break;
case 6:
((CCMenuItem*)pItem)->setTarget( this, menu_selector(MainSceneLayer::OnChatShow));
break;
......
}
}
跳转到聊天层
void MainSceneLayer::OnChatShow( CCObject* pSender )
{
CCScene* scene = ChatUILayer::show();
CCDirector::sharedDirector()->replaceScene(scene);
}
replaceScene会删除计划场景列表里的最后一个并把需要运行的加到列表的最后(可以释放正在运行的场景的内存)
void CCDirector::replaceScene(CCScene *pScene)
{
CCAssert(m_pRunningScene, "Use runWithScene: instead to start the director");
CCAssert(pScene != NULL, "the scene should not be null");
unsigned int index = m_pobScenesStack->count();
m_bSendCleanupToScene = true;
m_pobScenesStack->replaceObjectAtIndex(index - 1, pScene);
m_pNextScene = pScene;
}
8、层和精灵使用
(1)npc视图
怪物精灵附带的资源
class MonsterView : public CCSprite
{
public:
MonsterView();
MonsterView* initMonsterWithId(int nMonsterId);
//设置怪物信息
void setMonsterInfo(int nMonsterID , int nIndex , int nlift , int nTempLift);
//更新怪物位置
void updateMonsterPosition(CGPoint pos);
void animationWithMonster(Type_GameObjectState type);
void setMOnsterFlipX(bool bFlipX);
// 更新怪物血量
void updateMOnsterBlood(int nBlood);
void monsterAction();
//判断怪物是否为Boss yes为boss
bool checkMonsterIsBoss();
//显示怪物说话
void showMonsterSay(NSString * strSay);
//怪物走路
void monsterRunWithCurPosition();
//根据风力产生随机数 返回随机数0 1
int getRandomNumWithWeedSpeed();
// 检测是否是走路状态 yes为走路状态
bool checkMonsterStatus01();
//一个带自身响应时间的动作函数,1:动作类型,2:回调事件 3:是否重复播放标志
void monsterActionWithSelector(Type_GameObjectState type, SEL_CallFunc pSelector , bool bRepeat);
// 怪物死亡回调
void monsterDeadAction();
int m_nId ;//怪物ID
int m_nRound ;//共同回合
ushort m_nIndex ; // 怪物序号
float m_nLift ;//生命总值
int m_nTempLift ;//剩余生命值 如果怪物死亡则剩余生命总值设为-1
CC_SYNTHESIZE_RETAIN(NSString*, m_strSay, StrSay) ; // 怪物要说的话
bool m_bIsRun ;// 是否已经行动完了 YES为行动完毕
bool m_bIsBoss;// 是否是boss yes为boss;
bool m_bIsRemote ; //是否为远程攻击怪,YES为远程攻击
//怪物说话lb
CCLabelTTF *pMonsterSay;
//怪物说话背景
CCSprite *m_pSaySprite;
// 怪物动作
Type_GameObjectStateMonsterAct ;
// 怪物形象
//PlayerView *m_pMonsterView ;
//**角色下方血量条
CCSprite *m_pBloodValueView ;
CCSprite *m_pBloodBolck ;
//**角色下方的血量前框
CCSprite *m_pBloodBolck2;
// 怪物得当前位置
CGPoint m_cCurPoint ;
// 怪物得移动得目的位置
CGPoint m_cPurPoint;
// 被击中得玩家得信息
NSMutableArray*m_pByHitPlayerArray ;
//怪物音效
BranchAudioManager *pAudioManger;
};
(2)角色战斗效果层
class BranchFightUILayer : public LayerBase
{
typedef LayerBase super;
public:
BranchFightUILayer();
~BranchFightUILayer();
virtual void InitPlaceholder( int Id, float x, float y, float width, float height );
virtual void InitControl( int Id, cocos2d::CCNode* pItem );
static CCScene * scene();
static BranchFightUILayer * shareBranchFightUILayer();
static CCScene * sharedBranchFightScene();
// 初始化BranchFightUILayer
BranchFightUILayer* initBranchFightUILayer();
//与加载音频资源
void preloadAllSound();
//玩家攻击
void PlayerShotting(float nVx ,float nVy);
// 绘制力度显示条
void drawStrengthAndEngel();
// 在某一点绘制圆
void drawCircleAtPosition(float nRadius, CGPoint nPoint);
// 更新血量值
void updateBloodValue(int nBloodValue);
//初始化UI基本信息
void initUIBaseInfo ();
// 更新能量值
void updateOtherValue(int nOtherValue);
// 设置风向,风力
void setWindPower(int nWindPower, int nWindDirection);
//重置攻击状态
void reSetAttackbuff ();
// 显示轮到谁攻击了信息
void displayPlayerTurnInfo(short nSeatID);
//回合开始的时候设置前一次的力度,风力和角度数据
void setFightData ();
// 更新怒气值
void updateAngerValue(int nAngerBox);
//重置技能按钮状态
void reSetAllSkillButon ();
void updateRightSkillButon ();
//检查不够能量使用
void checkSkillCanUse ();
//显示输赢奖励画面
void showTimerForWhoWin(short nWinTeam);
//显示输赢奖励画面
void showBroadWhoWin ();
// 播放其他玩家的怒气特效
void startOtherPlayerPlayAnger(short SeatID ,int SkillID);
// 玩家怒气特效完后的攻击
void PlayerShotAfterAnger ();
// 显示胜利条件,失败条件暂不显示
void showWinCondition(NSString * win ,NSString * lose);
......
public:
//平移屏幕标志位
bool m_bIsMoveScreen;
//是否可攻击,yes为可攻击
bool m_bIsGrag ;
// 是否点击角色状态,NO已经点击,YES还没点击,点击后才能判断发射
bool m_bMoveOrShot;
//是否点击技能状态变量
bool m_bClickSkill;
//其他玩家屏幕可平移标志位
bool m_bIsCanTouchScreen;
// 是否使用怒气
bool m_bUseAnger;
//是否触摸到屏幕
bool _isTouchScreen;
int m_nRound_now ;
// 当前玩家角度限制
int m_nBeginAngle;
int m_nEndAngle;
// 要施放必杀的座位号
float nLastSeatId;
// 要施放必杀的技能ID
float nLastSkillID;
private:
// 左边固定技能盒子
BranchFightSkillBoxs*m_pRightSkillBox;
BranchFightPropsSkillBox*m_pLeftSkillBox;
//战斗数据层
BranchFightLayer*m_pBranchFightLayer;
// 发射力度和方向盘
// CCSprite *m_pShootController;
// 怒气盒
BranchFightAngerSkillBox *m_pAngerBox;
// 蓝气和血量显示块
CCSprite *m_pBloodAndMagic;
// 主角头像
CCSprite *m_pPlayerHead;
// 风向标
CCSprite *m_pWindFlag;
// 风向标签
CCLabelTTF *m_pWindText;
//右上角的生命条
CCProgressTimer *m_pBloodValueViewPT;
//右上角的能量条
CCProgressTimer *m_pOtherValueViewPT;
// 头像下方力度值
int m_pStre;
// 头像下方角度值
int m_pRoat;
// 头像下方风力值
int m_pWind;
// 胜利队伍
ushort winTeam ;
//定时器:显示胜利奖励画面
NSTimer * timerForShowWin;
......
//倒计时
CountDown* CountDownTime;
// 发射方向箭头
CCSprite *m_pDirection;
// 发射力度虚线末端的图片
CCSprite *m_pEndPosition;
// 拖拉起始坐标
CGPoint nBegin;
// 拖拉结束坐标
CGPoint nEnd;
// 力度条长度
float m_nDistance;
// 旋转之后的角度限制
int m_nRotatedBeginAngle;
int m_nRotatedEndAngle;
//角度限制
ShotLine *m_pBranchShotLine ;
......
};
(3)研究所层
class InstituteLayer : public LayerBase
{
public:
InstituteLayer(void);
~InstituteLayer(void);
static CCScene* GetScene();
static InstituteLayer* sharedInstitute();
virtual void onEnter();
virtual void onExit();
// 读取设置控件信息
virtual void InitControl(int controlId, cocos2d::CCNode* pItem);
//=================== 触摸相关 ============================//
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
// 按下格子
virtual void GridPressed(Grid *pGrid);
//=================== 按钮回调相关 ============================//
void OnWorkButton(CCObject *pSender);// 工作区域按钮
void OnPacketButton(CCObject *pSender);// 背包按钮
void OnSwitchPageButton(CCObject *pSender);// 翻页按钮
void OnReturnButton(CCObject *pSender);// 返回按钮
void OnChatButton(CCObject *pSender);// 聊天
private:
typedef enum {
PACKET_EQUIPMENT,// 装备背包
PACKET_PROP // 道具背包
}Type_Packet;
Type_Work m_eCurWork, m_ePreWork;
Type_Packet m_eCurPacket;
// 标签页
InstituteTagLayer*m_pTagLayer;
// 6个功能界面
SynthesizeLayer*m_pSynthLayer;
InlayLayer *m_pInlayLayer;
DismantleLayer*m_pDismaLayer;
StrengthenLayer*m_pStrenLayer;
TransformLayer*m_pTransLayer;
ForgeLayer *m_pForgeLayer;
// 物品信息面板
InstituteEquipLayer*m_pEquipPanel;
InstitutePropsLayer*m_pPropsPanel;
// 背包界面
InstitutePacketLayer*m_pPacketLayer;
// 装备、道具按钮
CCMenuItemToggle*m_pBtnEquip;
CCMenuItemToggle*m_pBtnProps;
// 物品页面label
CCLabelTTF *m_pLabPageCount;
CCPoint m_startPoint; // 记录起始触摸点
int m_nSelectIndex;// 选中物品的位置
};
const float k_Deviation = 5.0f;
static InstituteLayer *sharedLayer = NULL;
InstituteLayer::InstituteLayer(void)
: m_pTagLayer(NULL)
, m_pSynthLayer(NULL)
, m_pInlayLayer(NULL)
, m_pDismaLayer(NULL)
, m_pStrenLayer(NULL)
, m_pTransLayer(NULL)
, m_pForgeLayer(NULL)
, m_pEquipPanel(NULL)
, m_pPropsPanel(NULL)
, m_pPacketLayer(NULL)
, m_pBtnEquip(NULL)
, m_pBtnProps(NULL)
, m_pLabPageCount(NULL)
{
sharedLayer = this;
}
InstituteLayer::~InstituteLayer(void)
{
sharedLayer = NULL;
}
CCScene* InstituteLayer::GetScene()
{
return (CCScene*)g_uiPageManager->createScene("institute/institute.xml");
}
InstituteLayer* InstituteLayer::sharedInstitute()
{
return sharedLayer;
}
void InstituteLayer::onEnter()
{
CCLayer::onEnter();
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);//设定触摸代理
// 初始化成员变量
CCSize winSize = CCDirector::sharedDirector()->getWinSize();
m_eCurWork = m_ePreWork = WORK_SYNTHESIZE;
m_eCurPacket = PACKET_PROP;
m_nSelectIndex = -1;
UiPageManager *pPageMgr = g_uiPageManager;
// 背包
m_pPacketLayer = (InstitutePacketLayer*)pPageMgr->createLayer("institute/institute_packet.xml");
CCRect *pPacketRect = this->FindPlaceHolder(11);
m_pPacketLayer->setPosition(ccpSub(pPacketRect->origin, ccp(0, pPacketRect->size.height)));
this->addChild(m_pPacketLayer);
// 合成界面
m_pSynthLayer = (SynthesizeLayer*)pPageMgr->createLayer("institute/institute_synthesize.xml");
CCRect *pWorkRect = this->FindPlaceHolder(12);
m_pSynthLayer->setPosition(ccpSub(pWorkRect->origin, ccp(0, pWorkRect->size.height)));
this->addChild(m_pSynthLayer);
// 镶嵌界面
m_pInlayLayer = (InlayLayer*)pPageMgr->createLayer("institute/institute_inlay.xml");
m_pInlayLayer->setPosition(m_pSynthLayer->getPosition());
m_pInlayLayer->setVisible(false);
this->addChild(m_pInlayLayer);
// 拆卸页面
m_pDismaLayer = (DismantleLayer*)pPageMgr->createLayer("institute/institute_dismantle.xml");
m_pDismaLayer->setPosition(m_pSynthLayer->getPosition());
m_pDismaLayer->setVisible(false);
this->addChild(m_pDismaLayer);
// 强化页面
m_pStrenLayer = (StrengthenLayer*)pPageMgr->createLayer("institute/institute_strengthen.xml");
m_pStrenLayer->setPosition(m_pSynthLayer->getPosition());
m_pStrenLayer->setVisible(false);
this->addChild(m_pStrenLayer);
// 转换页面
m_pTransLayer = (TransformLayer*)pPageMgr->createLayer("institute/institute_transform.xml");
m_pTransLayer->setPosition(m_pSynthLayer->getPosition());
m_pTransLayer->setVisible(false);
this->addChild(m_pTransLayer);
// 重铸页面
m_pForgeLayer = (ForgeLayer*)pPageMgr->createLayer("institute/institute_forge.xml");
m_pForgeLayer->setPosition(m_pSynthLayer->getPosition());
m_pForgeLayer->setVisible(false);
this->addChild(m_pForgeLayer);
// 标签页
m_pTagLayer = (InstituteTagLayer*)pPageMgr->createLayer("institute/institute_tagButton.xml");
m_pTagLayer->SetTarget(this, menu_selector(InstituteLayer::OnWorkButton));
CCRect *pTagRect = this->FindPlaceHolder(14);
m_pTagLayer->setPosition(ccpSub(pTagRect->origin, ccp(0, pTagRect->size.height)));
this->addChild(m_pTagLayer);
// 查看装备信息的面板
m_pEquipPanel = (InstituteEquipLayer*)pPageMgr->createLayer("institute/institute_packet_equipment.xml");
m_pEquipPanel->setPosition(winSize.width, 20);
m_pEquipPanel->setVisible(false);
this->addChild(m_pEquipPanel, 1);
// 初始按钮显示
m_pBtnEquip->setSelectedIndex(0);
m_pBtnProps->setSelectedIndex(1);
m_pBtnProps->setEnabled(false);
}
void InstituteLayer::onExit()
{
CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this);
CCLayer::onExit();
}
void InstituteLayer::InitControl(int id, cocos2d::CCNode* pItem)
{
switch (id)
{
case 3: // 聊天
((CCMenuItem*)pItem)->setTarget(this, menu_selector(InstituteLayer::OnChatButton));
break;
case 5: // 装备
m_pBtnEquip = (CCMenuItemToggle*)pItem;
m_pBtnEquip->setTag(PACKET_EQUIPMENT);
m_pBtnEquip->setTarget(this, menu_selector(InstituteLayer::OnPacketButton));
break;
case 6: // 返回
((CCMenuItem*)pItem)->setTarget(this, menu_selector(InstituteLayer::OnReturnButton));
break;
case 7: // 道具
m_pBtnProps = (CCMenuItemToggle*)pItem;
m_pBtnProps->setTag(PACKET_PROP);
m_pBtnProps->setTarget(this, menu_selector(InstituteLayer::OnPacketButton));
break;
case 8: // 下一页
case 17: // 上一页
{
CCMenuItem *pPageItem = (CCMenuItem*)pItem;
pPageItem->setTag(id);
pPageItem->setTarget(this, menu_selector(InstituteLayer::OnSwitchPageButton));
}
break;
case 34: // 页码文字
m_pLabPageCount = (CCLabelTTF*)pItem;
break;
default:
break;
}
}
/************************************************************************/
/* 触摸相关 */
/************************************************************************/
bool InstituteLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)//判断是否在该区域
{
m_startPoint = pTouch->getLocationInView();
m_startPoint = CCDirector::sharedDirector()->convertToGL(m_startPoint);//converts a UIKit coordinate to an OpenGL coordinate
for (int i=0; i<k_CountOnePage; ++i)
{
if (CGRectContainsPoint(m_pPacketLayer->GetRectForLocation(i),
ccpSub(m_startPoint, m_pPacketLayer->getPosition())))
{
m_nSelectIndex = i;
break;
}
}
return true;
}
void InstituteLayer::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
}
void InstituteLayer::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent)
{
CCPoint endPoint = pTouch->getLocationInView();
endPoint = CCDirector::sharedDirector()->convertToGL(endPoint);
if (m_nSelectIndex!=-1 && fabsf(endPoint.x-m_startPoint.x)<=k_Deviation && fabsf(endPoint.y-m_startPoint.y)<=k_Deviation)
{
// 查看物品信息
CCLog("============ touch grid at %d", m_nSelectIndex);
m_nSelectIndex = -1;
}
}
void InstituteLayer::ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent)
{
}
/************************************************************************/
/* 按钮回调 */
/************************************************************************/
void InstituteLayer::OnWorkButton(CCObject *pSender)
{
Type_Work type = (Type_Work)((CCMenuItemToggle*)pSender)->getTag();
if (type == m_eCurWork)return;
m_ePreWork = m_eCurWork;
m_eCurWork = type;
// 当前工作状态处理
m_pTagLayer->m_pBtnWork[m_eCurWork]->setSelectedIndex(1);
m_pTagLayer->m_pBtnWork[m_eCurWork]->setEnabled(false);
switch (m_eCurWork)
{
case WORK_SYNTHESIZE:m_pSynthLayer->setVisible(true);break;//设置页面显示
case WORK_INLAY:m_pInlayLayer->setVisible(true);break;
case WORK_DISMANTLE:m_pDismaLayer->setVisible(true);break;
case WORK_STRENGTHEN:m_pStrenLayer->setVisible(true);break;
case WORK_TRANSFORM:m_pTransLayer->setVisible(true);break;
case WORK_FORGE:m_pForgeLayer->setVisible(true);break;
default: break;
}
// 上次工作状态处理
m_pTagLayer->m_pBtnWork[m_ePreWork]->setSelectedIndex(0);
m_pTagLayer->m_pBtnWork[m_ePreWork]->setEnabled(true);
switch (m_ePreWork)
{
case WORK_SYNTHESIZE:m_pSynthLayer->setVisible(false);break;
case WORK_INLAY:m_pInlayLayer->setVisible(false);break;
case WORK_DISMANTLE:m_pDismaLayer->setVisible(false);break;
case WORK_STRENGTHEN:m_pStrenLayer->setVisible(false);break;
case WORK_TRANSFORM:m_pTransLayer->setVisible(false);break;
case WORK_FORGE:m_pForgeLayer->setVisible(false);break;
default: break;
}
}
void InstituteLayer::OnPacketButton(CCObject *pSender)
{
Type_Packet type = (Type_Packet)((CCMenuItemToggle*)pSender)->getTag();
if (type == m_eCurPacket) return;
m_eCurPacket = type;
bool bEquipment = m_eCurPacket==PACKET_EQUIPMENT;
m_pBtnEquip->setEnabled(true);
m_pBtnProps->setEnabled(true);
m_pBtnEquip->setSelectedIndex(bEquipment ? 1 : 0);
m_pBtnProps->setSelectedIndex(!bEquipment ? 1 : 0);
std::string text = "";
if (bEquipment)
{
text = WStrToUTF8(L"装备");
m_pBtnEquip->setEnabled(false);
}else
{
text = WStrToUTF8(L"道具");
m_pBtnProps->setEnabled(false);
}
m_pPacketLayer->getLabelName()->setString(text.c_str());
}
void InstituteLayer::OnSwitchPageButton(CCObject *pSender)
{
}
void InstituteLayer::OnReturnButton(CCObject *pSender)
{
CCDirector::sharedDirector()->replaceScene(CCTransitionSlideInR::create(1.0f, MainSceneLayer::scene()));//右端进入,回到主场景
}
void InstituteLayer::OnChatButton(CCObject *pSender)
{
CCDirector::sharedDirector()->pushScene(CCTransitionFade::create(1.0f, FriendLayer::GetScene()));//聊天框一直在内存
}