记一次对cocos2dx的对象统计及内存泄露的历程(ps:很老的cocos版本)

对象统计思路:

为了不对引擎造成破话,都是采取帮函数指针、增加借口、多态性的方式,所以不需要再引擎中include包含统计类,当做插件set进去,类似于组件模式,扩展引擎。

1、对象创建时统计:

因为创建对象是通过create接口创建(先不考虑引擎内部new对象的情况,下面会说明怎么避免这个问题),这个借口里又会调用autorelease放到自动释放池中自动管理内存,所以在autorelease里放个函数指针绑定统计函数CNodeCounterLog::newNodeCount(CCObject* _node),里面写统计逻辑

2、对象销毁时统计:

对象销毁时调用的是release,里面会判断引用计数是否为0,0则销毁,所以在这里也放个函数指针绑定统计函数CNodeCounterLog::deleteNodeCount(CCObject* _node) ,里面写统计逻辑

3、统计逻辑里面获取对象及其大小:

可以通过typeid(*_node).name()获取到对象的名称,大小的话sizeof(*_node)获取不到的,不像java可以通过反射获取到对象。所以就定了个反射列表来获取对应的大小:

if (_name == CC_LuaStack) return sizeof(ccluaStack){}
else if (_name == CC_String) return sizeof(CCString){}
else //为了防止遗漏,把未在反射列表的对象写到本地记录一下
{
char tmp[128];
sprintf(tmp,“——- not found class:%s\n”,_name.c_str());
cclOG(“%s”,tmp);
CNodeCounterLog::GetInstance()->log(tmp); //未添加经列表的写到日志中,方便添加
return -1;
}

信息结构体
对象名、个数、总大小,对象指针的集合vector

4、统计贴图纹理对象占用的内存:

再纹理缓存集合CCTextureCache中增加个借口让统计类调用获取缓存集合textures,遍历textures,
每个对象的占用计算结果 = width * height * 每个像素格式占用位数 / 8.f,单位byte

5、统计字体纹理对象占用的内存:

直接从统计集合中获取到cclabelTTF在获取其纹理计算,公式同上。

6、统计lua占用内存:

在lua脚本引擎中增加个获取大小的借口即可,

int ccluaEngine::getMemSize()
{
lua_State* state = m_stack->getLuaState();
return state ? lua_gc(state,LUA_GCCOUNT,0) : 0;
}

7、实时绘制信息:

利用多态性,统计类继承CCNode,重写visit函数,然后在CCDirector加个CCNode节点,把统计类set进去,每帧调用这个CCNode的visit。

8、规避引擎内不统一的写法造成统计类统计错误的问题:

引擎内部有些地方使用new来创建对象,release销毁对象,会造成统计类里对象不增加,但会减少的情况。所以为了避免这个问题,在CCObject中增加了个标记,只要调用了autorelease进入统计的对象就标记一下,减少的时候判断一下该对象是否为标记过得对象,否则不进入统计逻辑直接返回。

9、黑白名单模式:

通过黑白名单来决定对象是否需要统计,减少不必要的对象统计或者具体统计某些对象。

内存泄露查找

反复打开关闭某个界面几次,看对象统计的总和是否不断增加,如果是则有对象泄露(增量是一样的)。

内存泄露定位

查看是开的是哪个xxx.json,命令行有log,即可查找到对用的lua文件
搜索一下有retain的相关代码,注释掉后再次测一下,如果恢复正常则可以判断是忘了release
搜索一下有removeFromParentAndCleanup(false)的代码,改为true后恢复正常(removeFromParentAndCleanup里面是stopAll定时器、动画)

可以在vs装上lua调试插件BabeLua, 断点追踪,看下创建时和销毁时的地址是否一致

有图有真相

附上代码:

CCNodeCounterDef.h

#ifndef __NODE_DEFINE_H__
#define __NODE_DEFINE_H__

#include <vector>
#include <string>

