/* * Copyright (c) 2015 Chukong Technologies Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ // // cocos2d boot // //+++++++++++++++++++++++++something about async begin+++++++++++++++++++++++++++++++ /** * Async Pool class, a helper of cc.async * @param {Object|Array} srcObj * @param {Number} limit the limit of parallel number * @param {function} iterator * @param {function} onEnd * @param {object} target * @constructor */ cc.AsyncPool = function(srcObj, limit, iterator, onEnd, target){ var self = this; self._srcObj = srcObj; self._limit = limit; self._pool = []; self._iterator = iterator; self._iteratorTarget = target; self._onEnd = onEnd; self._onEndTarget = target; self._results = srcObj instanceof Array ? [] : {}; self._isErr = false; cc.each(srcObj, function(value, index){ self._pool.push({index : index, value : value}); }); self.size = self._pool.length; self.finishedSize = 0; self._workingSize = 0; self._limit = self._limit || self.size; self.onIterator = function(iterator, target){ self._iterator = iterator; self._iteratorTarget = target; }; self.onEnd = function(endCb, endCbTarget){ self._onEnd = endCb; self._onEndTarget = endCbTarget; }; self._handleItem = function(){ var self = this; if(self._pool.length == 0) return; //return directly if the array's length = 0 if(self._workingSize >= self._limit) return; //return directly if the working size great equal limit number var item = self._pool.shift(); var value = item.value, index = item.index; self._workingSize++; self._iterator.call(self._iteratorTarget, value, index, function(err){ if(self._isErr) return; self.finishedSize++; self._workingSize--; if(err) { self._isErr = true; if(self._onEnd) self._onEnd.call(self._onEndTarget, err); return } var arr = Array.prototype.slice.call(arguments, 1); self._results[this.index] = arr[0]; if (self.finishedSize === self.size) { if (self._onEnd) self._onEnd.call(self._onEndTarget, null, self._results); return; } self._handleItem(); }.bind(item), self); }; self.flow = function(){ var self = this; if(self._pool.length === 0) { if(self._onEnd) self._onEnd.call(self._onEndTarget, null, []); return; } for(var i = 0; i < self._limit; i++) self._handleItem(); } }; /** * @class */ cc.async = /** @lends cc.async# */{ /** * Do tasks series. * @param {Array|Object} tasks * @param {function} [cb] callback * @param {Object} [target] * @return {cc.AsyncPool} */ series : function(tasks, cb, target){ var asyncPool = new cc.AsyncPool(tasks, 1, function(func, index, cb1){ func.call(target, cb1); }, cb, target); asyncPool.flow(); return asyncPool; }, /** * Do tasks parallel. * @param {Array|Object} tasks * @param {function} cb callback * @param {Object} [target] * @return {cc.AsyncPool} */ parallel : function(tasks, cb, target){ var asyncPool = new cc.AsyncPool(tasks, 0, function(func, index, cb1){ func.call(target, cb1); }, cb, target); asyncPool.flow(); return asyncPool; }, /** * Do tasks waterfall. * @param {Array|Object} tasks * @param {function} cb callback * @param {Object} [target] * @return {cc.AsyncPool} */ waterfall : function(tasks, cb, target){ var args = []; var lastResults = [null];//the array to store the last results var asyncPool = new cc.AsyncPool(tasks, 1, function (func, index, cb1) { args.push(function (err) { args = Array.prototype.slice.call(arguments, 1); if(tasks.length - 1 === index) lastResults = lastResults.concat(args);//while the last task cb1.apply(null, arguments); }); func.apply(target, args); }, function (err) { if (!cb) return; if (err) return cb.call(target, err); cb.apply(target, lastResults); }); asyncPool.flow(); return asyncPool; }, /** * Do tasks by iterator. * @param {Array|Object} tasks * @param {function|Object} iterator * @param {function} [callback] * @param {Object} [target] * @return {cc.AsyncPool} */ map : function(tasks, iterator, callback, target){ var locIterator = iterator; if(typeof(iterator) === "object"){ callback = iterator.cb; target = iterator.iteratorTarget; locIterator = iterator.iterator; } var asyncPool = new cc.AsyncPool(tasks, 0, locIterator, callback, target); asyncPool.flow(); return asyncPool; }, /** * Do tasks by iterator limit. * @param {Array|Object} tasks * @param {Number} limit * @param {function} iterator * @param {function} cb callback * @param {Object} [target] */ mapLimit : function(tasks, limit, iterator, cb, target){ var asyncPool = new cc.AsyncPool(tasks, limit, iterator, cb, target); asyncPool.flow(); return asyncPool; } }; //+++++++++++++++++++++++++something about async end+++++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++something about path begin++++++++++++++++++++++++++++++++ /** * @class */ cc.path = /** @lends cc.path# */{ normalizeRE: /[^\.\/]+\/\.\.\//, /** * Join strings to be a path. * @example cc.path.join("a", "b.png");//-->"a/b.png" cc.path.join("a", "b", "c.png");//-->"a/b/c.png" cc.path.join("a", "b");//-->"a/b" cc.path.join("a", "b", "/");//-->"a/b/" cc.path.join("a", "b/", "/");//-->"a/b/" * @returns {string} */ join: function () { var l = arguments.length; var result = ""; for (var i = 0; i < l; i++) { result = (result + (result === "" ? "" : "/") + arguments[i]).replace(/(\/|\\\\)$/, ""); } return result; }, /** * Get the ext name of a path. * @example cc.path.extname("a/b.png");//-->".png" cc.path.extname("a/b.png?a=1&b=2");//-->".png" cc.path.extname("a/b");//-->null cc.path.extname("a/b?a=1&b=2");//-->null * @param {string} pathStr * @returns {*} */ extname: function (pathStr) { var temp = /(\.[^\.\/\?\\]*)(\?.*)?$/.exec(pathStr); return temp ? temp[1] : null; }, /** * Get the main name of a file name * @param {string} fileName * @returns {string} */ mainFileName: function(fileName){ if(fileName){ var idx = fileName.lastIndexOf("."); if(idx !== -1) return fileName.substring(0,idx); } return fileName; }, /** * Get the file name of a file path. * @example cc.path.basename("a/b.png");//-->"b.png" cc.path.basename("a/b.png?a=1&b=2");//-->"b.png" cc.path.basename("a/b.png", ".png");//-->"b" cc.path.basename("a/b.png?a=1&b=2", ".png");//-->"b" cc.path.basename("a/b.png", ".txt");//-->"b.png" * @param {string} pathStr * @param {string} [extname] * @returns {*} */ basename: function (pathStr, extname) { var index = pathStr.indexOf("?"); if (index > 0) pathStr = pathStr.substring(0, index); var reg = /(\/|\\\\)([^(\/|\\\\)]+)$/g; var result = reg.exec(pathStr.replace(/(\/|\\\\)$/, "")); if (!result) return null; var baseName = result[2]; if (extname && pathStr.substring(pathStr.length - extname.length).toLowerCase() === extname.toLowerCase()) return baseName.substring(0, baseName.length - extname.length); return baseName; }, /** * Get dirname of a file path. * @example * unix cc.path.driname("a/b/c.png");//-->"a/b" cc.path.driname("a/b/c.png?a=1&b=2");//-->"a/b" cc.path.dirname("a/b/");//-->"a/b" cc.path.dirname("c.png");//-->"" * windows cc.path.driname("a\\b\\c.png");//-->"a\b" cc.path.driname("a\\b\\c.png?a=1&b=2");//-->"a\b" * @param {string} pathStr * @returns {*} */ dirname: function (pathStr) { return pathStr.replace(/((.*)(\/|\\|\\\\))?(.*?\..*$)?/, '$2'); }, /** * Change extname of a file path. * @example cc.path.changeExtname("a/b.png", ".plist");//-->"a/b.plist" cc.path.changeExtname("a/b.png?a=1&b=2", ".plist");//-->"a/b.plist?a=1&b=2" * @param {string} pathStr * @param {string} [extname] * @returns {string} */ changeExtname: function (pathStr, extname) { extname = extname || ""; var index = pathStr.indexOf("?"); var tempStr = ""; if (index > 0) { tempStr = pathStr.substring(index); pathStr = pathStr.substring(0, index); } index = pathStr.lastIndexOf("."); if (index < 0) return pathStr + extname + tempStr; return pathStr.substring(0, index) + extname + tempStr; }, /** * Change file name of a file path. * @example cc.path.changeBasename("a/b/c.plist", "b.plist");//-->"a/b/b.plist" cc.path.changeBasename("a/b/c.plist?a=1&b=2", "b.plist");//-->"a/b/b.plist?a=1&b=2" cc.path.changeBasename("a/b/c.plist", ".png");//-->"a/b/c.png" cc.path.changeBasename("a/b/c.plist", "b");//-->"a/b/b" cc.path.changeBasename("a/b/c.plist", "b", true);//-->"a/b/b.plist" * @param {String} pathStr * @param {String} basename * @param {Boolean} [isSameExt] * @returns {string} */ changeBasename: function (pathStr, basename, isSameExt) { if (basename.indexOf(".") === 0) return this.changeExtname(pathStr, basename); var index = pathStr.indexOf("?"); var tempStr = ""; var ext = isSameExt ? this.extname(pathStr) : ""; if (index > 0) { tempStr = pathStr.substring(index); pathStr = pathStr.substring(0, index); } index = pathStr.lastIndexOf("/"); index = index <= 0 ? 0 : index + 1; return pathStr.substring(0, index) + basename + ext + tempStr; }, //todo make public after verification _normalize: function(url){ var oldUrl = url = String(url); //removing all ../ do { oldUrl = url; url = url.replace(this.normalizeRE, ""); } while(oldUrl.length !== url.length); return url; } }; //+++++++++++++++++++++++++something about path end++++++++++++++++++++++++++++++++ //+++++++++++++++++++++++++something about loader start+++++++++++++++++++++++++++ cc.loader = { _resPath : "", _audioPath : "", _register : {},//register of loaders cache : {},//cache for data loaded _langPathCache : {},//cache for lang path /** * Get XMLHttpRequest. * @returns {XMLHttpRequest} */ getXMLHttpRequest : function () { return new XMLHttpRequest(); }, //@MODE_BEGIN DEV _jsCache : {},//cache for js _getArgs4Js: function (args) { var a0 = args[0], a1 = args[1], a2 = args[2], results = ["", null, null]; if (args.length === 1) { results[1] = a0 instanceof Array ? a0 : [a0]; } else if (args.length === 2) { if (typeof a1 === "function") { results[1] = a0 instanceof Array ? a0 : [a0]; results[2] = a1; } else { results[0] = a0 || ""; results[1] = a1 instanceof Array ? a1 : [a1]; } } else if (args.length === 3) { results[0] = a0 || ""; results[1] = a1 instanceof Array ? a1 : [a1]; results[2] = a2; } else throw new Error("arguments error to load js!"); return results; }, /** * Load js files. * @param {?string=} baseDir The pre path for jsList. * @param {array.} jsList List of js path. * @param {function} cb Callback function * * If the arguments.length == 2, then the baseDir turns to be "". * @returns {*} */ loadJs: function (baseDir, jsList, cb) { var self = this, localJsCache = self._jsCache, args = self._getArgs4Js(arguments); baseDir = args[0]; jsList = args[1]; cb = args[2]; var ccPath = cc.path; for(var i = 0, li = jsList.length; i < li; ++i){ require(ccPath.join(baseDir, jsList[i])); } if(cb) cb(); }, /** * Load js width loading image. * * @param {string} [baseDir] * @param {array} jsList * @param {function} [cb] */ loadJsWithImg : function(baseDir, jsList, cb){ this.loadJs.apply(this, arguments); }, //@MODE_END DEV /** * Load a single resource as txt. * @param {!string} url * @param {function} cb arguments are : err, txt */ loadTxt : function(url, cb){ cb(null, jsb.fileUtils.getStringFromFile(url)); }, loadJson : function(url, cb){ this.loadTxt(url, function(err, txt){ try{ err ? cb(err) : cb(null, JSON.parse(txt)); }catch(e){ throw e; cb("load json [" + url + "] failed : " + e); } }); }, /** * Load a single image. * @param {!string} url * @param {object} [option] * @param {function} cb * @returns {Image} */ loadImg: function (url, option, cb){ var l = arguments.length; if(l == 2) cb = option; var cachedTex = cc.textureCache.getTextureForKey(url); if (cachedTex) { cb && cb(null, cachedTex); } else if (url.match(jsb.urlRegExp)) { jsb.loadRemoteImg(url, function(succeed, tex) { if (succeed) { cb && cb(null, tex); } else { cb && cb("Load image failed"); } }); } else { cc.textureCache._addImageAsync(url, function (tex){ if (tex instanceof cc.Texture2D) cb && cb(null, tex); else cb && cb("Load image failed"); }); } }, /** * Load binary data by url. * @param {String} url * @param {Function} cb */ loadBinary : function(url, cb){ cb(null, jsb.fileUtils.getDataFromFile(url)); }, loadBinarySync : function(url){ return jsb.fileUtils.getDataFromFile(url); }, /** * Iterator function to load res * @param {object} item * @param {number} index * @param {function} [cb] * @returns {*} * @private */ _loadResIterator: function (item, index, cb) { var self = this, url = null; var type = item.type; if (type) { type = "." + type.toLowerCase(); url = item.src ? item.src : item.name + type; } else { url = item; type = cc.path.extname(url); } var obj = self.cache[url]; if (obj) return cb(null, obj); var loader = null; if (type) { loader = self._register[type.toLowerCase()]; } if (!loader) { cc.error("loader for [" + type + "] not exists!"); return cb(); } var basePath = loader.getBasePath ? loader.getBasePath() : self.resPath; var realUrl = self.getUrl(basePath, url); loader.load(realUrl, url, item, function (err, data) { if (err) { cc.log(err); self.cache[url] = null; delete self.cache[url]; cb(); } else { self.cache[url] = data; cb(null, data); } }); }, /** * Get url with basePath. * @param {string} basePath * @param {string} [url] * @returns {*} */ getUrl: function (basePath, url) { var self = this, langPathCache = self._langPathCache, path = cc.path; if (basePath !== undefined && url === undefined) { url = basePath; var type = path.extname(url); type = type ? type.toLowerCase() : ""; var loader = self._register[type]; if (!loader) basePath = self.resPath; else basePath = loader.getBasePath ? loader.getBasePath() : self.resPath; } url = cc.path.join(basePath || "", url); if (url.match(/[\/(\\\\)]lang[\/(\\\\)]/i)) { if (langPathCache[url]) return langPathCache[url]; var extname = path.extname(url) || ""; url = langPathCache[url] = url.substring(0, url.length - extname.length) + "_" + cc.sys.language + extname; } return url; }, /** * Load resources then call the callback. * @param {string} resources * @param {function} [option] callback or trigger * @param {function|Object} [loadCallback] * @return {cc.AsyncPool} */ load : function(resources, option, loadCallback){ var self = this; var len = arguments.length; if(len === 0) throw new Error("arguments error!"); if(len === 3){ if(typeof option === "function"){ if(typeof loadCallback === "function") option = {trigger : option, cb : loadCallback }; else option = { cb : option, cbTarget : loadCallback}; } }else if(len === 2){ if(typeof option === "function") option = {cb : option}; }else if(len === 1){ option = {}; } if(!(resources instanceof Array)) resources = [resources]; var asyncPool = new cc.AsyncPool( resources, 0, function (value, index, AsyncPoolCallback, aPool) { self._loadResIterator(value, index, function (err) { var arr = Array.prototype.slice.call(arguments, 1); if (option.trigger) option.trigger.call(option.triggerTarget, arr[0], aPool.size, aPool.finishedSize); //call trigger AsyncPoolCallback(err, arr[0]); }); }, option.cb, option.cbTarget); asyncPool.flow(); return asyncPool; }, /** *

* Loads alias map from the contents of a filename.
*
* @note The plist file name should follow the format below:
*
*
*
*
* filenames
*
* sounds/click.wav
* sounds/click.caf
* sounds/endgame.wav
* sounds/endgame.caf
* sounds/gem-0.wav
* sounds/gem-0.caf
*

* metadata
*
* version
* 1
*

*

*

*

* @param {String} filename The plist file name. * @param {Function} cb callback */ loadAliases : function(url, cb){ jsb.fileUtils.loadFilenameLookup(url); if(cb) cb(); }, /** * Register a resource loader into loader. * @param {string} extNames * @param {function} loader */ register: function (extNames, loader) { if (!extNames || !loader) return; var self = this; if (typeof extNames === "string") return this._register[extNames.trim().toLowerCase()] = loader; for (var i = 0, li = extNames.length; i < li; i++) { self._register["." + extNames[i].trim().toLowerCase()] = loader; } }, /** * Get resource data by url. * @param url * @returns {*} */ getRes : function(url){ var cached = this.cache[url]; if (cached) return cached; var type = cc.path.extname(url); if (!type) return cc.log("cc.loader.getRes: Invalid url"); var loader = this._register[type.toLowerCase()]; if (!loader) return cc.log("cc.loader.getRes: loader for [" + type + "] not exists!"); var basePath = loader.getBasePath ? loader.getBasePath() : this.resPath; var realUrl = this.getUrl(basePath, url); return loader.load(realUrl, url); }, /** * Release the cache of resource by url. * @param url */ release: function (url) { var cache = this.cache; delete cache[url]; }, /** * Resource cache of all resources. */ releaseAll: function () { var locCache = this.cache; for (var key in locCache) delete locCache[key]; } }; cc.defineGetterSetter(cc.loader, "resPath", function(){ return this._resPath; }, function(resPath){ this._resPath = resPath || ""; jsb.fileUtils.addSearchPath(this._resPath); }); cc.defineGetterSetter(cc.loader, "audioPath", function(){ return this._audioPath; }, function(audioPath){ this._audioPath = audioPath || ""; jsb.fileUtils.addSearchPath(this._audioPath); }); //+++++++++++++++++++++++++something about loader end+++++++++++++++++++++++++++++ /** * A string tool to construct a string with format string. * for example: * cc.formatStr("a: %d, b: %b", a, b); * cc.formatStr(a, b, c); * @returns {String} */ cc.formatStr = function(){ var args = arguments; var l = args.length; if(l < 1) return ""; var str = args[0]; var needToFormat = true; if(typeof str === "object"){ needToFormat = false; } for(var i = 1; i < l; ++i){ var arg = args[i]; if(needToFormat){ while(true){ var result = null; if(typeof arg === "number"){ result = str.match(/(%d)|(%s)/); if(result){ str = str.replace(/(%d)|(%s)/, arg); break; } } result = str.match(/%s/); if(result) str = str.replace(/%s/, arg); else str += " " + arg; break; } }else str += " " + arg; } return str; }; //+++++++++++++++++++++++++Engine initialization function begin+++++++++++++++++++++++++++ // Define singleton objects cc.director = cc.Director.getInstance(); cc.winSize = cc.director.getWinSize(); cc.view = cc.director.getOpenGLView(); cc.view.getDevicePixelRatio = cc.view.getRetinaFactor; cc.view.convertToLocationInView = function (tx, ty, relatedPos) { var _devicePixelRatio = cc.view.getDevicePixelRatio(); return {x: _devicePixelRatio * (tx - relatedPos.left), y: _devicePixelRatio * (relatedPos.top + relatedPos.height - ty)}; }; cc.view.enableRetina = function(enabled) {}; cc.view.isRetinaEnabled = function() { var sys = cc.sys; return (sys.os == sys.OS_IOS || sys.os == sys.OS_OSX) ? true : false; }; cc.view.adjustViewPort = function() {}; cc.view.resizeWithBrowserSize = function () {return;}; cc.view.setResizeCallback = function() {return;}; cc.view.enableAutoFullScreen = function () {return;}; cc.view.isAutoFullScreenEnabled = function() {return true;}; cc.view._setDesignResolutionSize = cc.view.setDesignResolutionSize; cc.view.setDesignResolutionSize = function(width,height,resolutionPolicy){ cc.view._setDesignResolutionSize(width,height,resolutionPolicy); cc.winSize = cc.director.getWinSize(); cc.visibleRect.init(); }; cc.view.setRealPixelResolution = cc.view.setDesignResolutionSize; cc.view.setResolutionPolicy = function(resolutionPolicy){ var size = cc.view.getDesignResolutionSize(); cc.view.setDesignResolutionSize(size.width,size.height,resolutionPolicy); }; cc.view.getCanvasSize = cc.view.getFrameSize; cc.view.getVisibleSizeInPixel = cc.view.getVisibleSize; cc.view.getVisibleOriginInPixel = cc.view.getVisibleOrigin; cc.view.setContentTranslateLeftTop = function(){return;}; cc.view.getContentTranslateLeftTop = function(){return null;}; cc.view.setFrameZoomFactor = function(){return;}; cc.DENSITYDPI_DEVICE = "device-dpi"; cc.DENSITYDPI_HIGH = "high-dpi"; cc.DENSITYDPI_MEDIUM = "medium-dpi"; cc.DENSITYDPI_LOW = "low-dpi"; cc.view.setTargetDensityDPI = function() {}; cc.view.getTargetDensityDPI = function() {return cc.DENSITYDPI_DEVICE;}; cc.eventManager = cc.director.getEventDispatcher(); cc.audioEngine = cc.AudioEngine.getInstance(); cc.audioEngine.end = function(){ this.stopMusic(); this.stopAllEffects(); }; cc.audioEngine.features = { MULTI_CHANNEL: true, AUTOPLAY: true }; cc.configuration = cc.Configuration.getInstance(); cc.textureCache = cc.director.getTextureCache(); cc.TextureCache.prototype._addImageAsync = cc.TextureCache.prototype.addImageAsync; cc.TextureCache.prototype.addImageAsync = function(url, cb, target) { var localTex = null; cc.loader.loadImg(url, function(err, tex) { if (err) tex = null; if (cb) { cb.call(target, tex); } localTex = tex; }); return localTex; }; // Fix for compatibility with old APIs cc.TextureCache.prototype._addImage = cc.TextureCache.prototype.addImage; cc.TextureCache.prototype.addImage = function(url, cb, target) { if (typeof cb === "function") { return this.addImageAsync(url, cb, target); } else { if (cb) { return this._addImage(url, cb); } else { return this._addImage(url); } } }; cc.shaderCache = cc.ShaderCache.getInstance(); cc.animationCache = cc.AnimationCache.getInstance(); cc.spriteFrameCache = cc.SpriteFrameCache.getInstance(); cc.plistParser = cc.PlistParser.getInstance(); // File utils (Temporary, won't be accessible) cc.fileUtils = cc.FileUtils.getInstance(); cc.fileUtils.setPopupNotify(false); cc.screen = { init: function() {}, fullScreen: function() { return true; }, requestFullScreen: function(element, onFullScreenChange) { onFullScreenChange.call(); }, exitFullScreen: function() { return false; }, autoFullScreen: function(element, onFullScreenChange) { onFullScreenChange.call(); } }; /** * @type {Object} * @name jsb.fileUtils * jsb.fileUtils is the native file utils singleton object, * please refer to Cocos2d-x API to know how to use it. * Only available in JSB */ jsb.fileUtils = cc.fileUtils; delete cc.FileUtils; delete cc.fileUtils; /** * @type {Object} * @name jsb.reflection * jsb.reflection is a bridge to let you invoke Java static functions. * please refer to this document to know how to use it: http://www.cocos2d-x.org/docs/manual/framework/html5/v3/reflection/en * Only available on Android platform */ jsb.reflection = { callStaticMethod : function(){ cc.log("not supported on current platform"); } }; var _initSys = function () { /** * System variables * @namespace * @name cc.sys */ cc.sys = window.sys || {}; var sys = cc.sys; /** * English language code * @memberof cc.sys * @name LANGUAGE_ENGLISH * @constant * @type {Number} */ sys.LANGUAGE_ENGLISH = "en"; /** * Chinese language code * @memberof cc.sys * @name LANGUAGE_CHINESE * @constant * @type {Number} */ sys.LANGUAGE_CHINESE = "zh"; /** * French language code * @memberof cc.sys * @name LANGUAGE_FRENCH * @constant * @type {Number} */ sys.LANGUAGE_FRENCH = "fr"; /** * Italian language code * @memberof cc.sys * @name LANGUAGE_ITALIAN * @constant * @type {Number} */ sys.LANGUAGE_ITALIAN = "it"; /** * German language code * @memberof cc.sys * @name LANGUAGE_GERMAN * @constant * @type {Number} */ sys.LANGUAGE_GERMAN = "de"; /** * Spanish language code * @memberof cc.sys * @name LANGUAGE_SPANISH * @constant * @type {Number} */ sys.LANGUAGE_SPANISH = "es"; /** * Spanish language code * @memberof cc.sys * @name LANGUAGE_DUTCH * @constant * @type {Number} */ sys.LANGUAGE_DUTCH = "du"; /** * Russian language code * @memberof cc.sys * @name LANGUAGE_RUSSIAN * @constant * @type {Number} */ sys.LANGUAGE_RUSSIAN = "ru"; /** * Korean language code * @memberof cc.sys * @name LANGUAGE_KOREAN * @constant * @type {Number} */ sys.LANGUAGE_KOREAN = "ko"; /** * Japanese language code * @memberof cc.sys * @name LANGUAGE_JAPANESE * @constant * @type {Number} */ sys.LANGUAGE_JAPANESE = "ja"; /** * Hungarian language code * @memberof cc.sys * @name LANGUAGE_HUNGARIAN * @constant * @type {Number} */ sys.LANGUAGE_HUNGARIAN = "hu"; /** * Portuguese language code * @memberof cc.sys * @name LANGUAGE_PORTUGUESE * @constant * @type {Number} */ sys.LANGUAGE_PORTUGUESE = "pt"; /** * Arabic language code * @memberof cc.sys * @name LANGUAGE_ARABIC * @constant * @type {Number} */ sys.LANGUAGE_ARABIC = "ar"; /** * Norwegian language code * @memberof cc.sys * @name LANGUAGE_NORWEGIAN * @constant * @type {Number} */ sys.LANGUAGE_NORWEGIAN = "no"; /** * Polish language code * @memberof cc.sys * @name LANGUAGE_POLISH * @constant * @type {Number} */ sys.LANGUAGE_POLISH = "pl"; /** * Unknown language code * @memberof cc.sys * @name LANGUAGE_UNKNOWN * @constant * @type {Number} */ sys.LANGUAGE_UNKNOWN = "unkonwn"; /** * @memberof cc.sys * @name OS_IOS * @constant * @type {string} */ sys.OS_IOS = "iOS"; /** * @memberof cc.sys * @name OS_ANDROID * @constant * @type {string} */ sys.OS_ANDROID = "Android"; /** * @memberof cc.sys * @name OS_WINDOWS * @constant * @type {string} */ sys.OS_WINDOWS = "Windows"; /** * @memberof cc.sys * @name OS_MARMALADE * @constant * @type {string} */ sys.OS_MARMALADE = "Marmalade"; /** * @memberof cc.sys * @name OS_LINUX * @constant * @type {string} */ sys.OS_LINUX = "Linux"; /** * @memberof cc.sys * @name OS_BADA * @constant * @type {string} */ sys.OS_BADA = "Bada"; /** * @memberof cc.sys * @name OS_BLACKBERRY * @constant * @type {string} */ sys.OS_BLACKBERRY = "Blackberry"; /** * @memberof cc.sys * @name OS_OSX * @constant * @type {string} */ sys.OS_OSX = "OS X"; /** * @memberof cc.sys * @name OS_WP8 * @constant * @type {string} */ sys.OS_WP8 = "WP8"; /** * @memberof cc.sys * @name OS_WINRT * @constant * @type {string} */ sys.OS_WINRT = "WINRT"; /** * @memberof cc.sys * @name OS_UNKNOWN * @constant * @type {string} */ sys.OS_UNKNOWN = "Unknown"; /** * @memberof cc.sys * @name UNKNOWN * @constant * @default * @type {Number} */ sys.UNKNOWN = -1; /** * @memberof cc.sys * @name WIN32 * @constant * @default * @type {Number} */ sys.WIN32 = 0; /** * @memberof cc.sys * @name LINUX * @constant * @default * @type {Number} */ sys.LINUX = 1; /** * @memberof cc.sys * @name MACOS * @constant * @default * @type {Number} */ sys.MACOS = 2; /** * @memberof cc.sys * @name ANDROID * @constant * @default * @type {Number} */ sys.ANDROID = 3; /** * @memberof cc.sys * @name IOS * @constant * @default * @type {Number} */ sys.IPHONE = 4; /** * @memberof cc.sys * @name IOS * @constant * @default * @type {Number} */ sys.IPAD = 5; /** * @memberof cc.sys * @name BLACKBERRY * @constant * @default * @type {Number} */ sys.BLACKBERRY = 6; /** * @memberof cc.sys * @name NACL * @constant * @default * @type {Number} */ sys.NACL = 7; /** * @memberof cc.sys * @name EMSCRIPTEN * @constant * @default * @type {Number} */ sys.EMSCRIPTEN = 8; /** * @memberof cc.sys * @name TIZEN * @constant * @default * @type {Number} */ sys.TIZEN = 9; /** * @memberof cc.sys * @name WINRT * @constant * @default * @type {Number} */ sys.WINRT = 10; /** * @memberof cc.sys * @name WP8 * @constant * @default * @type {Number} */ sys.WP8 = 11; /** * @memberof cc.sys * @name MOBILE_BROWSER * @constant * @default * @type {Number} */ sys.MOBILE_BROWSER = 100; /** * @memberof cc.sys * @name DESKTOP_BROWSER * @constant * @default * @type {Number} */ sys.DESKTOP_BROWSER = 101; sys.BROWSER_TYPE_WECHAT = "wechat"; sys.BROWSER_TYPE_ANDROID = "androidbrowser"; sys.BROWSER_TYPE_IE = "ie"; sys.BROWSER_TYPE_QQ = "qqbrowser"; sys.BROWSER_TYPE_MOBILE_QQ = "mqqbrowser"; sys.BROWSER_TYPE_UC = "ucbrowser"; sys.BROWSER_TYPE_360 = "360browser"; sys.BROWSER_TYPE_BAIDU_APP = "baiduboxapp"; sys.BROWSER_TYPE_BAIDU = "baidubrowser"; sys.BROWSER_TYPE_MAXTHON = "maxthon"; sys.BROWSER_TYPE_OPERA = "opera"; sys.BROWSER_TYPE_OUPENG = "oupeng"; sys.BROWSER_TYPE_MIUI = "miuibrowser"; sys.BROWSER_TYPE_FIREFOX = "firefox"; sys.BROWSER_TYPE_SAFARI = "safari"; sys.BROWSER_TYPE_CHROME = "chrome"; sys.BROWSER_TYPE_LIEBAO = "liebao"; sys.BROWSER_TYPE_QZONE = "qzone"; sys.BROWSER_TYPE_SOUGOU = "sogou"; sys.BROWSER_TYPE_UNKNOWN = "unknown"; /** * Is native ? This is set to be true in jsb auto. * @memberof cc.sys * @name isNative * @type {Boolean} */ sys.isNative = true; /** * Indicate the running platform * @memberof cc.sys * @name platform * @type {Number} */ var platform = sys.platform = __getPlatform(); /** * Indicate whether system is mobile system * @memberof cc.sys * @name isMobile * @type {Boolean} */ sys.isMobile = (platform === sys.ANDROID || platform === sys.IPAD || platform === sys.IPHONE || platform === sys.WP8 || platform === sys.TIZEN || platform === sys.BLACKBERRY) ? true : false; sys._application = cc.Application.getInstance(); /** * Indicate the current language of the running system * @memberof cc.sys * @name language * @type {String} */ sys.language = (function(){ var language = sys._application.getCurrentLanguage(); switch(language){ case 0: return sys.LANGUAGE_ENGLISH; case 1: return sys.LANGUAGE_CHINESE; case 2: return sys.LANGUAGE_FRENCH; case 3: return sys.LANGUAGE_ITALIAN; case 4: return sys.LANGUAGE_GERMAN; case 5: return sys.LANGUAGE_SPANISH; case 6: return sys.LANGUAGE_DUTCH; case 7: return sys.LANGUAGE_RUSSIAN; case 8: return sys.LANGUAGE_KOREAN; case 9: return sys.LANGUAGE_JAPANESE; case 10: return sys.LANGUAGE_HUNGARIAN; case 11: return sys.LANGUAGE_PORTUGUESE; case 12: return sys.LANGUAGE_ARABIC; case 13: return sys.LANGUAGE_NORWEGIAN; case 14: return sys.LANGUAGE_POLISH; default : return sys.LANGUAGE_ENGLISH; } })(); /** * Indicate the running os name * @memberof cc.sys * @name os * @type {String} */ sys.os = __getOS(); /** * Indicate the running browser type * @memberof cc.sys * @name browserType * @type {String} */ sys.browserType = null; //null in jsb /** * Indicate the running browser version * @memberof cc.sys * @name browserVersion * @type {Number} */ sys.browserVersion = null; //null in jsb /** * Indicate the real pixel resolution of the whole game window * @memberof cc.sys * @name windowPixelResolution * @type {Number} */ sys.windowPixelResolution = cc.view.getFrameSize(); /** * The capabilities of the current platform * @memberof cc.sys * @name capabilities * @type {Object} */ var capabilities = sys.capabilities = { "canvas": false, "opengl": true }; if( sys.isMobile ) { capabilities["accelerometer"] = true; capabilities["touches"] = true; if (platform === sys.WINRT || platform === sys.WP8) { capabilities["keyboard"] = true; } } else { // desktop capabilities["keyboard"] = true; capabilities["mouse"] = true; // winrt can't suppot mouse in current version if (platform === sys.WINRT || platform === sys.WP8) { capabilities["touches"] = true; capabilities["mouse"] = false; } } /** * Forces the garbage collection, only available in JSB * @memberof cc.sys * @name garbageCollect * @function */ sys.garbageCollect = function() { __jsc__.garbageCollect(); }; /** * Dumps rooted objects, only available in JSB * @memberof cc.sys * @name dumpRoot * @function */ sys.dumpRoot = function() { __jsc__.dumpRoot(); }; /** * Restart the JS VM, only available in JSB * @memberof cc.sys * @name restartVM * @function */ sys.restartVM = function() { __restartVM(); }; /** * Clean a script in the JS VM, only available in JSB * @memberof cc.sys * @name cleanScript * @param {String} jsfile * @function */ sys.cleanScript = function(jsFile) { __cleanScript(jsFile); }; /** * Check whether an object is valid, * In web engine, it will return true if the object exist * In native engine, it will return true if the JS object and the correspond native object are both valid * @memberof cc.sys * @name isObjectValid * @param {Object} obj * @return {boolean} Validity of the object * @function */ sys.isObjectValid = function(obj) { return __isObjectValid(obj); }; /** * Dump system informations * @memberof cc.sys * @name dump * @function */ sys.dump = function () { var self = this; var str = ""; str += "isMobile : " + self.isMobile + "\r\n"; str += "language : " + self.language + "\r\n"; str += "browserType : " + self.browserType + "\r\n"; str += "capabilities : " + JSON.stringify(self.capabilities) + "\r\n"; str += "os : " + self.os + "\r\n"; str += "platform : " + self.platform + "\r\n"; cc.log(str); }; /** * Open a url in browser * @memberof cc.sys * @name openURL * @param {String} url */ sys.openURL = function(url){ sys._application.openURL(url); }; // JS to Native bridges if(window.JavascriptJavaBridge && cc.sys.os == cc.sys.OS_ANDROID){ jsb.reflection = new JavascriptJavaBridge(); cc.sys.capabilities["keyboard"] = true; } else if(window.JavaScriptObjCBridge && (cc.sys.os == cc.sys.OS_IOS || cc.sys.os == cc.sys.OS_OSX)){ jsb.reflection = new JavaScriptObjCBridge(); } }; _initSys(); /** * Init Debug setting. * @function */ cc._initDebugSetting = function (mode) { var ccGame = cc.game; var bakLog = cc._cocosplayerLog || cc.log || log; cc.log = cc.warn = cc.error = cc.assert = function(){}; if(mode == ccGame.DEBUG_MODE_NONE){ }else{ cc.error = function(){ bakLog.call(this, "ERROR : " + cc.formatStr.apply(cc, arguments)); }; cc.assert = function(cond, msg) { if (!cond && msg) { var args = []; for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); bakLog("Assert: " + cc.formatStr.apply(cc, args)); } }; if(mode != ccGame.DEBUG_MODE_ERROR && mode != ccGame.DEBUG_MODE_ERROR_FOR_WEB_PAGE){ cc.warn = function(){ bakLog.call(this, "WARN : " + cc.formatStr.apply(cc, arguments)); }; } if(mode == ccGame.DEBUG_MODE_INFO || mode == ccGame.DEBUG_MODE_INFO_FOR_WEB_PAGE){ cc.log = function(){ bakLog.call(this, cc.formatStr.apply(cc, arguments)); }; } } }; cc._engineLoaded = false; cc.initEngine = function (config, cb) { require("script/jsb.js"); cc._renderType = cc.game.RENDER_TYPE_OPENGL; cc._initDebugSetting(config[cc.game.CONFIG_KEY.debugMode]); cc._engineLoaded = true; cc.log(cc.ENGINE_VERSION); if (cb) cb(); }; //+++++++++++++++++++++++++something about CCGame begin+++++++++++++++++++++++++++ /** * An object to boot the game. * @class * @name cc.game */ cc.game = /** @lends cc.game# */{ DEBUG_MODE_NONE: 0, DEBUG_MODE_INFO: 1, DEBUG_MODE_WARN: 2, DEBUG_MODE_ERROR: 3, DEBUG_MODE_INFO_FOR_WEB_PAGE: 4, DEBUG_MODE_WARN_FOR_WEB_PAGE: 5, DEBUG_MODE_ERROR_FOR_WEB_PAGE: 6, EVENT_HIDE: "game_on_hide", EVENT_SHOW: "game_on_show", EVENT_RESIZE: "game_on_resize", RENDER_TYPE_CANVAS: 0, RENDER_TYPE_WEBGL: 1, RENDER_TYPE_OPENGL: 2, _eventHide: null, _eventShow: null, /** * Key of config * @constant * @type {Object} */ CONFIG_KEY: { width: "width", height: "height", engineDir: "engineDir", modules: "modules", debugMode: "debugMode", showFPS: "showFPS", frameRate: "frameRate", id: "id", renderMode: "renderMode", jsList: "jsList" }, // states _paused: false,//whether the game is paused _prepareCalled: false,//whether the prepare function has been called _prepared: false,//whether the engine has prepared _intervalId: null,//interval target of main /** * Config of game * @type {Object} */ config: null, /** * Callback when the scripts of engine have been load. * @type {Function} */ onStart: null, /** * Callback when game exits. * @type {Function} */ onStop: null, //@Public Methods // @Game play control /** * Set frameRate of game. * @param frameRate */ setFrameRate: function (frameRate) { var self = this, config = self.config, CONFIG_KEY = self.CONFIG_KEY; config[CONFIG_KEY.frameRate] = frameRate; cc.director.setAnimationInterval(1.0/frameRate); }, /** * Run the game frame by frame. */ step: function () { cc.director.mainLoop(); }, /** * Pause the game. */ pause: function () { this._paused = true; cc.director.pause(); }, /** * Resume the game from pause. */ resume: function () { this._paused = false; cc.director.resume(); }, /** * Check whether the game is paused. */ isPaused: function () { return this._paused; }, /** * Restart game. */ restart: function () { __restartVM(); }, /** * End game, it will close the game window */ end: function () { close(); }, // @Game loading /** * Prepare game. * @param cb */ prepare: function (cb) { var self = this, config = self.config, CONFIG_KEY = self.CONFIG_KEY; this._loadConfig(); // Already prepared if (this._prepared) { if (cb) cb(); return; } // Prepare called, but not done yet if (this._prepareCalled) { return; } // Prepare never called and engine ready if (cc._engineLoaded) { this._prepareCalled = true; // Load game scripts var jsList = config[CONFIG_KEY.jsList]; if (jsList) { cc.loader.loadJsWithImg(jsList, function (err) { if (err) throw new Error(err); self._prepared = true; if (cb) cb(); }); } else { if (cb) cb(); } return; } // Engine not loaded yet cc.initEngine(this.config, function () { self.prepare(cb); }); }, /** * Run game with configuration object and onStart function. * @param {Object|Function} [config] Pass configuration object or onStart function * @param {onStart} [onStart] onStart function to be executed after game initialized */ run: function (config, onStart) { if (typeof config === 'function') { cc.game.onStart = config; } else { if (config) { cc.game.config = config; } if (typeof onStart === 'function') { cc.game.onStart = onStart; } } this.prepare(cc.game.onStart && cc.game.onStart.bind(cc.game)); }, //@Private Methods _loadConfig: function () { // Load config // Already loaded if (this.config) { this._initConfig(this.config); } // Load from project.json else { try { var txt = jsb.fileUtils.getStringFromFile("project.json"); var data = JSON.parse(txt); this._initConfig(data || {}); } catch (e) { console.log("Failed to read or parse project.json"); this._initConfig({}); } } }, _initConfig: function (config) { var CONFIG_KEY = this.CONFIG_KEY; // Configs adjustment config[CONFIG_KEY.showFPS] = typeof config[CONFIG_KEY.showFPS] === 'undefined' ? true : config[CONFIG_KEY.showFPS]; config[CONFIG_KEY.engineDir] = config[CONFIG_KEY.engineDir] || "frameworks/cocos2d-html5"; if (config[CONFIG_KEY.debugMode] == null) config[CONFIG_KEY.debugMode] = 0; config[CONFIG_KEY.frameRate] = config[CONFIG_KEY.frameRate] || 60; if (config[CONFIG_KEY.renderMode] == null) config[CONFIG_KEY.renderMode] = 0; this.config = config; cc.director.setDisplayStats(this.config[CONFIG_KEY.showFPS]); cc.director.setAnimationInterval(1.0/this.config[CONFIG_KEY.frameRate]); } }; //+++++++++++++++++++++++++something about CCGame end+++++++++++++++++++++++++++++ jsb.urlRegExp = new RegExp( "^" + // protocol identifier "(?:(?:https?|ftp)://)" + // user:pass authentication "(?:\\S+(?::\\S*)?@)?" + "(?:" + // IP address dotted notation octets // excludes loopback network 0.0.0.0 // excludes reserved space >= 224.0.0.0 // excludes network & broacast addresses // (first & last IP address of each class) "(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])" + "(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}" + "(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))" + "|" + // host name "(?:(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)" + // domain name "(?:\\.(?:[a-z\\u00a1-\\uffff0-9]-*)*[a-z\\u00a1-\\uffff0-9]+)*" + // TLD identifier "(?:\\.(?:[a-z\\u00a1-\\uffff]{2,}))" + "|" + "(?:localhost)" + ")" + // port number "(?::\\d{2,5})?" + // resource path "(?:/\\S*)?" + "$", "i" );