CocosCreator大廳+子游戲(v1.10.2)

基于熱更新的基礎(chǔ)上可缚,將子游戲構(gòu)建生成的main.js文件一并移入src目錄霎迫,在運(yùn)行子游戲的時(shí)候,我們只需要require main.js這個(gè)文件即可帘靡。

大廳跳到子游戲

首先是大廳封裝好的子游戲管理類知给,包括子游戲下載、更新描姚、進(jìn)入

export  class SubgameManager  {

    private static serverUrl;
    private static storagePath:[] = [];


    private static assertsMg;
    private static jsbCallback;

    private static subgameUpdateCallback;
    private static progressCallback;
    private static finishCallback;

    public static init(serverUrl:string){
        this.serverUrl = serverUrl;
    }

    public static isSubgameDownload(name:string):boolean{

        let file = (jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'ALLGame/' + name + '/project.manifest';
        if (jsb.fileUtils.isFileExist(file)) {
            return true;
        } else {
            return false;
        }
    }

    public static isNeedUpdateSubgame(name:string,subgameUpdateCallback?:Function){
        this.prepareJsb(name);
        this.subgameUpdateCallback = subgameUpdateCallback;
        this.jsbCallback =  new jsb.EventListenerAssetsManager(this.assertsMg, this.needUpdateCallback.bind(this));
        cc.eventManager.addListener(this.jsbCallback, 1);
        this.assertsMg.checkUpdate();
    }

    private static needUpdateCallback(event){
        let self = this;
        switch (event.getEventCode()) {
            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
                cc.log('子游戲已經(jīng)是最新的涩赢,不需要更新');
                self.subgameUpdateCallback && self.subgameUpdateCallback(false);
                break;

            case jsb.EventAssetsManager.NEW_VERSION_FOUND:
                cc.log('子游戲需要更新');
                self.subgameUpdateCallback && self.subgameUpdateCallback(true);
                break;

            // 檢查是否更新出錯(cuò)
            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
            case jsb.EventAssetsManager.ERROR_UPDATING:
            case jsb.EventAssetsManager.UPDATE_FAILED:
                //self._downloadCallback();
                break;
        }
    }

    public static downloadSubgame(name:string,progressCallback?:Function,finishCallback?:Function){
        this.prepareJsb(name);
        this.progressCallback = progressCallback;
        this.finishCallback = finishCallback;
        this.jsbCallback =  new jsb.EventListenerAssetsManager(this.assertsMg, this.downloadCallback.bind(this));
        cc.eventManager.addListener(this.jsbCallback, 1);
        this.assertsMg.update();
    }

    private static downloadCallback(event) {
        var failed = false;
        let self = this;
        switch (event.getEventCode()) {
            case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
                /*0 本地沒有配置文件*/
                cc.log('updateCb本地沒有配置文件');
                failed = true;
                break;

            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
                /*1下載配置文件錯(cuò)誤*/
                cc.log('updateCb下載配置文件錯(cuò)誤');
                failed = true;
                break;

            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
                /*2 解析文件錯(cuò)誤*/
                cc.log('updateCb解析文件錯(cuò)誤');
                failed = true;
                break;

            case jsb.EventAssetsManager.NEW_VERSION_FOUND:
                /*3發(fā)現(xiàn)新的更新*/
                cc.log('updateCb發(fā)現(xiàn)新的更新');
              
                break;

            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
                /*4 已經(jīng)是最新的*/
                cc.log('updateCb已經(jīng)是最新的');
                failed = true;
                break;

            case jsb.EventAssetsManager.UPDATE_PROGRESSION:
                /*5 最新進(jìn)展 */
                cc.log("event.getPercentByFile()"+event.getPercentByFile());
                self.progressCallback && self.progressCallback(event.getPercentByFile());
                break;


            case jsb.EventAssetsManager.ASSET_UPDATED:
                /*6需要更新*/
                break;

            case jsb.EventAssetsManager.ERROR_UPDATING:
                /*7更新錯(cuò)誤*/
                cc.log('updateCb更新錯(cuò)誤');
                break;

            case jsb.EventAssetsManager.UPDATE_FINISHED:
                /*8更新完成*/
                cc.log("UPDATE_FINISHED");
                self.finishCallback && self.finishCallback(true);
                break;

            case jsb.EventAssetsManager.UPDATE_FAILED:
                /*9更新失敗*/
                cc.log('UPDATE_FAILED');
                self.assertsMg.downloadFailedAssets();
                
                break;

            case jsb.EventAssetsManager.ERROR_DECOMPRESS:
                /*10解壓失敗*/
                cc.log('解壓失敗');
                break;
        }

        if (failed) {
            cc.eventManager.removeListener(self.jsbCallback);
            self.jsbCallback = null;
            self.finishCallback && self.finishCallback(false);
        }
    }

    public static enterSubgame(name) {
        if (!this.storagePath[name]) {
            this.downloadSubgame(name);
            return;
        }

        window.require(this.storagePath[name] + '/src/main.js');
    }


    private static prepareJsb(name:string){
        this.storagePath[name] = ((jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/') + 'ALLGame/' + name);
      
        var UIRLFILE = this.serverUrl +"/"+ name;
    
        var customManifestStr = JSON.stringify({
            'packageUrl': UIRLFILE,
            'remoteManifestUrl': UIRLFILE + '/project.manifest',
            'remoteVersionUrl': UIRLFILE + '/version.manifest',
            'version': '0.0.1',
            'assets': {},
            'searchPaths': []
        });

        this.assertsMg = new jsb.AssetsManager('', this.storagePath[name], this.versionCompare);

        if (!cc.sys.ENABLE_GC_FOR_NATIVE_OBJECTS) {
            this.assertsMg.retain();
        }

        this.assertsMg.setVerifyCallback(function(path, asset) {
            var compressed = asset.compressed;
            if (compressed) {
                return true;
            } else {
                return true;
            }
        });

        if (cc.sys.os === cc.sys.OS_ANDROID) {
            this.assertsMg.setMaxConcurrentTask(2);
        }

        if (this.assertsMg.getState() === jsb.AssetsManager.State.UNINITED) {
            var manifest = new jsb.Manifest(customManifestStr, this.storagePath[name]);
            this.assertsMg.loadLocalManifest(manifest, this.storagePath[name]);
        }

    }

    private static versionCompare(versionA, versionB):number{

        var vA = versionA.split('.');
            var vB = versionB.split('.');
            for (var i = 0; i < vA.length; ++i) {
                var a = parseInt(vA[i]);
                var b = parseInt(vB[i] || 0);
                if (a === b) {
                    continue;
                } else {
                    return a - b;
                }
            }
            if (vB.length > vA.length) {
                return -1;
            } else {
                return 0;
            }
    }
 
}

接著看使用這個(gè)類:

import { SubgameManager } from "./SubgameManager";

const {ccclass, property} = cc._decorator;

@ccclass
export default class Subgame extends cc.Component {

    @property(cc.Label)
    label: cc.Label = null;

    private subgame = "Niuniu"

    onLoad(){

        SubgameManager.init("http://192.168.0.136:8000");

        if(SubgameManager.isSubgameDownload(this.subgame)){

            SubgameManager.isNeedUpdateSubgame(this.subgame,(isSuccess)=>{
                this.label.string = isSuccess ? "子游戲需要更新" : "子游戲不需要更新";
            });

        }else{
            this.label.string = "子游戲未下載";
        }

    }

    click(){
        SubgameManager.downloadSubgame(this.subgame,(progress)=>{
            if (isNaN(progress)) {
                progress = 0;
            }
            this.label.string = "資源下載中   " + ~~(progress * 100) + "%";
        },(success)=>{
            if (success) {
                SubgameManager.enterSubgame(this.subgame);
            } 
        })
    }
}

準(zhǔn)備好之后,開始準(zhǔn)備小游戲轩勘,首先將小游戲構(gòu)建下筒扒,模板是default,如果使用腳本加密绊寻,那么大廳與子游戲腳本加密的key一定要相同;ǘ铡!因?yàn)橹鞒绦蚴谴髲d澄步,解密腳本都是用大廳的key冰蘑。構(gòu)建成功后,將main.js復(fù)制一份到src下村缸,然后打開修改兩個(gè)地方祠肥。無(wú)論creator哪個(gè)版本,以構(gòu)建出來的main.js為主梯皿,然后同樣修改這兩地方就好了

 //~~~~~~~~~1仇箱、添加這段~~~~~~~~~~~~~~~
     cc.director.startAnimation();  //官方說解決個(gè)BUG
     'use strict';
     //后面的路徑根據(jù)自己的游戲修改
     cc.INGAME = (jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/')+'ALLGame/Niuniu/';  
 //~~~~~~~~~~~~~~~~~~~~~~~~~~
 //~~~~~~~~~2.修改這段~~~~~~~~~~~~~~~
      require(cc.INGAME + 'src/settings.js');
      require(cc.INGAME  +window._CCSettings ? 'src/project.dev.js' : 'src/project.js');
      // require('src/jsb_polyfill.js');
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

整份main.js如下(v1.10.2):

(function () {

    //~~~~~~~~~1县恕、添加這段~~~~~~~~~~~~~~~
     cc.director.startAnimation();  //官方說解決個(gè)BUG
     'use strict';
     cc.INGAME = (jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/')+'ALLGame/Niuniu/';  
     //~~~~~~~~~~~~~~~~~~~~~~~~~~

    function boot () {

        var settings = window._CCSettings;
        window._CCSettings = undefined;

        if ( !settings.debug ) {
            var uuids = settings.uuids;

            var rawAssets = settings.rawAssets;
            var assetTypes = settings.assetTypes;
            var realRawAssets = settings.rawAssets = {};
            for (var mount in rawAssets) {
                var entries = rawAssets[mount];
                var realEntries = realRawAssets[mount] = {};
                for (var id in entries) {
                    var entry = entries[id];
                    var type = entry[1];
                    // retrieve minified raw asset
                    if (typeof type === 'number') {
                        entry[1] = assetTypes[type];
                    }
                    // retrieve uuid
                    realEntries[uuids[id] || id] = entry;
                }
            }

            var scenes = settings.scenes;
            for (var i = 0; i < scenes.length; ++i) {
                var scene = scenes[i];
                if (typeof scene.uuid === 'number') {
                    scene.uuid = uuids[scene.uuid];
                }
            }

            var packedAssets = settings.packedAssets;
            for (var packId in packedAssets) {
                var packedIds = packedAssets[packId];
                for (var j = 0; j < packedIds.length; ++j) {
                    if (typeof packedIds[j] === 'number') {
                        packedIds[j] = uuids[packedIds[j]];
                    }
                }
            }
        }

        // init engine
        var canvas;

        if (cc.sys.isBrowser) {
            canvas = document.getElementById('GameCanvas');
        }

        if (false) {
            var ORIENTATIONS = {
                'portrait': 1,
                'landscape left': 2,
                'landscape right': 3
            };
            BK.Director.screenMode = ORIENTATIONS[settings.orientation];
            initAdapter();
        }

        function setLoadingDisplay () {
            // Loading splash scene
            var splash = document.getElementById('splash');
            var progressBar = splash.querySelector('.progress-bar span');
            cc.loader.onProgress = function (completedCount, totalCount, item) {
                var percent = 100 * completedCount / totalCount;
                if (progressBar) {
                    progressBar.style.width = percent.toFixed(2) + '%';
                }
            };
            splash.style.display = 'block';
            progressBar.style.width = '0%';

            cc.director.once(cc.Director.EVENT_AFTER_SCENE_LAUNCH, function () {
                splash.style.display = 'none';
            });
        }

        var onStart = function () {
            cc.loader.downloader._subpackages = settings.subpackages;

            if (false) {
                BK.Script.loadlib();
            }

            cc.view.resizeWithBrowserSize(true);

            if (!false && !false) {
                if (cc.sys.isBrowser) {
                    setLoadingDisplay();
                }

                if (cc.sys.isMobile) {
                    if (settings.orientation === 'landscape') {
                        cc.view.setOrientation(cc.macro.ORIENTATION_LANDSCAPE);
                    }
                    else if (settings.orientation === 'portrait') {
                        cc.view.setOrientation(cc.macro.ORIENTATION_PORTRAIT);
                    }
                    cc.view.enableAutoFullScreen([
                        cc.sys.BROWSER_TYPE_BAIDU,
                        cc.sys.BROWSER_TYPE_WECHAT,
                        cc.sys.BROWSER_TYPE_MOBILE_QQ,
                        cc.sys.BROWSER_TYPE_MIUI,
                    ].indexOf(cc.sys.browserType) < 0);
                }

                // Limit downloading max concurrent task to 2,
                // more tasks simultaneously may cause performance draw back on some android system / browsers.
                // You can adjust the number based on your own test result, you have to set it before any loading process to take effect.
                if (cc.sys.isBrowser && cc.sys.os === cc.sys.OS_ANDROID) {
                    cc.macro.DOWNLOAD_MAX_CONCURRENT = 2;
                }
            }

            // init assets
            cc.AssetLibrary.init({
                libraryPath: 'res/import',
                rawAssetsBase: 'res/raw-',
                rawAssets: settings.rawAssets,
                packedAssets: settings.packedAssets,
                md5AssetsMap: settings.md5AssetsMap
            });

            if (false) {
                cc.Pipeline.Downloader.PackDownloader._doPreload("WECHAT_SUBDOMAIN", settings.WECHAT_SUBDOMAIN_DATA);
            }

            var launchScene = settings.launchScene;

            // load scene
            cc.director.loadScene(launchScene, null,
                function () {
                    if (cc.sys.isBrowser) {
                        // show canvas
                        canvas.style.visibility = '';
                        var div = document.getElementById('GameDiv');
                        if (div) {
                            div.style.backgroundImage = '';
                        }
                    }
                    cc.loader.onProgress = null;
                    console.log('Success to load scene: ' + launchScene);
                }
            );
        };

        // jsList
        var jsList = settings.jsList;

        if (!false) {
            var bundledScript = settings.debug ? 'src/project.dev.js' : 'src/project.js';
            if (jsList) {
                jsList = jsList.map(function (x) {
                    return 'src/' + x;
                });
                jsList.push(bundledScript);
            }
            else {
                jsList = [bundledScript];
            }
        }

        // anysdk scripts
        if (cc.sys.isNative && cc.sys.isMobile) {
//            jsList = jsList.concat(['src/anysdk/jsb_anysdk.js', 'src/anysdk/jsb_anysdk_constants.js']);
        }

        var option = {
            //width: width,
            //height: height,
            id: 'GameCanvas',
            scenes: settings.scenes,
            debugMode: settings.debug ? cc.DebugMode.INFO : cc.DebugMode.ERROR,
            showFPS: (!false && !false) && settings.debug,
            frameRate: 60,
            jsList: jsList,
            groupList: settings.groupList,
            collisionMatrix: settings.collisionMatrix,
            renderMode: 0
        }

        cc.game.run(option, onStart);
    }

    if (false) {
        BK.Script.loadlib('GameRes://libs/qqplay-adapter.js');
        BK.Script.loadlib('GameRes://src/settings.js');
        BK.Script.loadlib();
        BK.Script.loadlib('GameRes://libs/qqplay-downloader.js');
        qqPlayDownloader.REMOTE_SERVER_ROOT = "";
        var prevPipe = cc.loader.md5Pipe || cc.loader.assetLoader;
        cc.loader.insertPipeAfter(prevPipe, qqPlayDownloader);
        // <plugin script code>
        boot();
        return;
    }

    if (false) {
        require(window._CCSettings.debug ? 'cocos2d-js.js' : 'cocos2d-js-min.js');
        require('./libs/weapp-adapter/engine/index.js');
        var prevPipe = cc.loader.md5Pipe || cc.loader.assetLoader;
        cc.loader.insertPipeAfter(prevPipe, wxDownloader);
        boot();
        return;
    }

    if (window.jsb) {

        //~~~~~~~~~2.修改這段~~~~~~~~~~~~~~~
        require(cc.INGAME + 'src/settings.js');
        require(cc.INGAME  +window._CCSettings ? 'src/project.dev.js' : 'src/project.js');
          // require('src/jsb_polyfill.js');
        //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      
        boot();
        return;
    }

    if (window.document) {
        var splash = document.getElementById('splash');
        splash.style.display = 'block';

        var cocos2d = document.createElement('script');
        cocos2d.async = true;
        cocos2d.src = window._CCSettings.debug ? 'cocos2d-js.js' : 'cocos2d-js-min.js';

        var engineLoaded = function () {
            document.body.removeChild(cocos2d);
            cocos2d.removeEventListener('load', engineLoaded, false);
            if (typeof VConsole !== 'undefined') {
                window.vConsole = new VConsole();
            }
            boot();
        };
        cocos2d.addEventListener('load', engineLoaded, false);
        document.body.appendChild(cocos2d);
    }

})();

修改完成后,利用上一篇熱更新提到的version_generator.js剂桥,生成project. manifest和version. manifest忠烛,這里步驟不能變,一定先構(gòu)建好子游戲渊额,復(fù)制main.js到src并修改况木,再利用version_generator.js生成project. manifest和version. manifest。準(zhǔn)備好之后旬迹,將src、res求类、project. manifest奔垦、version. manifest放在服務(wù)器:

image.png

然后可以測(cè)試跳到子游戲了。

子游戲返回大廳

在大廳跳到子游戲時(shí)尸疆,我們利用了main.js椿猎,同理的,返回大廳也是寿弱。首先準(zhǔn)好返回大廳的代碼犯眠,注意我目前的版本需要window.require,網(wǎng)上其他文章好像1.5.1以前只需要require

 returnHall(){
      let subgameSearchPath = (jsb.fileUtils ? jsb.fileUtils.getWritablePath() : '/')+'ALLGame/Niuniu/';
      window.require(subgameSearchPath + 'src/hall.js');
  }

然后設(shè)置好點(diǎn)擊事件構(gòu)建后症革,與上面的步驟一樣復(fù)制main.js到src并修改筐咧,然后將修改完的main.js復(fù)制一份,改名為hall.js噪矛,修改hall.js的 cc.INGAME量蕊,這里區(qū)分Android與iOS

 if (cc.sys.os === cc.sys.OS_ANDROID) {
      cc.INGAME = 'assets/';
 }else if(cc.sys.os == cc.sys.OS_IOS){
      cc.INGAME = jsb.reflection.callStaticMethod("AppController", "getHallPath")+"/";
 }

iOS還需要在xcode中,AppController類下加入方法getHallPath:

+ (NSString *)getHallPath
{
    return [[NSBundle mainBundle] bundlePath];
}

解決游戲之間cid艇挨、classname沖突問題

A Class already exists with the same cid
cid沖突可能是復(fù)制原因造成的残炮,解決的方法是把沖突的腳本移出工程,再等creator刷新后缩滨,重新導(dǎo)入進(jìn)來势就。

A Class already exists with the same classname
classname沖突,如果是公用的腳本脉漏,比如一些通用類苞冯,在各個(gè)游戲一樣的話,可以忽略鸠删,creator不會(huì)重新加載抱完,但那些有區(qū)別的類名又相同的,目前的做法是每個(gè)游戲都類名都加游戲前綴刃泡。

解決內(nèi)存問題

已知的問題:

假如進(jìn)去子游戲一次巧娱,退出到大廳碉怔,發(fā)現(xiàn)更新了,更新子游戲了禁添,再進(jìn)去子游戲沒有更新到撮胧,因?yàn)樽佑螒虻臄?shù)據(jù)還在內(nèi)存,不會(huì)再去重新load老翘。

子游戲退出到大廳芹啥,內(nèi)存數(shù)據(jù)還在,下次進(jìn)入子游戲的數(shù)據(jù)還是最后一次修改的數(shù)據(jù)铺峭,不會(huì)重置墓怀。

目前沒有很好的方案,我們用了一種偏方卫键,返回大廳都用cc.game.restart傀履,黑屏的問題,利用原生交互彈一張loading莉炉,因?yàn)閏c.game.restart不會(huì)重啟應(yīng)用钓账,用一張loading圖先蓋住creator,等大廳onenable是時(shí)候隱藏了loading絮宁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末梆暮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绍昂,更是在濱河造成了極大的恐慌啦粹,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件治专,死亡現(xiàn)場(chǎng)離奇詭異卖陵,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)张峰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門泪蔫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人喘批,你說我怎么就攤上這事撩荣。” “怎么了饶深?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵餐曹,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我敌厘,道長(zhǎng)台猴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮饱狂,結(jié)果婚禮上曹步,老公的妹妹穿的比我還像新娘。我一直安慰自己休讳,他們只是感情好讲婚,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著俊柔,像睡著了一般筹麸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上雏婶,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天物赶,我揣著相機(jī)與錄音,去河邊找鬼留晚。 笑死块差,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的倔丈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼状蜗,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼需五!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起轧坎,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤宏邮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后缸血,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蜜氨,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年捎泻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了飒炎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笆豁,死狀恐怖郎汪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闯狱,我是刑警寧澤煞赢,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站哄孤,受9級(jí)特大地震影響照筑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一凝危、第九天 我趴在偏房一處隱蔽的房頂上張望波俄。 院中可真熱鬧,春花似錦媒抠、人聲如沸弟断。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阀趴。三九已至,卻和暖如春苍匆,著一層夾襖步出監(jiān)牢的瞬間刘急,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工浸踩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留叔汁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓检碗,卻偏偏與公主長(zhǎng)得像据块,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子折剃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 一另假、前言 根據(jù)上一篇(Cocos Creator熱更新),可以看出以下幾點(diǎn):build-default目錄下的ma...
    陌上冰火閱讀 17,166評(píng)論 43 27
  • creator生成的項(xiàng)目是純粹的數(shù)據(jù)驅(qū)動(dòng)而非代碼驅(qū)動(dòng)怕犁,一切皆為數(shù)據(jù)边篮,包括腳本、圖片奏甫、音頻戈轿、動(dòng)畫等,而數(shù)據(jù)驅(qū)動(dòng)需要一...
    Dane_404閱讀 647評(píng)論 0 0
  • 版權(quán)聲明:本文為博主原創(chuàng)文章智蝠,未經(jīng)博主允許不得轉(zhuǎn)載。 webpack介紹和使用 一奈梳、webpack介紹 1杈湾、由來 ...
    it筱竹閱讀 11,112評(píng)論 0 21
  • 丘奇先生 最近偏愛溫暖的影片。 阿米爾汗的摔跤吧爸爸攘须、神秘巨星漆撞;迪士尼的尋夢(mèng)環(huán)游記,還有前幾天看的返老還童,都是這...
    寧黛閱讀 259評(píng)論 0 0
  • 1 那時(shí)候的我浮驳,不過是六七歲的黃毛丫頭悍汛。 那也不過是平凡得不能再平凡的川東北冬日的黎明時(shí)分,雞剛鳴過第三遍至会,用現(xiàn)在...
    阿鹿在寫閱讀 846評(píng)論 1 3