#define CC_LuaStack "ccluaStack"
#define CC_String "CCString"
#define CC_Array "CCArray"
#define CC_Bool "CCBool"
#define CC_Integer "CCInteger"
#define CC_LabelAtlas "cclabelAtlas"
#define CC_TextureAtlas "CCTextureAtlas"
#define CC_Texture2D "CCTexture2D"
#define CC_Dictionary "CCDictionary"
#define CC_HTTPRequest "CCHTTPRequest"
#define CC_Image "CCImage"
#define CC_Sprite "CCSprite"
#define CC_GraySprite "CCGraySprite"
#define CC_Scene "CCScene"
#define CC_LabelTTF "cclabelTTF"
#define CC_NodeRGBA "CCNodeRGBA"
#define CC_TargetedTouchHandler "CC_TargetedTouchHandler"
#define CC_UIButton "UIButton"
#define CC_Scale9Sprite "CCScale9Sprite"
#define CC_GUIRenderer "GUIRenderer"
#define CC_SpriteBatchNode "CCSpriteBatchNode"
#define CC_Timer "CCTimer"
#define CC_Layer "cclayer"
#define CC_LayerRGBA "cclayerRGBA"
#define CC_DrawNode "CCDrawNode"
#define CC_TexturePVR "CCTexturePVR"
#define CC_UILayer "UILayer"
#define CC_UIRootWidget "UIRootWidget"
#define CC_UILabel "UILabel"
#define CC_SchedulerScriptHandlerEntry "CCSchedulerScriptHandlerEntry"
#define CC_NotificationObserver "CCNotificationObserver"
#define CC_UIRectClippingNode "UIRectClippingNode"
#define CC_Progresstimer "CCProgresstimer"
#define CC_DelayTime "CCDelayTime"
#define CC_Sequence "CCSequence"
#define CC_ZipFile "CCZipFile"
#define CC_AutoreleasePool "CCAutoreleasePool"
#define CC_CallFunc "CCCallFunc"
#define CC_TargetedTouchHandler "CCTargetedTouchHandler"
#define CC_Touch "CCTouch"
#define CC_BMFontConfiguration "CCBMFontConfiguration"
#define CC_LabelBMFont "cclabelBMFont"
#define CC_Color3bObject "CCColor3bObject"
#define CC_ClippingRegionNode "CcclippingRegionNode"
#define CC_Invocation "CCInvocation"
#define CC_EditBox "CCEditBox"
#define CC_Set "CCSet"
#define CC_MenuItemSprite "CcmenuItemSprite"
#define CC_Menu "Ccmenu"
#define CC_Progressto "CCProgressto"
#define CC_AnimationConf "AnimationConf"
#define CC_UILayout "UILayout"
#define CC_UIImageView "UIImageView"
#define CC_UILabelBMFont "UILabelBMFont"
#define CC_MovetoPX "CCMovetoPX"
#define CC_Moveto "CCMoveto"
#define CC_FadeOut "CCFadeOut"
#define CC_MoveBy "CCMoveBy"
#define CC_Node "CCNode"
#define CC_AnimationFrame "CCAnimationFrame"
#define CC_Animation "CCAnimation"
#define CC_QtzSprite "QtzSprite"
#define CC_CallFuncN "CCCallFuncN"
#define CC_Animation222 "Animation"
#define CC_display "display"
#define CC_Joint "Joint"
#define CC_QtzBone "QtzBone"
#define CC_Animate "CCAnimate"
#define CC_RepeatForever "CCRepeatForever"
#define CC_AnimationClip "AnimationClip"
#define CC_Rotateto "CCRotateto"
#define CC_QtzZOrderNode "QtzZOrderNode"
#define CC_QtzBoneAnimation "QtzBoneAnimation"
#define CC_Scaleto "CCScaleto"
#define CC_Repeat "CCRepeat"
#define CC_Spawn "CCSpawn"
#define CC_Fadeto "CCFadeto"
#define CC_TintTo "CCTintTo"
#define CC_UIWidget "UIWidget"
#define CC_TouchScriptHandlerEntry "CCTouchScriptHandlerEntry"
#define CC_JumpTo "CCJumpTo"
#define CC_ParticleSystemQuad "CCParticleSystemQuad"
#define CC_EaseExponentialOut "CCEaseExponentialOut"
#define CC_StandardTouchHandler "CCStandardTouchHandler"
#define CC_TintBy "CCTintBy"
#define CC_EaseBackOut "CCEaseBackOut"
#define CC_LayerColor "cclayerColor"
#define CC_SpriteFrame "CCSpriteFrame"
#define CC_UILoadingBar "UILoadingBar"
#define CC_FadeIn "CCFadeIn"
#define CC_QParticleSpriteQuad "QParticleSpriteQuad"
#define CC_ScaleBy "CCScaleBy"
#define CC_UIListView "UIListView"
#define CC_EaseBackIn "CCEaseBackIn"
#define CC_UILinearLayoutParameter "UILinearLayoutParameter"
#define CC_Show "CCShow"
#define CC_Hide "CCHide"
#define CC_UICheckBox "UICheckBox"
#define CC_UIListViewEx "UIListViewEx"
#define CC_UIListViewSmartAlign "UIListViewSmartAlign"
#define CC_UICCTextField "UICCTextField"
#define CC_UIRelativeLayoutParameter "UIRelativeLayoutParameter"
#define CC_OrbitCamera "CCOrbitCamera"
#define CC_UIScrollView "UIScrollView"
#define CC_UITextField "UITextField"
#define CC_RichText "RichText"

