3.2 removeArmatureFileInfo 上古卷轴5内存释放mod不完全 怎么破

LoadingController - 一枚程序 - 博客园
--local MainSceneConfig = require "res.scripts.configs.MainSceneConfig" -- 暂时添加一个临时配置文件
--require "res.scripts.scenes.MainScene"
-- 加载事件
OnLoadingStart
= "OnLoadingStart";
OnLoadingProcess
= "OnLoadingProcess";
OnLoadingEnd
= "OnLoadingEnd";
-- 加载类型
SOUNDTYPE = "sounds";
TEXTURETYPE = "textures";
ATLASTYPE = "atlas";
ANIMATIONTYPE = "animations";
EFFECTTYPE
= "effects";
-- 加载控制逻辑
local LoadingController = class("LoadingController", Behavior);
function LoadingController:ctor(sceneName)
LoadingController.super.ctor(self);
-- 定义成员变量
self.progress = 0; -- 加载进度
self.totalLoadingNum = 0; --加载总数数量
self.curLoadingNum = 0;
-- 当前加载数量
self.loadingConfig = ""; -- 资源配置文件
self.log = nil;
-- 加载界面log
self.btmLabel = nil; --进度显示标签
self.uiLayout = nil; -- 加载界面布局
self.uiLayer = nil; -- 加载界面层
self.curScene = nil; -- 上一个场景
self.nextScene = nil; -- 下一个场景
self.config = res[sceneName];-- 配置文件
self.curSceneName = sceneN
self.isLoaded = false;
-- 随机抽取一只怪物
local animKeys = table.keys(res.animations);
if #animKeys & 0 then
local index = math.random(1, #animKeys);
self.animName = tostring(animKeys[index]);
self.loadingxml = res.animations[self.animName];
self.loadingplist = string.gsub(self.loadingxml, ".xml", ".plist")
self.loadingpng = string.gsub (self.loadingxml, ".xml", ".png")
function LoadingController:run(
self.curScene = SceneM.getRunningScene();
self.nextScene = nil;
self.uiLayer = ObjectFactory.newLayer();
self.uiLayer:setColor(ccc3(0, 0, 0));
-- 2.创建构成加载场景的元素
self.btmLabel = ObjectFactory.newBMFontLabel({text = "Loading 0%", font = res.fonts.UIFont,})
self.btmLabel:setPosition(ccp(Screen.cx, Screen.cy - 80));
self.uiLayer:addChild(self.btmLabel);
if self.loadingxml then
CCArmatureDataManager:sharedArmatureDataManager():addArmatureFileInfoAsync(self.loadingpng, self.loadingplist, self.loadingxml, function (
if self.isLoaded then
local lion = ObjectFactory.newArmature(self.animName);
lion:setPosition(ccp(Screen.cx,Screen.cy));
lion:addParent(self.uiLayer);
lion:getComponent("Animation"):play("run", WrapMode.Loop);
-- 3. 添加到场景
SceneM.dontDestroy(self.uiLayer);
-- 4. 关掉触摸消息
CCDirector:sharedDirector():getTouchDispatcher():setDispatchEvents(false);
-- 5. 关掉动作管理
CCDirector:sharedDirector():getActionManager():removeAllActions();
-- 6. 退出当前场景
if self.curScene then
self.curScene:setVisible(false);
-- 7. 重新初始化管理类
SceneM.uiLayers = {};
-- 8.延迟清除当前资源,并且加载下一个场景资源
performWithDelay(function (
self:cleanup();
self:startLoading(self.config);
end, 0.01)
-- 9. 回收lua内存
collectgarbage("collect")
function LoadingController:startLoading(theloadingconfig)
if theloadingconfig == nil then
self.isLoaded = true;
-- 切换场景
self.nextScene = ObjectFactory.newScene(self.curSceneName);
SceneM.curScene = self.nextS
self.nextScene:addComponent(self.curSceneName,SceneM.getSceneController(self.curSceneName));
-- 关闭加载层
SceneM.destroy(self.uiLayer);
-- 开启触摸消息
CCDirector:sharedDirector():getTouchDispatcher():setDispatchEvents(true);
-- 记录配置文件路径
SceneM.lastSceneName = self.curSceneN
-- 切换到新场景
SceneM.replaceScene(self.nextScene, "crossfade", 0.2, Screen.COLOR_WHITE);
print ("start loading")
self.loadingConfig =
local resTypes = {"sounds","textures","atlas","animations","effects"}
local curIndex = 1;
-- 1.开始当前场景加载资源
self.curLoadingNum = 0
local totalNum
local function loopRes( t , resType)
if self.curLoadingNum & self.totalLoadingNum then
if t == nil then
curIndex = curIndex + 1;
local resType = resTypes[curIndex];
print("加载类型:",resType);
print("加载:",theloadingconfig[resType]);
loopRes(theloadingconfig[resType], resType);
local keys = table.keys(t);
totalNum = totalNum + #
local tempIndex = 1;
local function loadRes(
self.curLoadingNum = self.curLoadingNum + 1;
if self.curLoadingNum & self.totalLoadingNum then
--print("====",self.curLoadingNum , totalNum)
if self.curLoadingNum & totalNum then
tempIndex = 1;
curIndex = curIndex + 1;
local resType = resTypes[curIndex];
self.curLoadingNum = self.curLoadingNum - 1;
loopRes(theloadingconfig[resType], resType);
local key = keys[tempIndex];
local value = t[key];
tempIndex = tempIndex + 1;
if (tolua.type(value) == "table") then
loopRes( value );
elseif (tolua.type(value) == "string") then
if resType == SOUNDTYPE then
-- 1.异步声音加载
--print("加载声音:", value);
Audio.preloadEffect(value);
performWithDelay(function (
loadRes();
end, CCDirector:sharedDirector():deltaTime())
if resType == TEXTURETYPE then
-- 2.异步纹理加载
--print("加载纹理:", value);
CCTextureCache:sharedTextureCache():addImageAsync(value, function ( )
self:CheckedResLoaded(); -- 检测下是否加载完毕
performWithDelay(function (
loadRes();
end, CCDirector:sharedDirector():deltaTime())
if resType == ATLASTYPE then
-- 2.异步纹理加载
local png = string.gsub(value, ".plist", ".png")
--print("加载图集:",png);
CCTextureCache:sharedTextureCache():addImageAsync(png, function ( )
-- 添加plist 到 CCSpriteFrameCache
CCSpriteFrameCache:sharedSpriteFrameCache():addSpriteFramesWithFile(value)
self:CheckedResLoaded(); -- 检测下是否加载完毕
performWithDelay(function (
loadRes();
end, CCDirector:sharedDirector():deltaTime())
if resType == ANIMATIONTYPE or resType == EFFECTTYPE then
--3.异步动画加载
local plist = string.gsub(value, ".xml", ".plist")
local png = string.gsub (value, ".xml", ".png")
--print("加载骨骼动画:",png, plist, value);
CCArmatureDataManager:sharedArmatureDataManager():addArmatureFileInfoAsync(png, plist, value, function (
self:CheckedResLoaded(); -- 检测下是否加载完毕
performWithDelay(function (
loadRes();
end, CCDirector:sharedDirector():deltaTime())
loadRes();
-- 计算加载的资源总数
local function size( config )
return #table.keys(config.textures)
+ #table.keys(config.sounds)
+ #table.keys(config.fonts)
+ #table.keys(config.animations)
+ #table.keys(config.atlas)
+ #table.keys(config.effects);
self.totalLoadingNum = size(theloadingconfig);
-- 加载场景资源
local resType = resTypes[curIndex];
print("加载类型:",resType);
print("加载:",theloadingconfig[resType]);
loopRes(theloadingconfig[resType], resType);
-- 检测是否加载完毕
function LoadingController:CheckedResLoaded(
if self.curLoadingNum &= self.totalLoadingNum then
-- 1.更新当前进度
local percent = math.modf(self.curLoadingNum * 100 / self.totalLoadingNum)
self.btmLabel:setString(string.format("Loading %s%%", percent));
-- 2.检测下是否加载完毕
if (self.curLoadingNum == self.totalLoadingNum) then
local function onComplete(event)
print ("loading res finished!")
self.isLoaded = true;
-- 切换场景
self.nextScene = ObjectFactory.newScene(self.curSceneName);
SceneM.curScene = self.nextS
self.nextScene:addComponent(self.curSceneName,SceneM.getSceneController(self.curSceneName));
-- 关闭加载层
SceneM.destroy(self.uiLayer);
-- 开启触摸消息
CCDirector:sharedDirector():getTouchDispatcher():setDispatchEvents(true);
-- 记录配置文件路径
SceneM.lastSceneName = self.curSceneN
-- 切换到新场景
SceneM.replaceScene(self.nextScene, "crossfade", 0.2, Screen.COLOR_WHITE);
-- 等待一帧 不然最后一次无法绘制
performWithDelay(onComplete, CCDirector:sharedDirector():deltaTime() * 2);
-- 清理资源
function LoadingController:cleanup(
CCDirector:sharedDirector():getActionManager():removeAllActions();
-- 获得上一个场景配置,根据配置删除
if SceneM.lastSceneName then
local lastConfig = res[SceneM.lastSceneName];
local function removeRes( t , resType)
if t == nil or type(t) ~= "table" then
for key, value in pairs(t) do
if (tolua.type(value) == "table") then
loopRes( value );
elseif (tolua.type(value) == "string") then
if resType == SOUNDTYPE then
-- 1.删除声音
Audio.unloadSound(value);
if resType == TEXTURETYPE then
-- 2.删除纹理
CCTextureCache:sharedTextureCache():removeTextureForKey(value);
if resType == ATLASTYPE then
-- 3.删除plist纹理
CCSpriteFrameCache:sharedSpriteFrameCache():removeSpriteFramesFromFile(value);
value = string.gsub(value, ".plist", ".png");
CCTextureCache:sharedTextureCache():removeTextureForKey(value);
if resType == ANIMATIONTYPE then
-- 4.删除动画
print("删除骨骼动画资源:",value);
value = string.gsub(value, ".xml", ".png");
CCTextureCache:sharedTextureCache():removeTextureForKey(value);
value = string.gsub(value, ".png", ".plist");
CCSpriteFrameCache:sharedSpriteFrameCache():removeSpriteFramesFromFile(value);
--CCArmatureDataManager:purge();
removeRes(lastConfig.sounds, SOUNDTYPE);
--删除声音资源
removeRes(lastConfig.textures, TEXTURETYPE);
--删除纹理资源
removeRes(lastConfig.atlas, ATLASTYPE);
--删除图集资源
removeRes(lastConfig.animations, ANIMATIONTYPE);
--删除动画资源
removeRes(lastConfig.effects, ANIMATIONTYPE);
--删除动画资源
-- 移除临时动态公共资源
if ResM.tempPathCache then
removeRes(ResM.tempPathCache.sounds, SOUNDTYPE);
--删除声音资源
removeRes(ResM.tempPathCache.textures, TEXTURETYPE);
--删除纹理资源
removeRes(ResM.tempPathCache.atlas, ATLASTYPE);
--删除图集资源
removeRes(ResM.tempPathCache.animations, ANIMATIONTYPE);
--删除动画资源
ResM.init();
CCTextureCache:sharedTextureCache():dumpCachedTextureInfo();
-- CCSpriteFrameCache:purgeSharedSpriteFrameCache();
-- CCTextureCache:sharedTextureCache():removeAllTextures();
-- CCArmatureDataManager:purge();
return LoadingC主题 : removeArmatureFileInfo 有用么
级别: 新手上路
可可豆: 208 CB
威望: 209 点
在线时间: 149(时)
发自: Web Page
来源于&&分类
removeArmatureFileInfo 有用么&&&
我用的3.1.1版本&发现怎么使用都无效,内存没有变小&经常切换场景不停地变大&&求解
级别: 论坛版主
UID: 387086
发帖: 1493
可可豆: 1897 CB
威望: 1886 点
在线时间: 1039(时)
发自: Web Page
remove的只有Armature的动画数据。&还需要清理图片帧,图片缓存(记得按我说的顺序来)
关注本帖(如果有新回复会站内信通知您)
论坛技术问题应该发布到? 正确答案:CocoaChina问答
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版cocos2d-x 3.2 lua 怎么导入cocostudio动画_百度知道
cocos2d-x 3.2 lua 怎么导入cocostudio动画
提问者采纳
function MyGameScene:createAnimation()
ccs.ArmatureDataManager:getInstance():addArmatureFileInfo(&img/role0.png&,&role0.plist&,&img/role.ExportJson&)
local animation = ccs.Armature:create(&role&)
animation:setPosition(self.windowsSize.width/2,self.windowsSize.height/2)
animation:getAnimation():play(&attack&)
return animationendlocal animation = ccs.Armature:cr俯耿碘际鄢宦碉为冬力eate(&role&)
其他类似问题
为您推荐:
cocos2d的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁主题 : CCArmature动画释放
级别: 新手上路
可可豆: 134 CB
威望: 134 点
在线时间: 54(时)
发自: Web Page
来源于&&分类
CCArmature动画释放&&&
释放摸一个动画,按照fancong 童鞋的方法!armature-&removeFromParent(); armature-&release()&&&& CCArmatureDataManager::sharedArmatureDataManager()-&removeArmatureFileInfo(&xxxx.xml&) ; &&&&CCSpriteFrameCache::sharedSpriteFrameCache()-&removeSpriteFramesFromFile(&xxx.plist&); &&&& CCTextureCache::sharedTextureCache()-&removeTextureForKey(&xxx.png&); 完全没有感觉出内存释放啊!2.2.1版本,新的版本呢?
级别: 新手上路
可可豆: 11 CB
威望: 1 点
在线时间: 23(时)
发自: Web Page
同问啊 移除CCArmature的缓存到底是怎么个流程 是需要每一个动画对象都依次removeArmatureFileInfo()&&removeSpriteFramesFromFile() removeTextureForKey() 然后再purge() ? 异步加载的资源也能这样移除掉吗?
级别: 新手上路
可可豆: 53 CB
威望: 63 点
在线时间: 8(时)
发自: Web Page
同问,Texture没有释放,如果使用removeTextureForKey,感觉有什么地方没弄干净
关注本帖(如果有新回复会站内信通知您)
iPhone5的分辨率? 正确答案:
发帖、回帖都会得到可观的积分奖励。
按"Ctrl+Enter"直接提交
关注CocoaChina
关注微信 每日推荐
扫一扫 浏览移动版我忘了我这篇测试的主要目的是干啥了...。
就算往项目上靠靠吧,我项目里面要用到CCArmature这个,给这个实现单指拖拽,双指缩放功能。
新建类MyArmature,和MySprite类似,如下:
MyArmature.h
MyArmature.h
TouchesTest
Created by HanHongmin on 13-12-29.
9 #ifndef __TouchesTest__MyArmature__
10 #define __TouchesTest__MyArmature__
12 #include "cocos2d.h"
13 #include "cocos-ext.h"
14 using namespace cocos2d;
15 using namespace cocos2d::
16 class MyArmature:public CCArmature,public CCTouchDelegate{
17 public:
static MyArmature* create(const char* name,int nPriority);
virtual void onEnter();
virtual void onExit();
void draw();//for Test
// optional
virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);
virtual void ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent);
void setPriority(int nPriority);
int getPriority();
31 protected:
35 #endif /* defined(__TouchesTest__MyArmature__) */
MyArmature.cpp
MyArmature.cpp
TouchesTest
Created by HanHongmin on 13-12-29.
9 #include "MyArmature.h"
11 MyArmature* MyArmature::create(const char *name,int nPriority){
MyArmature *armature = new MyArmature();
if (armature && armature-&init(name))
armature-&setPriority(nPriority);
armature-&autorelease();
CC_SAFE_DELETE(armature);
return NULL;
22 void MyArmature::setPriority(int nPriority){
_nPriority = nP
25 int MyArmature::getPriority(){
return _nP
29 void MyArmature::onEnter(){
CCDirector::sharedDirector()-&getTouchDispatcher()-&addStandardDelegate(this, _nPriority);//多点触控
CCArmature::onEnter();
33 void MyArmature::onExit(){
CCDirector::sharedDirector()-&getTouchDispatcher()-&removeDelegate(this);
CCArmature::onExit();
38 void MyArmature::draw(){
CCArmature::draw();
CCRect rect = this-&boundingBox();
ccDrawColor4B(255, 0, 0, 255);
ccDrawRect(convertToNodeSpace(rect.origin), convertToNodeSpace(ccp(rect.getMaxX(), rect.getMaxY())));
47 // optional
48 void MyArmature::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){
//CCLog("ccTouchesBegan touches point count:%i",pTouches-&count());
CCLog("origin:%f,%f",this-&boundingBox().origin.x,this-&boundingBox().origin.y);
52 void MyArmature::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent){
//CCLog("ccTouchesMoved touches point count:%i",pTouches-&count());
CCDictionary* touchesDic = CCDictionary::create();
CCSetIterator iter = pTouches-&begin();
CCRect rect = this-&boundingBox();
CCLog("rect:%f,%f",rect.size.width,rect.size.height);
for (; iter != pTouches-&end(); iter++){
CCTouch* pTouch = (CCTouch*)(*iter);
if(rect.containsPoint(pTouch-&getLocation())){
touchesDic-&setObject(pTouch, CCString::createWithFormat("%d",pTouch-&getID())-&getCString());
CCArray* keys = touchesDic-&allKeys();
//两个手指
if (touchesDic-&count() &= 2){
//CCLog("****ccTouchesMoved*");
CCArray* keys = touchesDic-&allKeys();
CCTouch *touch1 = (CCTouch*)touchesDic-&objectForKey(((CCString*)keys-&objectAtIndex(0))-&getCString());
CCTouch *touch2 = (CCTouch*)touchesDic-&objectForKey(((CCString*)keys-&objectAtIndex(1))-&getCString());
CCPoint p1End = touch1-&getLocation();
CCPoint p2End = touch2-&getLocation();
CCPoint p1Start = touch1-&getPreviousLocation();
CCPoint p2Start = touch2-&getPreviousLocation();
float startDistance = ccpDistance(p1Start,p2Start);
float endDistance = ccpDistance(p1End,p2End);
//CCLog("startDistance:%f,endDistance:%f",startDistance,endDistance);
float scale = this-&getScale()*(endDistance/startDistance);
CCLog("scale %f",scale);
if(scale&1.0f){
scale = 1.0f;
}else if(scale&3.0f){
scale = 3.0f;
this-&setScale(scale);
pTouches-&removeObject(touch1);
pTouches-&removeObject(touch2);
}else if(touchesDic-&count() ==1){//单点
CCTouch *pTouch = (CCTouch*)touchesDic-&objectForKey(((CCString*)keys-&objectAtIndex(0))-&getCString());
CCPoint start = pTouch-&getPreviousLocation();
CCPoint end = pTouch-&getLocation();
//计算位移,直接使用point充当position的话,会有偏差,比如点住图片的一角进行拖动,setPosition的时候是依据AnchorPoint进行设置的
CCPoint sub = ccpSub(end, start);
CCPoint newPosition = ccpAdd(this-&getPosition(),sub);
this-&setPosition(newPosition);
pTouches-&removeObject(pTouch);
104 void MyArmature::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent){
//CCLog("****ccTouchesEnded*");
107 void MyArmature::ccTouchesCancelled(CCSet *pTouches, CCEvent *pEvent){
//CCLog("****ccTouchesCancelled*");
draw方法是测试用的,因为在测试时发现boundingBox的位置不准,所以把它描绘出来看看。后面再说这个吧。
HelloWorld的init方法
bool HelloWorld::init()
if ( !CCLayer::init() )
return false;
CCArmatureDataManager::sharedArmatureDataManager()-&addArmatureFileInfo("run.png", "run.plist", "run.xml");//加载动画资源
MyArmature* armature = MyArmature::create("run",1);
armature-&setPosition(VisibleRect::center());
armature-&setScale(2.0f);
this-&addChild(armature,0);
MySprite* pSprite2 = MySprite::create("Icon-114.png",2);//优先级数值越小越优先响应
pSprite2-&setPosition(VisibleRect::center());
pSprite2-&setScale(2.0f);
this-&addChild(pSprite2, 1);
MySprite* pSprite = MySprite::create("HelloWorld.png",0);
pSprite-&setPosition(VisibleRect::center());
this-&addChild(pSprite, 1);
return true;
CCArmature是 cocos2dx 扩展包里的东西,别忘了下面两行
#include "cocos-ext.h"
using namespace cocos2d::
然后就应该可以看看效果了。
是不是发现boundingBox不是想得那么回事?因为Armature中有子Armature的关系吧,我猜的。
在论坛发帖问了,还没得到回复,自己尝试hack了一下源码,没想到啊,还好使了。。。
修改CCArmature::boundingBox如下:
CCRect CCArmature::boundingBox()
float minx, miny, maxx, maxy = 0;
bool first = true;
CCRect boundingBox = CCRectMake(0, 0, 0, 0);
CCObject *object = NULL;
CCARRAY_FOREACH(m_pChildren, object)
if (CCBone *bone = dynamic_cast&CCBone *&(object))
CCArmature* child = bone-&getChildArmature();
//CCRect r = bone-&getDisplayManager()-&getBoundingBox();//hack by HanHongmin
if(child!=NULL){
r = child-&boundingBox();
r = bone-&getDisplayManager()-&getBoundingBox();
//hack finish
minx = r.getMinX();
miny = r.getMinY();
maxx = r.getMaxX();
maxy = r.getMaxY();
first = false;
minx = r.getMinX() & boundingBox.getMinX() ? r.getMinX() : boundingBox.getMinX();
miny = r.getMinY() & boundingBox.getMinY() ? r.getMinY() : boundingBox.getMinY();
maxx = r.getMaxX() & boundingBox.getMaxX() ? r.getMaxX() : boundingBox.getMaxX();
maxy = r.getMaxY() & boundingBox.getMaxY() ? r.getMaxY() : boundingBox.getMaxY();
boundingBox.setRect(minx, miny, maxx - minx, maxy - miny);
return CCRectApplyAffineTransform(boundingBox, nodeToParentTransform());
运行之,看看吧。
改的对不对我不知道哈,反正跟我要的效果差不多了。
等着看论坛帖子下文吧:
恩,现在两个自定义类了,可能大家早就发现了,能够提取出来公共代码。
虽然复制粘贴不麻烦,但是我想,大多数程序员都应该有代码洁癖吧。。。
各位自行搞一搞吧,我尝试了一下不会弄T_T,谁弄好了告诉我一声。
还有一点,如果涉及到x轴Y轴单向翻转的话,缩放哪里要注意,X,Y要分开。
setScale方法会把scaleX和scaleY都设置了,相当于调用了setScaleX和setScaleY。
阅读(...) 评论()

我要回帖

更多关于 内存释放专家 的文章

 

随机推荐