游戏客户端之cocos2dx客户端应用思路

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()));//聊天框一直在内存
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值