/****************** gloable singleton #define CC_GLProgram "CCGLProgram" #define CC_Configuration "CCConfiguration" #define CC_NotificationCenter "CCNotificationCenter" #define CC_ArmatureDataManager "CCArmatureDataManager" #define CC_displayLinkDirector "CCdisplayLinkDirector" #define CC_Scheduler "CCScheduler" #define CC_ActionManager "CCActionManager" #define CC_Touchdispatcher "CCTouchdispatcher" #define CC_Keypaddispatcher "CCKeypaddispatcher" #define CC_shadercache "CCshadercache" #define CC_TextureCache "CCTextureCache" #define CC_SpriteFrameCache "CCSpriteFrameCache" */
std::vector<std::string>    gBlackList;
std::vector<std::string>    gWhiteList;
void gInitBlackList()
{
    //gBlackList.push_back(CC_LuaStack);
    //gBlackList.push_back(CC_String);
    gBlackList.push_back(CC_Array);
    //gBlackList.push_back(CC_Bool);
    //gBlackList.push_back(CC_Integer);
    //gBlackList.push_back(CC_LabelAtlas);
    //gBlackList.push_back(CC_TextureAtlas);
    gBlackList.push_back(CC_Texture2D);
    //gBlackList.push_back(CC_Dictionary);
    //gBlackList.push_back(CC_HTTPRequest);
    //gBlackList.push_back(CC_Image);
    //gBlackList.push_back(CC_Sprite);
    //gBlackList.push_back(CC_GraySprite);
    //gBlackList.push_back(CC_Scene);
    //gBlackList.push_back(CC_LabelTTF);
    //gBlackList.push_back(CC_NodeRGBA);
    //gBlackList.push_back(CC_TargetedTouchHandler);
    //gBlackList.push_back(CC_UIButton);
    //gBlackList.push_back(CC_Scale9Sprite);
    //gBlackList.push_back(CC_GUIRenderer);
    //gBlackList.push_back(CC_SpriteBatchNode);
    gBlackList.push_back(CC_Timer);//sssssssss
    //gBlackList.push_back(CC_Layer);
    //gBlackList.push_back(CC_LayerRGBA);
    //gBlackList.push_back(CC_DrawNode);
    //gBlackList.push_back(CC_TexturePVR);
    //gBlackList.push_back(CC_UILayer);
    //gBlackList.push_back(CC_UIRootWidget);
    //gBlackList.push_back(CC_UILabel);
    gBlackList.push_back(CC_SchedulerScriptHandlerEntry); //sssssssss
    //gBlackList.push_back(CC_NotificationObserver);
    //gBlackList.push_back(CC_UIRectClippingNode);
    //gBlackList.push_back(CC_Progresstimer);
    gBlackList.push_back(CC_DelayTime);//sssssssss
    //gBlackList.push_back(CC_Sequence);
    gBlackList.push_back(CC_ZipFile);
    gBlackList.push_back(CC_AutoreleasePool);
    gBlackList.push_back(CC_CallFunc);
    gBlackList.push_back(CC_TargetedTouchHandler);
    gBlackList.push_back(CC_Touch);
    gBlackList.push_back(CC_BMFontConfiguration);
    //gBlackList.push_back(CC_LabelBMFont);
    //gBlackList.push_back(CC_Color3bObject);
    gBlackList.push_back(CC_ClippingRegionNode);
    gBlackList.push_back(CC_Invocation);
    //gBlackList.push_back(CC_EditBox);
    gBlackList.push_back(CC_Set);
    //gBlackList.push_back(CC_MenuItemSprite);
    //gBlackList.push_back(CC_Menu);
    gBlackList.push_back(CC_Progressto);
    gBlackList.push_back(CC_AnimationConf);
    //gBlackList.push_back(CC_UILayout);
    //gBlackList.push_back(CC_UIImageView);
    //gBlackList.push_back(CC_UILabelBMFont);
    gBlackList.push_back(CC_MovetoPX);
    gBlackList.push_back(CC_Moveto);
    gBlackList.push_back(CC_FadeOut);
    gBlackList.push_back(CC_MoveBy);
    gBlackList.push_back(CC_Node);
    gBlackList.push_back(CC_AnimationFrame);
    gBlackList.push_back(CC_Animation);
    //gBlackList.push_back(CC_QtzSprite);
    gBlackList.push_back(CC_CallFuncN);
    gBlackList.push_back(CC_Animation222);
    gBlackList.push_back(CC_display);
    gBlackList.push_back(CC_Joint);
    //gBlackList.push_back(CC_QtzBone);
    gBlackList.push_back(CC_Animate);
    gBlackList.push_back(CC_RepeatForever);
    gBlackList.push_back(CC_AnimationClip);
    //gBlackList.push_back(CC_Rotateto);
    //gBlackList.push_back(CC_QtzZOrderNode);
    //gBlackList.push_back(CC_QtzBoneAnimation);
    gBlackList.push_back(CC_Scaleto);
    gBlackList.push_back(CC_Repeat);
    gBlackList.push_back(CC_Spawn);
    gBlackList.push_back(CC_Fadeto);
    gBlackList.push_back(CC_TintTo);
    //gBlackList.push_back(CC_UIWidget);
    gBlackList.push_back(CC_TouchScriptHandlerEntry);
    gBlackList.push_back(CC_JumpTo);
    gBlackList.push_back(CC_ParticleSystemQuad);
    gBlackList.push_back(CC_EaseExponentialOut);
    gBlackList.push_back(CC_StandardTouchHandler);
    gBlackList.push_back(CC_TintBy);
    gBlackList.push_back(CC_EaseBackOut);
    gBlackList.push_back(CC_LayerColor);
    //gBlackList.push_back(CC_SpriteFrame);
    //gBlackList.push_back(CC_UILoadingBar);
    gBlackList.push_back(CC_FadeIn);
    gBlackList.push_back(CC_QParticleSpriteQuad);
    gBlackList.push_back(CC_ScaleBy);
    //gBlackList.push_back(CC_UIListView);
    gBlackList.push_back(CC_EaseBackIn);
    gBlackList.push_back(CC_UILinearLayoutParameter);
    gBlackList.push_back(CC_Show);
    gBlackList.push_back(CC_Hide);
    //gBlackList.push_back(CC_UICheckBox);
    //gBlackList.push_back(CC_UIListViewEx);
    gBlackList.push_back(CC_UIListViewSmartAlign);
    //gBlackList.push_back(CC_UICCTextField);
    gBlackList.push_back(CC_UIRelativeLayoutParameter);
    gBlackList.push_back(CC_OrbitCamera);
    //gBlackList.push_back(CC_LabelTTF);
}

void gInitWhiteList()
{
    //gWhiteList.push_back(CC_RichText);
    gWhiteList.push_back(CC_LabelTTF);
    gWhiteList.push_back(CC_UILabel);
    gWhiteList.push_back(CC_Sprite);
    //gWhiteList.push_back(CC_Scale9Sprite);
    gWhiteList.push_back(CC_GUIRenderer);
    gWhiteList.push_back(CC_UIImageView);
    gWhiteList.push_back(CC_LabelBMFont);
    gWhiteList.push_back(CC_HTTPRequest);
    //gWhiteList.push_back(CC_Texture2D);

}

#endif

CCNodeCounter.h

#ifndef __NODE_COUNTER_H__
#define __NODE_COUNTER_H__ 

#include <iostream>
#include <vector>
#include <map>

#include "cocos2d.h"

/* * 改动文件 * CCDirector * CCObject * CCTextureCache * CCTexture2D * ccluaEngine * GUIReader * document.h */

struct NodeInfo
{
    NodeInfo() : mName(""),mCounter(0),mTotalSize(0),mPerSize(0)
    {
    }
    std::string             mName;
    int                     mCounter;
    int                     mTotalSize;
    int                     mPerSize;
    std::vector<cocos2d::CCObject*> mPtrVec;
};

class CNodeCounterLog : public cocos2d::CCNode
{
public:
    CNodeCounterLog();
    virtual ~CNodeCounterLog();

    static CNodeCounterLog* GetInstance();
    static CNodeCounterLog* gNodeCounterLog;

    void            destory();
    void            initFunc();
    void            initHUD();
    void            initShowBtn();

