• 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 = sceneName; 
    
        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")
        end
    end
    
    function LoadingController:run(  )
        self.curScene = SceneM.getRunningScene();
        self.nextScene = nil;
    
        -- 1.ui层
        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
                    return;
                end
                local lion = ObjectFactory.newArmature(self.animName);
                lion:setPosition(ccp(Screen.cx,Screen.cy));
                lion:addParent(self.uiLayer);
                lion:getComponent("Animation"):play("run", WrapMode.Loop);
            end)
        end
    
        -- 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);
        end
    
        -- 7. 重新初始化管理类
        SceneM.uiLayers = {};
    
        -- 8.延迟清除当前资源,并且加载下一个场景资源 
        performWithDelay(function (  )
            self:cleanup();
            self:startLoading(self.config);
        end, 0.01)
    
        -- 9. 回收lua内存
        collectgarbage("collect")
    end
    
    function LoadingController:startLoading(theloadingconfig)
        if theloadingconfig == nil then
            self.isLoaded = true;
                -- 切换场景
                self.nextScene = ObjectFactory.newScene(self.curSceneName);
                SceneM.curScene = self.nextScene;
                self.nextScene:addComponent(self.curSceneName,SceneM.getSceneController(self.curSceneName));
                
                -- 关闭加载层
                SceneM.destroy(self.uiLayer);
    
                -- 开启触摸消息
                CCDirector:sharedDirector():getTouchDispatcher():setDispatchEvents(true);
    
                -- 记录配置文件路径
                SceneM.lastSceneName = self.curSceneName;
    
                -- 切换到新场景
                SceneM.replaceScene(self.nextScene, "crossfade", 0.2, Screen.COLOR_WHITE);
            return;
        end
        print ("start loading")
        self.loadingConfig = theloadingconfig;
        local resTypes = {"sounds","textures","atlas","animations","effects"}
        local curIndex = 1;
        -- 1.开始当前场景加载资源
        self.curLoadingNum = 0
        local totalNum  = 0
        local function loopRes( t , resType)
            if self.curLoadingNum > self.totalLoadingNum then
                return;
            end
            if t == nil then
                curIndex = curIndex + 1;
                local resType = resTypes[curIndex];
                print("加载类型:",resType);
                print("加载:",theloadingconfig[resType]);
                loopRes(theloadingconfig[resType], resType);
                return;
            end
            local keys = table.keys(t);
            totalNum = totalNum + #keys;
            local tempIndex = 1;
            local function loadRes(  )
                self.curLoadingNum = self.curLoadingNum + 1;
                if self.curLoadingNum > self.totalLoadingNum then
                    return;
                end
                --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);
                    return;
                end
                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())
                    end
    
                    if resType == TEXTURETYPE then
                        -- 2.异步纹理加载
                        --print("加载纹理:", value);
                        CCTextureCache:sharedTextureCache():addImageAsync(value, function ( )
                            self:CheckedResLoaded(); -- 检测下是否加载完毕
                            performWithDelay(function (  )
                                loadRes();
                            end, CCDirector:sharedDirector():deltaTime())
                        end);
                    end
    
                    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())
                        end);
                    end
    
                    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())
                        end)
                    end
                end
            end
    
            loadRes();
        end
        -- 计算加载的资源总数
        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);
        end
        self.totalLoadingNum = size(theloadingconfig);
    
        -- 加载场景资源
        local resType = resTypes[curIndex];
        print("加载类型:",resType);
        print("加载:",theloadingconfig[resType]);
        loopRes(theloadingconfig[resType], resType);
    end
    
    -- 检测是否加载完毕
    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));
        end
    
        -- 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.nextScene;
                self.nextScene:addComponent(self.curSceneName,SceneM.getSceneController(self.curSceneName));
                
                -- 关闭加载层
                SceneM.destroy(self.uiLayer);
    
                -- 开启触摸消息
                CCDirector:sharedDirector():getTouchDispatcher():setDispatchEvents(true);
    
                -- 记录配置文件路径
                SceneM.lastSceneName = self.curSceneName;
    
                -- 切换到新场景
                SceneM.replaceScene(self.nextScene, "crossfade", 0.2, Screen.COLOR_WHITE);
            end
            -- 等待一帧 不然最后一次无法绘制
            performWithDelay(onComplete, CCDirector:sharedDirector():deltaTime() * 2);
        end
    end
    
    -- 清理资源
    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
                    return;
                end
                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);
                        end
    
                        if resType == TEXTURETYPE then
                            -- 2.删除纹理
                            CCTextureCache:sharedTextureCache():removeTextureForKey(value);
                        end
    
                        if resType == ATLASTYPE then
                            -- 3.删除plist纹理
                            CCSpriteFrameCache:sharedSpriteFrameCache():removeSpriteFramesFromFile(value);
                            value = string.gsub(value, ".plist", ".png");
                            CCTextureCache:sharedTextureCache():removeTextureForKey(value);
                        end
    
                        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();
                        end
                    end
                end 
            end
            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);    --删除动画资源
            end
            ResM.init();
            
            CCTextureCache:sharedTextureCache():dumpCachedTextureInfo();
        end
        
        -- CCSpriteFrameCache:purgeSharedSpriteFrameCache();
        -- CCTextureCache:sharedTextureCache():removeAllTextures();
        -- CCArmatureDataManager:purge();
    end
    
    return LoadingController;
  • 相关阅读:
    miniui mini-combobox的使用
    xsd文件记录
    Hibernate 一次查询分多次返回 避免内存溢出
    卡口扩展信息
    删除 maven仓库,更新失败的jar包命令
    杀windows进程
    layer 遮罩层等待
    math() 对象
    JavaScript 字符串方法
    JavaScript 数组遍历方法;
  • 原文地址:https://www.cnblogs.com/newlist/p/3647660.html
Copyright © 2020-2023  润新知