    static void     newNodeCount(cocos2d::CCObject* _node);
    void            increaseFunc(const std::string _name,int size,cocos2d::CCObject* obj);
    static void     deleteNodeCount(cocos2d::CCObject* _node);
    void            decreaseFunc(const std::string _name,cocos2d::CCObject* obj);
    bool            isBeTraced(const std::string& _name,CCObject* _node,bool _isIncrease);
    bool            isBlackList(const std::string& _name) const;
    bool            isWhiteList(const std::string& _name) const;
    std::string     getTypeName(const cocos2d::CCObject* _node) const; //获取类型名字符串
    std::map<std::string,NodeInfo*>&       getNodeMap() { return mNodeMap; }

    //提供lua掉的接口
    void            setopen(bool _open) const;
    void            setShowAll(bool _b);
    void            setWhiteCheck(bool _b) { mIsWhite = _b; }
    bool            isWhiteCheck() const { return mIsWhite; }
    void            log(const std::string& _str = ""); //写到本地log

    virtual void    visit() override;//利用node的visit绘制信息
    void            getInfo(std::string& _info,std::string& _info2);
    void            getTextureInfo(std::string& _info,float& _size);
    void            getcclabelTextureInfo(std::string& _info,NodeInfo* _nodeInfo,float& _size);
    void            getLuaInfo(std::string& _info,float& _size);
    void            getJsonInfo(std::string& _info,float& _size);

private:
    typedef std::map<std::string,NodeInfo*> StrNodeMap;
    StrNodeMap                          mNodeMap;
    bool                                mIsWhite;
    bool                                mShowAll;

    cocos2d::CCNode*                    mParentNode;
    cocos2d::cclayerColor*              mLayer;
    cocos2d::cclabelTTF*                mLabelInfo;
    cocos2d::cclabelTTF*                mLabelInfo2;
};

#define Get_NodeCounter() CNodeCounterLog::GetInstance();

#endif

CCNodeCounter.cpp

#include "CCNodeCounter.h"
#include "cocos2d.h"
#include <typeinfo>
#include "CCNodeCounterDef.h"
#include <fstream> 
#include <algorithm>

#include "ccluaStack.h"
#include "network/CCHTTPRequest.h"
#include "CocosGUI.h"
#include "CCScale9Sprite.h"
#include "platform/CCZipFile.h"
#include "GUI/BaseClasses/UIWidget.h"
#include "GUI/CCEditBox/CCEditBox.h"
#include "QtzAnimation/AnimationData.h"
#include "QtzAnimation/AnimationClip.h"
#include "QtzAnimation/Animation.h"
#include "QtzAnimation/display.h"
#include "QtzAnimation/Joint.h"

USING_NS_CC;
USING_NS_CC_EXTRA;
USING_NS_CC_EXT;

const static std::string gCocosNS   =   "::";
const static std::string logFile    =   "d:\\a_counterLog.lua";
const static std::string gLogFormat = "--- [num=%6d] [size=%8.2fkb] [%s]\n";
const static std::string gLogFormatTexture = "--- [num=%6d] [size=%8.2fmb] [%s]\n";
const static std::string gLogTotal = "------- [totalNum=%8u] [totalSize=%10.2lfmb]\n";
const static std::string gLogTotalMemSize = "------- [total Mem=%8.2fmb]\n";
const static int gChangeLine        =    18;

static int GetSizeByName(const std::string& _name)
{
    if (_name == CC_LuaStack) return sizeof(ccluaStack);
    else if (_name == CC_String) return sizeof(CCString);
    else if (_name == CC_Array) return sizeof(CCArray);
    else if (_name == CC_Bool) return sizeof(CCBool);
    else if (_name == CC_Bool) return sizeof(CCBool);
    else if (_name == CC_Integer) return sizeof(CCInteger);
    else if (_name == CC_LabelAtlas) return sizeof(cclabelAtlas);
    else if (_name == CC_TextureAtlas) return sizeof(CCTextureAtlas);
    else if (_name == CC_Texture2D) return sizeof(CCTexture2D);
    else if (_name == CC_Dictionary) return sizeof(CCDictionary);
    else if (_name == CC_HTTPRequest) return sizeof(CCHTTPRequest);
    else if (_name == CC_Image) return sizeof(CCImage);
    else if (_name == CC_Sprite) return sizeof(CCSprite);
    else if (_name == CC_GraySprite) return sizeof(CCGraySprite);
    else if (_name == CC_Scene) return sizeof(CCScene);
    else if (_name == CC_LabelTTF) return sizeof(cclabelTTF);
    else if (_name == CC_NodeRGBA) return sizeof(CCNodeRGBA);
    else if (_name == CC_TargetedTouchHandler) return sizeof(CCTargetedTouchHandler);
    else if (_name == CC_UIButton) return sizeof(UIButton);
    else if (_name == CC_Scale9Sprite) return sizeof(CCScale9Sprite);
    else if (_name == CC_GUIRenderer) return sizeof(GUIRenderer);
    else if (_name == CC_SpriteBatchNode) return sizeof(CCSpriteBatchNode);
    else if (_name == CC_Timer) return sizeof(CCTimer);
    else if (_name == CC_Layer) return sizeof(cclayer);
    else if (_name == CC_LayerRGBA) return sizeof(cclayerRGBA);
    else if (_name == CC_DrawNode) return sizeof(CCDrawNode);
    else if (_name == CC_TexturePVR) return sizeof(CCTexturePVR);
    else if (_name == CC_UILayer) return sizeof(UILayer);
    else if (_name == CC_UIRootWidget) return sizeof(UIRootWidget);
    else if (_name == CC_UILabel) return sizeof(UILabel);
    else if (_name == CC_SchedulerScriptHandlerEntry) return sizeof(CCSchedulerScriptHandlerEntry);
    else if (_name == CC_NotificationObserver) return sizeof(CCNotificationObserver);
    else if (_name == CC_UIRectClippingNode) return sizeof(UIRectClippingNode);
    else if (_name == CC_Progresstimer) return sizeof(CCProgresstimer);
    else if (_name == CC_DelayTime) return sizeof(CCDelayTime);
    else if (_name == CC_Sequence) return sizeof(CCSequence);
    else if (_name == CC_ZipFile) return sizeof(CCZipFile);
    else if (_name == CC_AutoreleasePool) return sizeof(CCAutoreleasePool);
    else if (_name == CC_CallFunc) return sizeof(CCCallFunc);
    else if (_name == CC_TargetedTouchHandler) return sizeof(CCTargetedTouchHandler);
    else if (_name == CC_Touch) return sizeof(CCTouch);
    else if (_name == CC_BMFontConfiguration) return sizeof(CCBMFontConfiguration);
    else if (_name == CC_LabelBMFont) return sizeof(cclabelBMFont);
    else if (_name == CC_Color3bObject) return sizeof(CCColor3bObject);
    else if (_name == CC_ClippingRegionNode) return sizeof(CcclippingRegionNode);
    else if (_name == CC_Invocation) return sizeof(CCInvocation);
    else if (_name == CC_EditBox) return sizeof(CCEditBox);
    else if (_name == CC_Set) return sizeof(CCSet);
    else if (_name == CC_MenuItemSprite) return sizeof(CcmenuItemSprite);
    else if (_name == CC_Menu) return sizeof(Ccmenu);
    else if (_name == CC_Progressto) return sizeof(CCProgressto);
    else if (_name == CC_AnimationConf) return sizeof(AnimationConf);
    else if (_name == CC_UILayout) return sizeof(UILayout);
    else if (_name == CC_UIImageView) return sizeof(UIImageView);
    else if (_name == CC_UILabelBMFont) return sizeof(UILabelBMFont);
    else if (_name == CC_MovetoPX) return sizeof(CCMovetoPX);
    else if (_name == CC_Moveto) return sizeof(CCMoveto);
    else if (_name == CC_FadeOut) return sizeof(CCFadeOut);
    else if (_name == CC_MoveBy) return sizeof(CCMoveBy);
    else if (_name == CC_Node) return sizeof(CCNode);
    else if (_name == CC_AnimationFrame) return sizeof(CCAnimationFrame);
    else if (_name == CC_Animation) return sizeof(CCAnimation);
    else if (_name == CC_QtzSprite) return sizeof(QtzSprite);
    else if (_name == CC_CallFuncN) return sizeof(CCCallFuncN);
    else if (_name == CC_Animation222) return sizeof(Animation);
    else if (_name == CC_display) return sizeof(display);
    else if (_name == CC_Joint) return sizeof(Joint);
    else if (_name == CC_QtzBone) return sizeof(QtzBone);
    else if (_name == CC_Animate) return sizeof(CCAnimate);
    else if (_name == CC_RepeatForever) return sizeof(CCRepeatForever);
    else if (_name == CC_AnimationClip) return sizeof(AnimationClip);
    else if (_name == CC_Rotateto) return sizeof(CCRotateto);
    else if (_name == CC_QtzZOrderNode) return sizeof(QtzZOrderNode);
    else if (_name == CC_QtzBoneAnimation) return sizeof(QtzBoneAnimation);
    else if (_name == CC_Scaleto) return sizeof(CCScaleto);
    else if (_name == CC_Repeat) return sizeof(CCRepeat);
    else if (_name == CC_Spawn) return sizeof(CCSpawn);
    else if (_name == CC_Fadeto) return sizeof(CCFadeto);
    else if (_name == CC_TintTo) return sizeof(CCTintTo);
    else if (_name == CC_UIWidget) return sizeof(UIWidget);
    else if (_name == CC_TouchScriptHandlerEntry) return sizeof(CCTouchScriptHandlerEntry);
    else if (_name == CC_JumpTo) return sizeof(CCJumpTo);
    else if (_name == CC_ParticleSystemQuad) return sizeof(CCParticleSystemQuad);
    else if (_name == CC_EaseExponentialOut) return sizeof(CCEaseExponentialOut);
    else if (_name == CC_StandardTouchHandler) return sizeof(CCStandardTouchHandler);
    else if (_name == CC_TintBy) return sizeof(CCTintBy);
    else if (_name == CC_EaseBackOut) return sizeof(CCEaseBackOut);
    else if (_name == CC_LayerColor) return sizeof(cclayerColor);
    else if (_name == CC_SpriteFrame) return sizeof(CCSpriteFrame);
    else if (_name == CC_UILoadingBar) return sizeof(UILoadingBar);
    else if (_name == CC_FadeIn) return sizeof(CCFadeIn);
    else if (_name == CC_QParticleSpriteQuad) return sizeof(QParticleSpriteQuad);
    else if (_name == CC_ScaleBy) return sizeof(CCScaleBy);
    else if (_name == CC_UIListView) return sizeof(UIListView);
    else if (_name == CC_EaseBackIn) return sizeof(CCEaseBackIn);
    else if (_name == CC_UILinearLayoutParameter) return sizeof(UILinearLayoutParameter);
    else if (_name == CC_Show) return sizeof(CCShow);
    else if (_name == CC_Hide) return sizeof(CCHide);
    else if (_name == CC_UICheckBox) return sizeof(UICheckBox);
    else if (_name == CC_UIListViewEx) return sizeof(UIListViewEx);
    else if (_name == CC_UIListViewSmartAlign) return sizeof(UIListViewSmartAlign);
    else if (_name == CC_UICCTextField) return sizeof(UICCTextField);
    else if (_name == CC_UIRelativeLayoutParameter) return sizeof(UIRelativeLayoutParameter);
    else if (_name == CC_OrbitCamera) return sizeof(CCOrbitCamera);
    else if (_name == CC_UIScrollView) return sizeof(UIScrollView);
    else if (_name == CC_UITextField) return sizeof(UITextField);
    else
    {
        char tmp[128];
        sprintf(tmp,"------- not found class:%s\n",_name.c_str());
        cclOG("%s",tmp);
        CNodeCounterLog::GetInstance()->log(tmp); //未添加经列表的写到日志中,方便添加
        return -1;
    }
}

CNodeCounterLog* CNodeCounterLog::gNodeCounterLog = NULL;

CNodeCounterLog::CNodeCounterLog() 
: mIsWhite(false),mParentNode(NULL),mLabelInfo(NULL),mLabelInfo2(NULL),mShowAll(true)
{
    mNodeMap.clear();
}

CNodeCounterLog::~CNodeCounterLog()
{
    for (StrNodeMap::iterator iter = mNodeMap.begin(); iter != mNodeMap.end(); ++iter)
    {
        if (iter->second != nullptr)
            delete iter->second;
    }
    setopen(false);
    CCDirector::sharedDirector()->setNodeCounter(NULL);
    mNodeMap.clear();
    mLayer->removeFromParentAndCleanup(true);
    mLabelInfo->removeFromParentAndCleanup(true);
    mLabelInfo2->removeFromParentAndCleanup(true);
    //Todo: 不知道为啥析构时这里老是蹦,所以上面释放子节点
    //CC_SAFE_RELEASE(mParentNode); 
}

CNodeCounterLog* CNodeCounterLog::GetInstance()
{
    if (!gNodeCounterLog)
    {
        gNodeCounterLog = new CNodeCounterLog();
        gNodeCounterLog->initFunc();
    }
    return gNodeCounterLog;
}

void CNodeCounterLog::destory()
{
    if (gNodeCounterLog)
    {
        delete gNodeCounterLog;
        gNodeCounterLog = NULL;
    }
}

void CNodeCounterLog::initFunc()
{
    setopen(true);
    setWhiteCheck(false);
    gInitBlackList();
    gInitWhiteList();
    initHUD();

    CCDirector::sharedDirector()->setNodeCounter(this); //将这个类作为插件设置进去,以便每帧调用visit绘制
}

void CNodeCounterLog::initHUD()
{
    mParentNode = CCNode::create();
    mParentNode->retain();//retain父节点就行

    float scale = 1.5f;
    float alpha = 255.f;
    ccColor3B fontc = ccc3(255.f,255.f,255.f);
    CCSize size = CCDirector::sharedDirector()->getWinSize();

    mLayer = cclayerColor::create(ccc4(0.f,0.f,100.f),size.width,size.height);
    mLayer->setAnchorPoint(ccp(0.f,0.f));
    mLayer->setPosition(ccp(0.f,0.f));

    mLabelInfo = cclabelTTF::create();
    mLabelInfo->setAnchorPoint(ccp(0.f,1.f));
    mLabelInfo->setPosition(ccp(0.f,size.height));
    mLabelInfo->setScale(scale);
    mLabelInfo->setopacity(alpha);
    mLabelInfo->setColor(fontc);

    mLabelInfo2 = cclabelTTF::create();
    mLabelInfo2->setAnchorPoint(ccp(0.f,1.f));
    mLabelInfo2->setPosition(ccp(size.width/2.f,size.height));
    mLabelInfo2->setScale(scale);
    mLabelInfo2->setopacity(alpha);
    mLabelInfo2->setColor(fontc);

    mParentNode->addChild(mLayer);
    mParentNode->addChild(mLabelInfo);
    mParentNode->addChild(mLabelInfo2);
}

void CNodeCounterLog::setopen(bool _open) const
{
    if (_open)
    {
        void(*pfunNew)(CCObject*) = &CNodeCounterLog::newNodeCount;
        void(*pfunDelete)(CCObject*) = &CNodeCounterLog::deleteNodeCount;
        CCObject::SetNodeCounterFunc(pfunNew,pfunDelete); //绑定函数到ccobject中
    }
    else
    {
        CCObject::SetNodeCounterFunc(NULL,NULL);
    }
}

void CNodeCounterLog::setShowAll(bool _b)
{
    mShowAll = _b;
    CCSize size = CCDirector::sharedDirector()->getWinSize();
    if (_b)
    {
        mLayer->setContentSize(CCSize(size.width,size.height));
        mLayer->setPosition(0.f,0.f);
    }
    else
    {
        float width = 400.f;
        float height = 130.f;
        mLayer->setContentSize(CCSize(width,height));
        mLayer->setPosition(0.f,size.height - height);
    }

}

void CNodeCounterLog::newNodeCount(CCObject* _node)
{
    CNodeCounterLog* pLog = CNodeCounterLog::GetInstance();
    std::string typName(pLog->getTypeName(_node));
    _node->mIsAutoRelease = true;

    if (pLog->isWhiteCheck())
    {
        if (!pLog->isWhiteList(typName))
            return;
    }
    else
    {
        if (pLog->isBlackList(typName)) 
            return;
    }

    int size = ::GetSizeByName(typName);
    pLog->increaseFunc(typName,size,_node);
}

void CNodeCounterLog::increaseFunc(const std::string _name,CCObject* obj)
{
    CNodeCounterLog* pLog = CNodeCounterLog::GetInstance();
    StrNodeMap& nodeMap = pLog->getNodeMap();

    isBeTraced(_name,obj,true);

    bool isExist = false;
    for (StrNodeMap::iterator iter = nodeMap.begin(); iter != nodeMap.end(); ++iter)
    {
        if (_name == iter->first)
        {
            NodeInfo* nodeInfo = iter->second;
            nodeInfo->mCounter++;
            nodeInfo->mTotalSize += size;
            nodeInfo->mPtrVec.push_back(obj);
            isExist = true;
            break;
        }
    }
    if (!isExist)// 不存在,新建
    {
        NodeInfo* newNodeInfo = new NodeInfo();
        newNodeInfo->mName = _name;
        newNodeInfo->mCounter = 1;
        newNodeInfo->mTotalSize = size;
        newNodeInfo->mPerSize = size;
        newNodeInfo->mPtrVec.push_back(obj);
        nodeMap.insert(std::make_pair(_name,newNodeInfo));
    }
}

void CNodeCounterLog::deleteNodeCount(CCObject* _node)
{
    if (!_node->mIsAutoRelease)
        return;

    CNodeCounterLog* pLog = CNodeCounterLog::GetInstance();
    std::string typName(pLog->getTypeName(_node));
    if (pLog->isWhiteCheck())
    {
        if (!pLog->isWhiteList(typName))
            return;
    }
    else
    {
        if (pLog->isBlackList(typName))
            return;
    }

    int size = ::GetSizeByName(typName);
    pLog->decreaseFunc(typName,_node);
}

void CNodeCounterLog::decreaseFunc(const std::string _name,false);

    for (StrNodeMap::iterator iter = nodeMap.begin(); iter != nodeMap.end(); ++iter)
    {
        if (_name == iter->first)
        {
            NodeInfo* nodeInfo = iter->second;
            nodeInfo->mCounter--;
            nodeInfo->mTotalSize -= size;
            for (std::vector<CCObject*>::iterator ptrIter = nodeInfo->mPtrVec.begin(); ptrIter != nodeInfo->mPtrVec.end(); ++ptrIter)
            {
                if (*ptrIter == obj)
                {
                    nodeInfo->mPtrVec.erase(ptrIter);
                    break;
                }
            }

            if (nodeInfo->mCounter == 0)
                nodeMap.erase(iter);
            break;
        }
    }
}

//追踪具体的某个对象
bool CNodeCounterLog::isBeTraced(const std::string& _name,bool _isIncrease)
{
    return false;

    const char* tmp = _name.c_str();
    //if (strcmp(tmp,CC_UILayout) == 0)
    //{
    // UIWidget* layout = dynamic_cast<UIWidget*>(_node);
    // if (layout)
    // {
            char logStr[128] = { 0 };
            if (_isIncrease)
                sprintf(logStr,"--- Increase %s\t\t:0x%x\n",tmp,_node);
            else
                sprintf(logStr,"--- Decrease %s\t\t:0x%x\n",_node);
            log(logStr);

    // return true;
    // }
    //}
    return false;
}

bool CNodeCounterLog::isBlackList(const std::string& _name) const
{
    for (std::vector<std::string>::const_iterator iter = gBlackList.begin(); iter != gBlackList.end(); ++iter)
    {
        if (_name == *iter)
            return true;
    }
    return false;
}

bool CNodeCounterLog::isWhiteList(const std::string& _name) const
{
    for (std::vector<std::string>::const_iterator iter = gWhiteList.begin(); iter != gWhiteList.end(); ++iter)
    {
        if (_name == *iter)
            return true;
    }
    return false;
}

std::string CNodeCounterLog::getTypeName(const cocos2d::CCObject* _node) const
{
    std::string typName(typeid(*_node).name());
    short lastpos = typName.find_last_of(gCocosNS); //干掉前缀class coocs2d::
    if (lastpos == std::string::npos)
    {
        assert(false,"--------- typName is not cocos2d::");
        return typName;
    }
    return  typName.substr(lastpos + 1,typName.length() - lastpos - 1);;
}

void CNodeCounterLog::log(const std::string& _str /* = "" */)
{
    std::ofstream osOutFile(logFile.c_str(),std::ios::app);
    if (!osOutFile.is_open())
    {
        osOutFile.close();
        assert(false,"--- Error: write file error");
        return;
    }
    osOutFile << _str;
    osOutFile.close();
}

void CNodeCounterLog::visit()
{
    std::string info("");
    std::string info2("");
    getInfo(info,info2);
    if (mParentNode && mLabelInfo && mLabelInfo2) 
    {
        mLabelInfo->setString(info.c_str());
        mLabelInfo2->setString(info2.c_str());
        mParentNode->visit();
    }
    else
        assert(false,"--- Error: display node null");
}

void CNodeCounterLog::getInfo(string& _info,std::string& _info2) 
{
    std::string allInfo("");
    std::string allInfo2("\n");
    unsigned int totalNum = 0;
    unsigned int totalSize = 0;
    int flag = 0;
    float totalMem = 0.f;

    std::string labelTextureInfo("");
    for (StrNodeMap::const_iterator iter = mNodeMap.begin(); iter != mNodeMap.end(); ++iter)
    {
        //cclabel纹理信息
        getcclabelTextureInfo(labelTextureInfo,iter->second,totalMem);

        totalNum += iter->second->mCounter;
        totalSize += iter->second->mTotalSize;
        char tmp[128] = { 0 };
        sprintf(tmp,gLogFormat.c_str(),iter->second->mCounter,(float)iter->second->mTotalSize/1024.f,iter->second->mName.c_str());
        if (flag < gChangeLine) // 挂在另一个节点显示
            allInfo.append(tmp);
        else
            allInfo2.append(tmp);
        flag++;
    }

    //纹理信息
    std::string textureInfo("");
    getTextureInfo(textureInfo,totalMem);

    //lua大小
    std::string luaInfo("");
    getLuaInfo(luaInfo,totalMem);

    //json缓存大小
    std::string jsonInfo("");
    getJsonInfo(jsonInfo,totalMem);

    char tmp1[128] = { 0 };
    char tmp2[128] = { 0 };
    float totalMb = (float)(totalSize / 1024) / 1024.f;
    totalMem += totalMb;

    sprintf(tmp1,gLogTotalMemSize.c_str(),totalMem);
    sprintf(tmp2,gLogFormatTexture.c_str(),totalNum,totalMb,"CCNodes");

    _info.append(tmp1); //total
    _info.append(textureInfo);
    _info.append(labelTextureInfo);
    _info.append(luaInfo);
    _info.append(jsonInfo);
    _info.append(tmp2); //total

    if (mShowAll)
    {
        _info.append("----------- split -----------\n");
        _info.append(allInfo);
        _info2.append(allInfo2);
    }
}

void CNodeCounterLog::getTextureInfo(std::string& _info,float& _size)
{
    CCDictionary* textures = CCTextureCache::sharedTextureCache()->getAllTextures();
    unsigned int counter = 0;
    unsigned int totalBytes = 0;

    CCDictElement* pElement = NULL;
    CCDICT_FOREACH(textures,pElement)
    {
        CCTexture2D* tex = (CCTexture2D*)pElement->getobject();
        unsigned int bpp = tex->bitsPerPixelForFormat();
        unsigned int bytes = tex->getPixelsWide() * tex->getPixelsHigh() * bpp / 8;
        totalBytes += bytes;
        counter++;
    }

    if (totalBytes > 0)
    {
        float totalMb = (float)(totalBytes / 1024) / 1024.f;
        _size += totalMb;
        char tmp[128] = { 0 };
        sprintf(tmp,counter,CC_Texture2D);

        //if (totalMb > 150.f)
        // CCTextureCache::sharedTextureCache()->removeUnusedTextures();

        _info.append(tmp);
    }
}

void CNodeCounterLog::getcclabelTextureInfo(std::string& _info,float& _size)
{
    if (strcmp(_nodeInfo->mName.c_str(),CC_LabelTTF) != 0)
        return;

    unsigned int totalBytes = 0;
    for (std::vector<CCObject*>::const_iterator iter = _nodeInfo->mPtrVec.begin(); iter != _nodeInfo->mPtrVec.end(); ++iter)
    {
        cclabelTTF* label = dynamic_cast<cclabelTTF*>(*iter);
        if (label)
        {
            CCTexture2D* tex = label->getTexture();
            unsigned int bpp = tex->bitsPerPixelForFormat();
            if (bpp != -1)
            {
                unsigned int bytes = tex->getPixelsWide() * tex->getPixelsHigh() * bpp / 8;
                totalBytes += bytes;
            }
            else
            {
                int a = 1;
            }
        }
    }

    if (totalBytes > 0)
    {
        float totalMb = (float)(totalBytes / 1024) / 1024.f;
        _size += totalMb;
        char tmp[128] = { 0 };
        sprintf(tmp,_nodeInfo->mPtrVec.size(),CC_LabelTTF);

        /*if (totalMb > 150.f) //缓存纹理超过150自动清除unusedTex CCTextureCache::sharedTextureCache()->removeUnusedTextures();*/

        _info.append(tmp);
    }
}

void CNodeCounterLog::getLuaInfo(std::string& _info,float& _size)
{
    int size = ccluaEngine::defaultEngine()->getMemSize();
    if (size > 0)
    {
        char tmp[128] = { 0 };
        float totalMb = (float)size / 1024.f;
        _size += totalMb;
        sprintf(tmp,1,CC_LuaStack);
        _info.append(tmp);
    }
}

void CNodeCounterLog::getJsonInfo(std::string& _info,float& _size)
{
    unsigned int totoal = 0;
    int num = 0;
    std::map<std::string,rapidjson::Document *>* jsonMap = GUIReader::shareReader()->getJsonCache();
    if (jsonMap)
    {
        for (std::map<std::string,rapidjson::Document *>::iterator iter = jsonMap->begin(); iter != jsonMap->end(); ++iter)
        {
            totoal += iter->second->sizeTmp;
            num += 1;
        }
    }

    if (totoal > 0)
    {
        char tmp[128] = { 0 };
        float totalMb = (float)(totoal / 1024) / 1024.f;
        _size += totalMb;
        sprintf(tmp,num,"JsonCache");
        _info.append(tmp);
    }
}

coco2dx对象统计及内存查漏的更多相关文章

  1. Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转换公式)

    这篇文章主要介绍了Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转换公式),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. HTML5 WebSocket实现点对点聊天的示例代码

    这篇文章主要介绍了HTML5 WebSocket实现点对点聊天的示例代码的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

  4. ios – 在Swift中将输入字段字符串转换为Int

    所以我非常擅长制作APP广告Swift,我试图在文本字段中做一些非常简单的输入,取值,然后将它们用作Int进行某些计算.但是’vardistance’有些东西不正确它是导致错误的最后一行代码.它说致命错误:无法解开Optional.None解决方法在你的例子中,距离是一个Int?否则称为可选的Int..toInt()返回Int?因为从String到Int的转换可能失败.请参阅以下示例:

  5. 如何在iOS中检测文本(字符串)语言?

    例如,给定以下字符串:我想检测每个声明的字符串中使用的语言.让我们假设已实现函数的签名是:如果没有检测到语言,则返回可选字符串.因此,适当的结果将是:有一个简单的方法来实现它吗?

  6. ios – 如何使用Objective C类中的多个参数调用Swift函数?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  7. 使用最新的Flurry SDK和ios4重新启动应用程序

    我真的希望这对我来说只是一个愚蠢的错误.我很高兴使用Flurry但这样的事情会导致我的应用被拒绝.解决方法我写了关于这个的Flurry,他们很快回到我身边,他们会调查这个.大约一个星期后,他们回信并表示他们已经在v2.6中修复了它,现在可用了.我似乎无法重现这个问题.不是说我很棒或者什么,但我还是单枪匹马地解决了这个问题.

  8. xamarin – 崩溃在AccountStore.Create().保存(e.Account,“);

    在Xamarin.Forms示例TodoAwsAuth中https://developer.xamarin.com/guides/xamarin-forms/web-services/authentication/oauth/成功登录后,在aOnAuthenticationCompleted事件中,应用程序在尝试保存到Xamarin.Auth时崩溃错误说不能对钥匙串说期待着寻求帮助.解决方法看看你

  9. ios – 将视频分享到Facebook

    我正在编写一个简单的测试应用程序,用于将视频从iOS上传到Facebook.由于FacebookSDK的所有文档都在Objective-C中,因此我发现很难在线找到有关如何使用Swift执行此操作的示例/教程.到目前为止我有这个在我的UI上放置一个共享按钮,但它看起来已禁用,从我读到的这是因为没有内容设置,但我看不出这是怎么可能的.我的getVideoURL()函数返回一个NSURL,它肯定包含视

  10. xcode – 错误“线程1:断点2.1”

    我正在研究RESTAPI管理器.这是一个错误,我无法解决它.我得到的错误在下面突出显示.当我打电话给这个班级获取资源时:我评论的线打印:Thread1:breakpoint2.1我需要修复错误的建议.任何建议都非常感谢解决方法您可能在不注意的情况下意外设置了断点.单击并拖动代表断路器外部断点的蓝色刻度线以将其擦除.

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部