CCBoot.js 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972
  1. /****************************************************************************
  2. Copyright (c) 2011-2012 cocos2d-x.org
  3. Copyright (c) 2013-2014 Chukong Technologies Inc.
  4. http://www.cocos2d-x.org
  5. Permission is hereby granted, free of charge, to any person obtaining a copy
  6. of this software and associated documentation files (the "Software"), to deal
  7. in the Software without restriction, including without limitation the rights
  8. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. copies of the Software, and to permit persons to whom the Software is
  10. furnished to do so, subject to the following conditions:
  11. The above copyright notice and this permission notice shall be included in
  12. all copies or substantial portions of the Software.
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. THE SOFTWARE.
  20. ****************************************************************************/
  21. var cc = cc || {};
  22. cc._tmp = cc._tmp || {};
  23. cc._LogInfos = {};
  24. /** @expose */
  25. window._p;
  26. _p = window;
  27. /** @expose */
  28. _p.gl;
  29. /** @expose */
  30. _p.WebGLRenderingContext;
  31. /** @expose */
  32. _p.DeviceOrientationEvent;
  33. /** @expose */
  34. _p.DeviceMotionEvent;
  35. /** @expose */
  36. _p.AudioContext;
  37. /** @expose */
  38. _p.webkitAudioContext;
  39. /** @expose */
  40. _p.mozAudioContext;
  41. _p = Object.prototype;
  42. /** @expose */
  43. _p._super;
  44. /** @expose */
  45. _p.ctor;
  46. delete window._p;
  47. cc.newElement = function (x) {
  48. return document.createElement(x);
  49. };
  50. cc._addEventListener = function (element, type, listener, useCapture) {
  51. element.addEventListener(type, listener, useCapture);
  52. };
  53. //is nodejs ? Used to support node-webkit.
  54. cc._isNodeJs = typeof require !== 'undefined' && require("fs");
  55. /**
  56. * Iterate over an object or an array, executing a function for each matched element.
  57. * @param {object|array} obj
  58. * @param {function} iterator
  59. * @param {object} [context]
  60. */
  61. cc.each = function (obj, iterator, context) {
  62. if (!obj)
  63. return;
  64. if (obj instanceof Array) {
  65. for (var i = 0, li = obj.length; i < li; i++) {
  66. if (iterator.call(context, obj[i], i) === false)
  67. return;
  68. }
  69. } else {
  70. for (var key in obj) {
  71. if (iterator.call(context, obj[key], key) === false)
  72. return;
  73. }
  74. }
  75. };
  76. /**
  77. * Check the url whether cross origin
  78. * @param {String} url
  79. * @returns {boolean}
  80. */
  81. cc.isCrossOrigin = function (url) {
  82. if (!url) {
  83. cc.log("invalid URL");
  84. return false;
  85. }
  86. var startIndex = url.indexOf("://");
  87. if (startIndex == -1)
  88. return false;
  89. var endIndex = url.indexOf("/", startIndex + 3);
  90. var urlOrigin = (endIndex == -1) ? url : url.substring(0, endIndex);
  91. return urlOrigin != location.origin;
  92. };
  93. //+++++++++++++++++++++++++something about async begin+++++++++++++++++++++++++++++++
  94. /**
  95. * Async Pool class, a helper of cc.async
  96. * @param {Object|Array} srcObj
  97. * @param {Number} limit the limit of parallel number
  98. * @param {function} iterator
  99. * @param {function} onEnd
  100. * @param {object} target
  101. * @constructor
  102. */
  103. cc.AsyncPool = function(srcObj, limit, iterator, onEnd, target){
  104. var self = this;
  105. self._srcObj = srcObj;
  106. self._limit = limit;
  107. self._pool = [];
  108. self._iterator = iterator;
  109. self._iteratorTarget = target;
  110. self._onEnd = onEnd;
  111. self._onEndTarget = target;
  112. self._results = srcObj instanceof Array ? [] : {};
  113. self._isErr = false;
  114. cc.each(srcObj, function(value, index){
  115. self._pool.push({index : index, value : value});
  116. });
  117. self.size = self._pool.length;
  118. self.finishedSize = 0;
  119. self._workingSize = 0;
  120. self._limit = self._limit || self.size;
  121. self.onIterator = function(iterator, target){
  122. self._iterator = iterator;
  123. self._iteratorTarget = target;
  124. };
  125. self.onEnd = function(endCb, endCbTarget){
  126. self._onEnd = endCb;
  127. self._onEndTarget = endCbTarget;
  128. };
  129. self._handleItem = function(){
  130. var self = this;
  131. if(self._pool.length == 0)
  132. return; //return directly if the array's length = 0
  133. if(self._workingSize >= self._limit)
  134. return; //return directly if the working size great equal limit number
  135. var item = self._pool.shift();
  136. var value = item.value, index = item.index;
  137. self._workingSize++;
  138. self._iterator.call(self._iteratorTarget, value, index, function(err){
  139. if(self._isErr)
  140. return;
  141. self.finishedSize++;
  142. self._workingSize--;
  143. if(err) {
  144. self._isErr = true;
  145. if(self._onEnd)
  146. self._onEnd.call(self._onEndTarget, err);
  147. return
  148. }
  149. var arr = Array.prototype.slice.call(arguments, 1);
  150. self._results[this.index] = arr[0];
  151. if(self.finishedSize == self.size) {
  152. if(self._onEnd)
  153. self._onEnd.call(self._onEndTarget, null, self._results);
  154. return
  155. }
  156. self._handleItem();
  157. }.bind(item), self);
  158. };
  159. self.flow = function(){
  160. var self = this;
  161. if(self._pool.length == 0) {
  162. if(self._onEnd)
  163. self._onEnd.call(self._onEndTarget, null, []);
  164. return;
  165. }
  166. for(var i = 0; i < self._limit; i++)
  167. self._handleItem();
  168. }
  169. };
  170. cc.async = {
  171. /**
  172. * Do tasks series.
  173. * @param {Array|Object} tasks
  174. * @param {function} [cb] callback
  175. * @param {Object} [target]
  176. * @return {cc.AsyncPool}
  177. */
  178. series : function(tasks, cb, target){
  179. var asyncPool = new cc.AsyncPool(tasks, 1, function(func, index, cb1){
  180. func.call(target, cb1);
  181. }, cb, target);
  182. asyncPool.flow();
  183. return asyncPool;
  184. },
  185. /**
  186. * Do tasks parallel.
  187. * @param {Array|Object} tasks
  188. * @param {function} cb callback
  189. * @param {Object} [target]
  190. * @return {cc.AsyncPool}
  191. */
  192. parallel : function(tasks, cb, target){
  193. var asyncPool = new cc.AsyncPool(tasks, 0, function(func, index, cb1){
  194. func.call(target, cb1);
  195. }, cb, target);
  196. asyncPool.flow();
  197. return asyncPool;
  198. },
  199. /**
  200. * Do tasks waterfall.
  201. * @param {Array|Object} tasks
  202. * @param {function} cb callback
  203. * @param {Object} [target]
  204. * @return {cc.AsyncPool}
  205. */
  206. waterfall : function(tasks, cb, target){
  207. var args = [];
  208. var asyncPool = new cc.AsyncPool(tasks, 1,
  209. function (func, index, cb1) {
  210. args.push(function (err) {
  211. args = Array.prototype.slice.call(arguments, 1);
  212. cb1.apply(null, arguments);
  213. });
  214. func.apply(target, args);
  215. }, function (err, results) {
  216. if (!cb)
  217. return;
  218. if (err)
  219. return cb.call(target, err);
  220. cb.call(target, null, results[results.length - 1]);
  221. });
  222. asyncPool.flow();
  223. return asyncPool;
  224. },
  225. /**
  226. * Do tasks by iterator.
  227. * @param {Array|Object} tasks
  228. * @param {function|Object} iterator
  229. * @param {function} cb callback
  230. * @param {Object} [target]
  231. * @return {cc.AsyncPool}
  232. */
  233. map : function(tasks, iterator, cb, target){
  234. var locIterator = iterator;
  235. if(typeof(iterator) == "object"){
  236. cb = iterator.cb;
  237. target = iterator.iteratorTarget;
  238. locIterator = iterator.iterator;
  239. }
  240. var asyncPool = new cc.AsyncPool(tasks, 0, locIterator, cb, target);
  241. asyncPool.flow();
  242. return asyncPool;
  243. },
  244. /**
  245. * Do tasks by iterator limit.
  246. * @param {Array|Object} tasks
  247. * @param {Number} limit
  248. * @param {function} iterator
  249. * @param {function} cb callback
  250. * @param {Object} [target]
  251. */
  252. mapLimit : function(tasks, limit, iterator, cb, target){
  253. var asyncPool = new cc.AsyncPool(tasks, limit, iterator, cb, target);
  254. asyncPool.flow();
  255. return asyncPool;
  256. }
  257. };
  258. //+++++++++++++++++++++++++something about async end+++++++++++++++++++++++++++++++++
  259. //+++++++++++++++++++++++++something about path begin++++++++++++++++++++++++++++++++
  260. cc.path = {
  261. /**
  262. * Join strings to be a path.
  263. * @example
  264. cc.path.join("a", "b.png");//-->"a/b.png"
  265. cc.path.join("a", "b", "c.png");//-->"a/b/c.png"
  266. cc.path.join("a", "b");//-->"a/b"
  267. cc.path.join("a", "b", "/");//-->"a/b/"
  268. cc.path.join("a", "b/", "/");//-->"a/b/"
  269. * @returns {string}
  270. */
  271. join: function () {
  272. var l = arguments.length;
  273. var result = "";
  274. for (var i = 0; i < l; i++) {
  275. result = (result + (result == "" ? "" : "/") + arguments[i]).replace(/(\/|\\\\)$/, "");
  276. }
  277. return result;
  278. },
  279. /**
  280. * Get the ext name of a path.
  281. * @example
  282. cc.path.extname("a/b.png");//-->".png"
  283. cc.path.extname("a/b.png?a=1&b=2");//-->".png"
  284. cc.path.extname("a/b");//-->null
  285. cc.path.extname("a/b?a=1&b=2");//-->null
  286. * @param {string} pathStr
  287. * @returns {*}
  288. */
  289. extname: function (pathStr) {
  290. var temp = /(\.[^\.\/\?\\]*)(\?.*)?$/.exec(pathStr);
  291. return temp ? temp[1] : null;
  292. },
  293. /**
  294. * Get the main name of a file name
  295. * @param {string} fileName
  296. * @returns {string}
  297. */
  298. mainFileName: function(fileName){
  299. if(fileName){
  300. var idx = fileName.lastIndexOf(".");
  301. if(idx !== -1)
  302. return fileName.substring(0,idx);
  303. }
  304. return fileName
  305. },
  306. /**
  307. * Get the file name of a file path.
  308. * @example
  309. cc.path.basename("a/b.png");//-->"b.png"
  310. cc.path.basename("a/b.png?a=1&b=2");//-->"b.png"
  311. cc.path.basename("a/b.png", ".png");//-->"b"
  312. cc.path.basename("a/b.png?a=1&b=2", ".png");//-->"b"
  313. cc.path.basename("a/b.png", ".txt");//-->"b.png"
  314. * @param {string} pathStr
  315. * @param {string} [extname]
  316. * @returns {*}
  317. */
  318. basename: function (pathStr, extname) {
  319. var index = pathStr.indexOf("?");
  320. if (index > 0) pathStr = pathStr.substring(0, index);
  321. var reg = /(\/|\\\\)([^(\/|\\\\)]+)$/g;
  322. var result = reg.exec(pathStr.replace(/(\/|\\\\)$/, ""));
  323. if (!result) return null;
  324. var baseName = result[2];
  325. if (extname && pathStr.substring(pathStr.length - extname.length).toLowerCase() == extname.toLowerCase())
  326. return baseName.substring(0, baseName.length - extname.length);
  327. return baseName;
  328. },
  329. /**
  330. * Get dirname of a file path.
  331. * @example
  332. * unix
  333. cc.path.driname("a/b/c.png");//-->"a/b"
  334. cc.path.driname("a/b/c.png?a=1&b=2");//-->"a/b"
  335. cc.path.dirname("a/b/");//-->"a/b"
  336. cc.path.dirname("c.png");//-->""
  337. * windows
  338. cc.path.driname("a\\b\\c.png");//-->"a\b"
  339. cc.path.driname("a\\b\\c.png?a=1&b=2");//-->"a\b"
  340. * @param {string} pathStr
  341. * @returns {*}
  342. */
  343. dirname: function (pathStr) {
  344. return pathStr.replace(/((.*)(\/|\\|\\\\))?(.*?\..*$)?/, '$2');
  345. },
  346. /**
  347. * Change extname of a file path.
  348. * @example
  349. cc.path.changeExtname("a/b.png", ".plist");//-->"a/b.plist"
  350. cc.path.changeExtname("a/b.png?a=1&b=2", ".plist");//-->"a/b.plist?a=1&b=2"
  351. * @param {string} pathStr
  352. * @param {string} [extname]
  353. * @returns {string}
  354. */
  355. changeExtname: function (pathStr, extname) {
  356. extname = extname || "";
  357. var index = pathStr.indexOf("?");
  358. var tempStr = "";
  359. if (index > 0) {
  360. tempStr = pathStr.substring(index);
  361. pathStr = pathStr.substring(0, index);
  362. }
  363. index = pathStr.lastIndexOf(".");
  364. if (index < 0) return pathStr + extname + tempStr;
  365. return pathStr.substring(0, index) + extname + tempStr;
  366. },
  367. /**
  368. * Change file name of a file path.
  369. * @example
  370. cc.path.changeBasename("a/b/c.plist", "b.plist");//-->"a/b/b.plist"
  371. cc.path.changeBasename("a/b/c.plist?a=1&b=2", "b.plist");//-->"a/b/b.plist?a=1&b=2"
  372. cc.path.changeBasename("a/b/c.plist", ".png");//-->"a/b/c.png"
  373. cc.path.changeBasename("a/b/c.plist", "b");//-->"a/b/b"
  374. cc.path.changeBasename("a/b/c.plist", "b", true);//-->"a/b/b.plist"
  375. * @param {String} pathStr
  376. * @param {String} basename
  377. * @param {Boolean} [isSameExt]
  378. * @returns {string}
  379. */
  380. changeBasename: function (pathStr, basename, isSameExt) {
  381. if (basename.indexOf(".") == 0) return this.changeExtname(pathStr, basename);
  382. var index = pathStr.indexOf("?");
  383. var tempStr = "";
  384. var ext = isSameExt ? this.extname(pathStr) : "";
  385. if (index > 0) {
  386. tempStr = pathStr.substring(index);
  387. pathStr = pathStr.substring(0, index);
  388. }
  389. index = pathStr.lastIndexOf("/");
  390. index = index <= 0 ? 0 : index + 1;
  391. return pathStr.substring(0, index) + basename + ext + tempStr;
  392. }
  393. };
  394. //+++++++++++++++++++++++++something about path end++++++++++++++++++++++++++++++++
  395. //+++++++++++++++++++++++++something about loader start+++++++++++++++++++++++++++
  396. cc.loader = {
  397. _jsCache: {},//cache for js
  398. _register: {},//register of loaders
  399. _langPathCache: {},//cache for lang path
  400. _aliases: {},//aliases for res url
  401. resPath: "",//root path of resource
  402. audioPath: "",//root path of audio
  403. cache: {},//cache for data loaded
  404. /**
  405. * Get XMLHttpRequest.
  406. * @returns {XMLHttpRequest}
  407. */
  408. getXMLHttpRequest: function () {
  409. return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP");
  410. },
  411. //@MODE_BEGIN DEV
  412. _getArgs4Js: function (args) {
  413. var a0 = args[0], a1 = args[1], a2 = args[2], results = ["", null, null];
  414. if (args.length === 1) {
  415. results[1] = a0 instanceof Array ? a0 : [a0];
  416. } else if (args.length === 2) {
  417. if (typeof a1 == "function") {
  418. results[1] = a0 instanceof Array ? a0 : [a0];
  419. results[2] = a1;
  420. } else {
  421. results[0] = a0 || "";
  422. results[1] = a1 instanceof Array ? a1 : [a1];
  423. }
  424. } else if (args.length === 3) {
  425. results[0] = a0 || "";
  426. results[1] = a1 instanceof Array ? a1 : [a1];
  427. results[2] = a2;
  428. } else throw "arguments error to load js!";
  429. return results;
  430. },
  431. /**
  432. * Load js files.
  433. * If the third parameter doesn't exist, then the baseDir turns to be "".
  434. *
  435. * @param {string} [baseDir] The pre path for jsList or the list of js path.
  436. * @param {array} jsList List of js path.
  437. * @param {function} [cb] Callback function
  438. * @returns {*}
  439. */
  440. loadJs: function (baseDir, jsList, cb) {
  441. var self = this, localJsCache = self._jsCache,
  442. args = self._getArgs4Js(arguments);
  443. var preDir = args[0], list = args[1], callback = args[2];
  444. if (navigator.userAgent.indexOf("Trident/5") > -1) {
  445. self._loadJs4Dependency(preDir, list, 0, callback);
  446. } else {
  447. cc.async.map(list, function (item, index, cb1) {
  448. var jsPath = cc.path.join(preDir, item);
  449. if (localJsCache[jsPath]) return cb1(null);
  450. self._createScript(jsPath, false, cb1);
  451. }, callback);
  452. }
  453. },
  454. /**
  455. * Load js width loading image.
  456. *
  457. * @param {string} [baseDir]
  458. * @param {array} jsList
  459. * @param {function} [cb]
  460. */
  461. loadJsWithImg: function (baseDir, jsList, cb) {
  462. var self = this, jsLoadingImg = self._loadJsImg(),
  463. args = self._getArgs4Js(arguments);
  464. this.loadJs(args[0], args[1], function (err) {
  465. if (err) throw err;
  466. jsLoadingImg.parentNode.removeChild(jsLoadingImg);//remove loading gif
  467. if (args[2]) args[2]();
  468. });
  469. },
  470. _createScript: function (jsPath, isAsync, cb) {
  471. var d = document, self = this, s = cc.newElement('script');
  472. s.async = isAsync;
  473. s.src = jsPath;
  474. self._jsCache[jsPath] = true;
  475. cc._addEventListener(s, 'load', function () {
  476. s.parentNode.removeChild(s);
  477. this.removeEventListener('load', arguments.callee, false);
  478. cb();
  479. }, false);
  480. cc._addEventListener(s, 'error', function () {
  481. s.parentNode.removeChild(s);
  482. cb("Load " + jsPath + " failed!");
  483. }, false);
  484. d.body.appendChild(s);
  485. },
  486. _loadJs4Dependency: function (baseDir, jsList, index, cb) {
  487. if (index >= jsList.length) {
  488. if (cb) cb();
  489. return;
  490. }
  491. var self = this;
  492. self._createScript(cc.path.join(baseDir, jsList[index]), false, function (err) {
  493. if (err) return cb(err);
  494. self._loadJs4Dependency(baseDir, jsList, index + 1, cb);
  495. });
  496. },
  497. _loadJsImg: function () {
  498. var d = document, jsLoadingImg = d.getElementById("cocos2d_loadJsImg");
  499. if (!jsLoadingImg) {
  500. jsLoadingImg = cc.newElement('img');
  501. if (cc._loadingImage)
  502. jsLoadingImg.src = cc._loadingImage;
  503. var canvasNode = d.getElementById(cc.game.config["id"]);
  504. canvasNode.style.backgroundColor = "black";
  505. canvasNode.parentNode.appendChild(jsLoadingImg);
  506. var canvasStyle = getComputedStyle ? getComputedStyle(canvasNode) : canvasNode.currentStyle;
  507. if (!canvasStyle)
  508. canvasStyle = {width: canvasNode.width, height: canvasNode.height};
  509. jsLoadingImg.style.left = canvasNode.offsetLeft + (parseFloat(canvasStyle.width) - jsLoadingImg.width) / 2 + "px";
  510. jsLoadingImg.style.top = canvasNode.offsetTop + (parseFloat(canvasStyle.height) - jsLoadingImg.height) / 2 + "px";
  511. jsLoadingImg.style.position = "absolute";
  512. }
  513. return jsLoadingImg;
  514. },
  515. //@MODE_END DEV
  516. /**
  517. * Load a single resource as txt.
  518. * @param {string} url
  519. * @param {function} [cb] arguments are : err, txt
  520. */
  521. loadTxt: function (url, cb) {
  522. if (!cc._isNodeJs) {
  523. var xhr = this.getXMLHttpRequest(),
  524. errInfo = "load " + url + " failed!";
  525. xhr.open("GET", url, true);
  526. if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
  527. // IE-specific logic here
  528. xhr.setRequestHeader("Accept-Charset", "utf-8");
  529. xhr.onreadystatechange = function () {
  530. if(xhr.readyState == 4)
  531. xhr.status == 200 ? cb(null, xhr.responseText) : cb(errInfo);
  532. };
  533. } else {
  534. if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=utf-8");
  535. xhr.onload = function () {
  536. if(xhr.readyState == 4)
  537. xhr.status == 200 ? cb(null, xhr.responseText) : cb(errInfo);
  538. };
  539. }
  540. xhr.send(null);
  541. } else {
  542. var fs = require("fs");
  543. fs.readFile(url, function (err, data) {
  544. err ? cb(err) : cb(null, data.toString());
  545. });
  546. }
  547. },
  548. _loadTxtSync: function (url) {
  549. if (!cc._isNodeJs) {
  550. var xhr = this.getXMLHttpRequest();
  551. xhr.open("GET", url, false);
  552. if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
  553. // IE-specific logic here
  554. xhr.setRequestHeader("Accept-Charset", "utf-8");
  555. } else {
  556. if (xhr.overrideMimeType) xhr.overrideMimeType("text\/plain; charset=utf-8");
  557. }
  558. xhr.send(null);
  559. if (!xhr.readyState == 4 || xhr.status != 200) {
  560. return null;
  561. }
  562. return xhr.responseText;
  563. } else {
  564. var fs = require("fs");
  565. return fs.readFileSync(url).toString();
  566. }
  567. },
  568. /**
  569. * Load a single resource as json.
  570. * @param {string} url
  571. * @param {function} [cb] arguments are : err, json
  572. */
  573. loadJson: function (url, cb) {
  574. this.loadTxt(url, function (err, txt) {
  575. try {
  576. err ? cb(err) : cb(null, JSON.parse(txt));
  577. } catch (e) {
  578. throw "load json [" + url + "] failed : " + e;
  579. }
  580. });
  581. },
  582. _checkIsImageURL: function (url) {
  583. var ext = /(\.png)|(\.jpg)|(\.bmp)|(\.jpeg)|(\.gif)/.exec(url);
  584. return (ext != null);
  585. },
  586. /**
  587. * Load a single image.
  588. * @param {!string} url
  589. * @param {object} [option]
  590. * @param {function} cb
  591. * @returns {Image}
  592. */
  593. loadImg: function (url, option, cb) {
  594. var opt = {
  595. isCrossOrigin: true
  596. };
  597. if (cb !== undefined)
  598. opt.isCrossOrigin = option.isCrossOrigin == null ? opt.isCrossOrigin : option.isCrossOrigin;
  599. else if (option !== undefined)
  600. cb = option;
  601. var img = new Image();
  602. if (opt.isCrossOrigin && location.origin != "file://")
  603. img.crossOrigin = "Anonymous";
  604. cc._addEventListener(img, "load", function () {
  605. this.removeEventListener('load', arguments.callee, false);
  606. this.removeEventListener('error', arguments.callee, false);
  607. if (cb)
  608. cb(null, img);
  609. });
  610. cc._addEventListener(img, "error", function () {
  611. this.removeEventListener('error', arguments.callee, false);
  612. if (cb)
  613. cb("load image failed");
  614. });
  615. img.src = url;
  616. return img;
  617. },
  618. /**
  619. * Iterator function to load res
  620. * @param {object} item
  621. * @param {number} index
  622. * @param {function} [cb]
  623. * @returns {*}
  624. * @private
  625. */
  626. _loadResIterator: function (item, index, cb) {
  627. var self = this, url = null;
  628. var type = item.type;
  629. if (type) {
  630. type = "." + type.toLowerCase();
  631. url = item.src ? item.src : item.name + type;
  632. } else {
  633. url = item;
  634. type = cc.path.extname(url);
  635. }
  636. var obj = self.cache[url];
  637. if (obj)
  638. return cb(null, obj);
  639. var loader = self._register[type.toLowerCase()];
  640. if (!loader) {
  641. cc.error("loader for [" + type + "] not exists!");
  642. return cb();
  643. }
  644. var basePath = loader.getBasePath ? loader.getBasePath() : self.resPath;
  645. var realUrl = self.getUrl(basePath, url);
  646. loader.load(realUrl, url, item, function (err, data) {
  647. if (err) {
  648. cc.log(err);
  649. self.cache[url] = null;
  650. delete self.cache[url];
  651. cb();
  652. } else {
  653. self.cache[url] = data;
  654. cb(null, data);
  655. }
  656. });
  657. },
  658. /**
  659. * Get url with basePath.
  660. * @param {string} basePath
  661. * @param {string} [url]
  662. * @returns {*}
  663. */
  664. getUrl: function (basePath, url) {
  665. var self = this, langPathCache = self._langPathCache, path = cc.path;
  666. if (basePath !== undefined && url === undefined) {
  667. url = basePath;
  668. var type = path.extname(url);
  669. type = type ? type.toLowerCase() : "";
  670. var loader = self._register[type];
  671. if (!loader)
  672. basePath = self.resPath;
  673. else
  674. basePath = loader.getBasePath ? loader.getBasePath() : self.resPath;
  675. }
  676. url = cc.path.join(basePath || "", url);
  677. if (url.match(/[\/(\\\\)]lang[\/(\\\\)]/i)) {
  678. if (langPathCache[url])
  679. return langPathCache[url];
  680. var extname = path.extname(url) || "";
  681. url = langPathCache[url] = url.substring(0, url.length - extname.length) + "_" + cc.sys.language + extname;
  682. }
  683. return url;
  684. },
  685. /**
  686. * Load resources then call the callback.
  687. * @param {string} resources
  688. * @param {function|Object} [option] option or cb
  689. * @param {function} [cb]
  690. * @return {cc.AsyncPool}
  691. */
  692. load : function(resources, option, cb){
  693. var self = this;
  694. var len = arguments.length;
  695. if(len == 0)
  696. throw "arguments error!";
  697. if(len == 3){
  698. if(typeof option == "function"){
  699. if(typeof cb == "function")
  700. option = {trigger : option, cb : cb };
  701. else
  702. option = { cb : option, cbTarget : cb};
  703. }
  704. }else if(len == 2){
  705. if(typeof option == "function")
  706. option = {cb : option};
  707. }else if(len == 1){
  708. option = {};
  709. }
  710. if(!(resources instanceof Array))
  711. resources = [resources];
  712. var asyncPool = new cc.AsyncPool(resources, 0, function(value, index, cb1, aPool){
  713. self._loadResIterator(value, index, function(err){
  714. if(err)
  715. return cb1(err);
  716. var arr = Array.prototype.slice.call(arguments, 1);
  717. if(option.trigger)
  718. option.trigger.call(option.triggerTarget, arr[0], aPool.size, aPool.finishedSize); //call trigger
  719. cb1(null, arr[0]);
  720. });
  721. }, option.cb, option.cbTarget);
  722. asyncPool.flow();
  723. return asyncPool;
  724. },
  725. _handleAliases: function (fileNames, cb) {
  726. var self = this, aliases = self._aliases;
  727. var resList = [];
  728. for (var key in fileNames) {
  729. var value = fileNames[key];
  730. aliases[key] = value;
  731. resList.push(value);
  732. }
  733. this.load(resList, cb);
  734. },
  735. /**
  736. * <p>
  737. * Loads alias map from the contents of a filename. <br/>
  738. * <br/>
  739. * @note The plist file name should follow the format below: <br/>
  740. * <?xml version="1.0" encoding="UTF-8"?> <br/>
  741. * <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <br/>
  742. * <plist version="1.0"> <br/>
  743. * <dict> <br/>
  744. * <key>filenames</key> <br/>
  745. * <dict> <br/>
  746. * <key>sounds/click.wav</key> <br/>
  747. * <string>sounds/click.caf</string> <br/>
  748. * <key>sounds/endgame.wav</key> <br/>
  749. * <string>sounds/endgame.caf</string> <br/>
  750. * <key>sounds/gem-0.wav</key> <br/>
  751. * <string>sounds/gem-0.caf</string> <br/>
  752. * </dict> <br/>
  753. * <key>metadata</key> <br/>
  754. * <dict> <br/>
  755. * <key>version</key> <br/>
  756. * <integer>1</integer> <br/>
  757. * </dict> <br/>
  758. * </dict> <br/>
  759. * </plist> <br/>
  760. * </p>
  761. * @param {String} url The plist file name.
  762. * @param {Function} [cb] callback
  763. */
  764. loadAliases: function (url, cb) {
  765. var self = this, dict = self.getRes(url);
  766. if (!dict) {
  767. self.load(url, function (err, results) {
  768. self._handleAliases(results[0]["filenames"], cb);
  769. });
  770. } else
  771. self._handleAliases(dict["filenames"], cb);
  772. },
  773. /**
  774. * Register a resource loader into loader.
  775. * @param {string} extNames
  776. * @param {function} loader
  777. */
  778. register: function (extNames, loader) {
  779. if (!extNames || !loader) return;
  780. var self = this;
  781. if (typeof extNames == "string")
  782. return this._register[extNames.trim().toLowerCase()] = loader;
  783. for (var i = 0, li = extNames.length; i < li; i++) {
  784. self._register["." + extNames[i].trim().toLowerCase()] = loader;
  785. }
  786. },
  787. /**
  788. * Get resource data by url.
  789. * @param url
  790. * @returns {*}
  791. */
  792. getRes: function (url) {
  793. return this.cache[url] || this.cache[this._aliases[url]];
  794. },
  795. /**
  796. * Release the cache of resource by url.
  797. * @param url
  798. */
  799. release: function (url) {
  800. var cache = this.cache, aliases = this._aliases;
  801. delete cache[url];
  802. delete cache[aliases[url]];
  803. delete aliases[url];
  804. },
  805. /**
  806. * Resource cache of all resources.
  807. */
  808. releaseAll: function () {
  809. var locCache = this.cache, aliases = this._aliases;
  810. for (var key in locCache)
  811. delete locCache[key];
  812. for (var key in aliases)
  813. delete aliases[key];
  814. }
  815. };
  816. //+++++++++++++++++++++++++something about loader end+++++++++++++++++++++++++++++
  817. /**
  818. * A string tool to construct a string with format string.
  819. * for example:
  820. * cc.formatStr("a: %d, b: %b", a, b);
  821. * cc.formatStr(a, b, c);
  822. * @returns {String}
  823. */
  824. cc.formatStr = function(){
  825. var args = arguments;
  826. var l = args.length;
  827. if(l < 1)
  828. return "";
  829. var str = args[0];
  830. var needToFormat = true;
  831. if(typeof str == "object"){
  832. str = JSON.stringify(str);
  833. needToFormat = false;
  834. }
  835. for(var i = 1; i < l; ++i){
  836. var arg = args[i];
  837. arg = typeof arg == "object" ? JSON.stringify(arg) : arg;
  838. if(needToFormat){
  839. while(true){
  840. var result = null;
  841. if(typeof arg == "number"){
  842. result = str.match(/(%d)|(%s)/);
  843. if(result){
  844. str = str.replace(/(%d)|(%s)/, arg);
  845. break;
  846. }
  847. }
  848. result = str.match(/%s/);
  849. if(result)
  850. str = str.replace(/%s/, arg);
  851. else
  852. str += " " + arg;
  853. break;
  854. }
  855. }else
  856. str += " " + arg;
  857. }
  858. return str;
  859. };
  860. //+++++++++++++++++++++++++something about window events begin+++++++++++++++++++++++++++
  861. (function () {
  862. var win = window, hidden, visibilityChange, _undef = "undefined";
  863. if (typeof document.hidden !== _undef) {
  864. hidden = "hidden";
  865. visibilityChange = "visibilitychange";
  866. } else if (typeof document.mozHidden !== _undef) {
  867. hidden = "mozHidden";
  868. visibilityChange = "mozvisibilitychange";
  869. } else if (typeof document.msHidden !== _undef) {
  870. hidden = "msHidden";
  871. visibilityChange = "msvisibilitychange";
  872. } else if (typeof document.webkitHidden !== _undef) {
  873. hidden = "webkitHidden";
  874. visibilityChange = "webkitvisibilitychange";
  875. }
  876. var onHidden = function () {
  877. if (cc.eventManager && cc.game._eventHide)
  878. cc.eventManager.dispatchEvent(cc.game._eventHide);
  879. };
  880. var onShow = function () {
  881. if (cc.eventManager && cc.game._eventShow)
  882. cc.eventManager.dispatchEvent(cc.game._eventShow);
  883. if(cc.game._intervalId){
  884. window.cancelAnimationFrame(cc.game._intervalId);
  885. cc.game._runMainLoop();
  886. }
  887. };
  888. if (hidden) {
  889. cc._addEventListener(document, visibilityChange, function () {
  890. if (document[hidden]) onHidden();
  891. else onShow();
  892. }, false);
  893. } else {
  894. cc._addEventListener(win, "blur", onHidden, false);
  895. cc._addEventListener(win, "focus", onShow, false);
  896. }
  897. if(navigator.userAgent.indexOf("MicroMessenger") > -1){
  898. win.onfocus = function(){ onShow() };
  899. }
  900. if ("onpageshow" in window && "onpagehide" in window) {
  901. cc._addEventListener(win, "pagehide", onHidden, false);
  902. cc._addEventListener(win, "pageshow", onShow, false);
  903. }
  904. win = null;
  905. visibilityChange = null;
  906. })();
  907. //+++++++++++++++++++++++++something about window events end+++++++++++++++++++++++++++++
  908. //+++++++++++++++++++++++++something about log start++++++++++++++++++++++++++++
  909. //to make sure the cc.log, cc.warn, cc.error and cc.assert would not throw error before init by debugger mode.
  910. cc.log = cc.warn = cc.error = cc.assert = function () {
  911. };
  912. //+++++++++++++++++++++++++something about log end+++++++++++++++++++++++++++++
  913. /**
  914. * create a webgl context
  915. * @param {HTMLCanvasElement} canvas
  916. * @param {Object} opt_attribs
  917. * @return {WebGLRenderingContext}
  918. */
  919. cc.create3DContext = function (canvas, opt_attribs) {
  920. var names = ["webgl", "experimental-webgl", "webkit-3d", "moz-webgl"];
  921. var context = null;
  922. for (var ii = 0; ii < names.length; ++ii) {
  923. try {
  924. context = canvas.getContext(names[ii], opt_attribs);
  925. } catch (e) {
  926. }
  927. if (context) {
  928. break;
  929. }
  930. }
  931. return context;
  932. };
  933. //+++++++++++++++++++++++++something about sys begin+++++++++++++++++++++++++++++
  934. cc._initSys = function (config, CONFIG_KEY) {
  935. /**
  936. * Canvas of render type
  937. * @constant
  938. * @type {Number}
  939. */
  940. cc._RENDER_TYPE_CANVAS = 0;
  941. /**
  942. * WebGL of render type
  943. * @constant
  944. * @type {Number}
  945. */
  946. cc._RENDER_TYPE_WEBGL = 1;
  947. /**
  948. * System variables
  949. * @memberof cc
  950. * @global
  951. * @type {Object}
  952. * @name cc.sys
  953. */
  954. cc.sys = {};
  955. var sys = cc.sys;
  956. /**
  957. * English language code
  958. * @memberof cc.sys
  959. * @constant
  960. * @type {Number}
  961. */
  962. sys.LANGUAGE_ENGLISH = "en";
  963. /**
  964. * Chinese language code
  965. * @memberof cc.sys
  966. * @constant
  967. * @type {Number}
  968. */
  969. sys.LANGUAGE_CHINESE = "zh";
  970. /**
  971. * French language code
  972. * @memberof cc.sys
  973. * @constant
  974. * @type {Number}
  975. */
  976. sys.LANGUAGE_FRENCH = "fr";
  977. /**
  978. * Italian language code
  979. * @memberof cc.sys
  980. * @constant
  981. * @type {Number}
  982. */
  983. sys.LANGUAGE_ITALIAN = "it";
  984. /**
  985. * German language code
  986. * @memberof cc.sys
  987. * @constant
  988. * @type {Number}
  989. */
  990. sys.LANGUAGE_GERMAN = "de";
  991. /**
  992. * Spanish language code
  993. * @memberof cc.sys
  994. * @constant
  995. * @type {Number}
  996. */
  997. sys.LANGUAGE_SPANISH = "es";
  998. /**
  999. * Russian language code
  1000. * @memberof cc.sys
  1001. * @constant
  1002. * @type {Number}
  1003. */
  1004. sys.LANGUAGE_RUSSIAN = "ru";
  1005. /**
  1006. * Korean language code
  1007. * @memberof cc.sys
  1008. * @constant
  1009. * @type {Number}
  1010. */
  1011. sys.LANGUAGE_KOREAN = "ko";
  1012. /**
  1013. * Japanese language code
  1014. * @memberof cc.sys
  1015. * @constant
  1016. * @type {Number}
  1017. */
  1018. sys.LANGUAGE_JAPANESE = "ja";
  1019. /**
  1020. * Hungarian language code
  1021. * @memberof cc.sys
  1022. * @constant
  1023. * @type {Number}
  1024. */
  1025. sys.LANGUAGE_HUNGARIAN = "hu";
  1026. /**
  1027. * Portuguese language code
  1028. * @memberof cc.sys
  1029. * @constant
  1030. * @type {Number}
  1031. */
  1032. sys.LANGUAGE_PORTUGUESE = "pt";
  1033. /**
  1034. * Arabic language code
  1035. * @memberof cc.sys
  1036. * @constant
  1037. * @type {Number}
  1038. */
  1039. sys.LANGUAGE_ARABIC = "ar";
  1040. /**
  1041. * Norwegian language code
  1042. * @memberof cc.sys
  1043. * @constant
  1044. * @type {Number}
  1045. */
  1046. sys.LANGUAGE_NORWEGIAN = "no";
  1047. /**
  1048. * Polish language code
  1049. * @memberof cc.sys
  1050. * @constant
  1051. * @type {Number}
  1052. */
  1053. sys.LANGUAGE_POLISH = "pl";
  1054. /**
  1055. * @memberof cc.sys
  1056. * @constant
  1057. * @type {string}
  1058. */
  1059. sys.OS_WINDOWS = "Windows";
  1060. /**
  1061. * @memberof cc.sys
  1062. * @constant
  1063. * @type {string}
  1064. */
  1065. sys.OS_IOS = "iOS";
  1066. /**
  1067. * @memberof cc.sys
  1068. * @constant
  1069. * @type {string}
  1070. */
  1071. sys.OS_OSX = "OS X";
  1072. /**
  1073. * @memberof cc.sys
  1074. * @constant
  1075. * @type {string}
  1076. */
  1077. sys.OS_UNIX = "UNIX";
  1078. /**
  1079. * @memberof cc.sys
  1080. * @constant
  1081. * @type {string}
  1082. */
  1083. sys.OS_LINUX = "Linux";
  1084. /**
  1085. * @memberof cc.sys
  1086. * @constant
  1087. * @type {string}
  1088. */
  1089. sys.OS_ANDROID = "Android";
  1090. sys.OS_UNKNOWN = "Unknown";
  1091. /**
  1092. * @memberof cc.sys
  1093. * @constant
  1094. * @default
  1095. * @type {Number}
  1096. */
  1097. sys.WINDOWS = 0;
  1098. /**
  1099. * @memberof cc.sys
  1100. * @constant
  1101. * @default
  1102. * @type {Number}
  1103. */
  1104. sys.LINUX = 1;
  1105. /**
  1106. * @memberof cc.sys
  1107. * @constant
  1108. * @default
  1109. * @type {Number}
  1110. */
  1111. sys.MACOS = 2;
  1112. /**
  1113. * @memberof cc.sys
  1114. * @constant
  1115. * @default
  1116. * @type {Number}
  1117. */
  1118. sys.ANDROID = 3;
  1119. /**
  1120. * @memberof cc.sys
  1121. * @constant
  1122. * @default
  1123. * @type {Number}
  1124. */
  1125. sys.IPHONE = 4;
  1126. /**
  1127. * @memberof cc.sys
  1128. * @constant
  1129. * @default
  1130. * @type {Number}
  1131. */
  1132. sys.IPAD = 5;
  1133. /**
  1134. * @memberof cc.sys
  1135. * @constant
  1136. * @default
  1137. * @type {Number}
  1138. */
  1139. sys.BLACKBERRY = 6;
  1140. /**
  1141. * @memberof cc.sys
  1142. * @constant
  1143. * @default
  1144. * @type {Number}
  1145. */
  1146. sys.NACL = 7;
  1147. /**
  1148. * @memberof cc.sys
  1149. * @constant
  1150. * @default
  1151. * @type {Number}
  1152. */
  1153. sys.EMSCRIPTEN = 8;
  1154. /**
  1155. * @memberof cc.sys
  1156. * @constant
  1157. * @default
  1158. * @type {Number}
  1159. */
  1160. sys.TIZEN = 9;
  1161. /**
  1162. * @memberof cc.sys
  1163. * @constant
  1164. * @default
  1165. * @type {Number}
  1166. */
  1167. sys.WINRT = 10;
  1168. /**
  1169. * @memberof cc.sys
  1170. * @constant
  1171. * @default
  1172. * @type {Number}
  1173. */
  1174. sys.WP8 = 11;
  1175. /**
  1176. * @memberof cc.sys
  1177. * @constant
  1178. * @default
  1179. * @type {Number}
  1180. */
  1181. sys.MOBILE_BROWSER = 100;
  1182. /**
  1183. * @memberof cc.sys
  1184. * @constant
  1185. * @default
  1186. * @type {Number}
  1187. */
  1188. sys.DESKTOP_BROWSER = 101;
  1189. sys.BROWSER_TYPE_WECHAT = "wechat";
  1190. sys.BROWSER_TYPE_ANDROID = "androidbrowser";
  1191. sys.BROWSER_TYPE_IE = "ie";
  1192. sys.BROWSER_TYPE_QQ = "qqbrowser";
  1193. sys.BROWSER_TYPE_MOBILE_QQ = "mqqbrowser";
  1194. sys.BROWSER_TYPE_UC = "ucbrowser";
  1195. sys.BROWSER_TYPE_360 = "360browser";
  1196. sys.BROWSER_TYPE_BAIDU_APP = "baiduboxapp";
  1197. sys.BROWSER_TYPE_BAIDU = "baidubrowser";
  1198. sys.BROWSER_TYPE_MAXTHON = "maxthon";
  1199. sys.BROWSER_TYPE_OPERA = "opera";
  1200. sys.BROWSER_TYPE_MIUI = "miuibrowser";
  1201. sys.BROWSER_TYPE_FIREFOX = "firefox";
  1202. sys.BROWSER_TYPE_SAFARI = "safari";
  1203. sys.BROWSER_TYPE_CHROME = "chrome";
  1204. sys.BROWSER_TYPE_UNKNOWN = "unknown";
  1205. /**
  1206. * Is native ? This is set to be true in jsb auto.
  1207. * @constant
  1208. * @type {Boolean}
  1209. */
  1210. sys.isNative = false;
  1211. /**
  1212. * WhiteList of browser for WebGL.
  1213. * @constant
  1214. * @type {Array}
  1215. */
  1216. var webglWhiteList = [sys.BROWSER_TYPE_BAIDU, sys.BROWSER_TYPE_OPERA, sys.BROWSER_TYPE_FIREFOX, sys.BROWSER_TYPE_CHROME, sys.BROWSER_TYPE_SAFARI];
  1217. var multipleAudioWhiteList = [
  1218. sys.BROWSER_TYPE_BAIDU, sys.BROWSER_TYPE_OPERA, sys.BROWSER_TYPE_FIREFOX, sys.BROWSER_TYPE_CHROME,
  1219. sys.BROWSER_TYPE_SAFARI, sys.BROWSER_TYPE_UC, sys.BROWSER_TYPE_QQ, sys.BROWSER_TYPE_MOBILE_QQ, sys.BROWSER_TYPE_IE
  1220. ];
  1221. var win = window, nav = win.navigator, doc = document, docEle = doc.documentElement;
  1222. var ua = nav.userAgent.toLowerCase();
  1223. sys.isMobile = ua.indexOf('mobile') != -1 || ua.indexOf('android') != -1;
  1224. sys.platform = sys.isMobile ? sys.MOBILE_BROWSER : sys.DESKTOP_BROWSER;
  1225. var currLanguage = nav.language;
  1226. currLanguage = currLanguage ? currLanguage : nav.browserLanguage;
  1227. currLanguage = currLanguage ? currLanguage.split("-")[0] : sys.LANGUAGE_ENGLISH;
  1228. sys.language = currLanguage;
  1229. /** The type of browser */
  1230. var browserType = sys.BROWSER_TYPE_UNKNOWN;
  1231. var browserTypes = ua.match(/micromessenger|qqbrowser|mqqbrowser|ucbrowser|360browser|baiduboxapp|baidubrowser|maxthon|trident|opera|miuibrowser|firefox/i)
  1232. || ua.match(/chrome|safari/i);
  1233. if (browserTypes && browserTypes.length > 0) {
  1234. browserType = browserTypes[0].toLowerCase();
  1235. if (browserType == 'micromessenger') {
  1236. browserType = sys.BROWSER_TYPE_WECHAT;
  1237. } else if (browserType === "safari" && (ua.match(/android.*applewebkit/)))
  1238. browserType = sys.BROWSER_TYPE_ANDROID;
  1239. else if (browserType == "trident") browserType = sys.BROWSER_TYPE_IE;
  1240. }
  1241. sys.browserType = browserType;
  1242. sys._supportMultipleAudio = multipleAudioWhiteList.indexOf(sys.browserType) > -1;
  1243. //++++++++++++++++++something about cc._renderTYpe and cc._supportRender begin++++++++++++++++++++++++++++
  1244. var userRenderMode = parseInt(config[CONFIG_KEY.renderMode]);
  1245. var renderType = cc._RENDER_TYPE_WEBGL;
  1246. var tempCanvas = cc.newElement("Canvas");
  1247. cc._supportRender = true;
  1248. var notInWhiteList = webglWhiteList.indexOf(sys.browserType) == -1;
  1249. if (userRenderMode === 1 || (userRenderMode === 0 && (sys.isMobile || notInWhiteList)) || (location.origin == "file://")) {
  1250. renderType = cc._RENDER_TYPE_CANVAS;
  1251. }
  1252. sys._canUseCanvasNewBlendModes = function(){
  1253. var canvas = document.createElement('canvas');
  1254. canvas.width = 1;
  1255. canvas.height = 1;
  1256. var context = canvas.getContext('2d');
  1257. context.fillStyle = '#000';
  1258. context.fillRect(0,0,1,1);
  1259. context.globalCompositeOperation = 'multiply';
  1260. context.fillStyle = '#fff';
  1261. context.fillRect(0,0,1,1);
  1262. return context.getImageData(0,0,1,1).data[0] === 0;
  1263. };
  1264. //Whether or not the Canvas BlendModes are supported.
  1265. sys._supportCanvasNewBlendModes = sys._canUseCanvasNewBlendModes();
  1266. if (renderType == cc._RENDER_TYPE_WEBGL) {
  1267. if (!win.WebGLRenderingContext
  1268. || !cc.create3DContext(tempCanvas, {'stencil': true, 'preserveDrawingBuffer': true })) {
  1269. if (userRenderMode == 0) renderType = cc._RENDER_TYPE_CANVAS;
  1270. else cc._supportRender = false;
  1271. }
  1272. }
  1273. if (renderType == cc._RENDER_TYPE_CANVAS) {
  1274. try {
  1275. tempCanvas.getContext("2d");
  1276. } catch (e) {
  1277. cc._supportRender = false;
  1278. }
  1279. }
  1280. cc._renderType = renderType;
  1281. //++++++++++++++++++something about cc._renderTYpe and cc._supportRender end++++++++++++++++++++++++++++++
  1282. // check if browser supports Web Audio
  1283. // check Web Audio's context
  1284. try {
  1285. sys._supportWebAudio = !!(new (win.AudioContext || win.webkitAudioContext || win.mozAudioContext)());
  1286. } catch (e) {
  1287. sys._supportWebAudio = false;
  1288. }
  1289. /** LocalStorage is a local storage component.
  1290. */
  1291. try {
  1292. var localStorage = sys.localStorage = win.localStorage;
  1293. localStorage.setItem("storage", "");
  1294. localStorage.removeItem("storage");
  1295. localStorage = null;
  1296. } catch (e) {
  1297. if (e.name === "SECURITY_ERR" || e.name === "QuotaExceededError") {
  1298. cc.warn("Warning: localStorage isn't enabled. Please confirm browser cookie or privacy option");
  1299. }
  1300. sys.localStorage = function () {
  1301. };
  1302. }
  1303. var capabilities = sys.capabilities = {"canvas": true};
  1304. if (cc._renderType == cc._RENDER_TYPE_WEBGL)
  1305. capabilities["opengl"] = true;
  1306. if (docEle['ontouchstart'] !== undefined || nav.msPointerEnabled)
  1307. capabilities["touches"] = true;
  1308. if (docEle['onmouseup'] !== undefined)
  1309. capabilities["mouse"] = true;
  1310. if (docEle['onkeyup'] !== undefined)
  1311. capabilities["keyboard"] = true;
  1312. if (win.DeviceMotionEvent || win.DeviceOrientationEvent)
  1313. capabilities["accelerometer"] = true;
  1314. /** Get the os of system */
  1315. var iOS = ( ua.match(/(iPad|iPhone|iPod)/i) ? true : false );
  1316. var isAndroid = ua.match(/android/i) || nav.platform.match(/android/i) ? true : false;
  1317. var osName = sys.OS_UNKNOWN;
  1318. if (nav.appVersion.indexOf("Win") != -1) osName = sys.OS_WINDOWS;
  1319. else if (iOS) osName = sys.OS_IOS;
  1320. else if (nav.appVersion.indexOf("Mac") != -1) osName = sys.OS_OSX;
  1321. else if (nav.appVersion.indexOf("X11") != -1) osName = sys.OS_UNIX;
  1322. else if (isAndroid) osName = sys.OS_ANDROID;
  1323. else if (nav.appVersion.indexOf("Linux") != -1) osName = sys.OS_LINUX;
  1324. sys.os = osName;
  1325. // Forces the garbage collector
  1326. sys.garbageCollect = function () {
  1327. // N/A in cocos2d-html5
  1328. };
  1329. // Dumps rooted objects
  1330. sys.dumpRoot = function () {
  1331. // N/A in cocos2d-html5
  1332. };
  1333. // restarts the JS VM
  1334. sys.restartVM = function () {
  1335. // N/A in cocos2d-html5
  1336. };
  1337. sys.dump = function () {
  1338. var self = this;
  1339. var str = "";
  1340. str += "isMobile : " + self.isMobile + "\r\n";
  1341. str += "language : " + self.language + "\r\n";
  1342. str += "browserType : " + self.browserType + "\r\n";
  1343. str += "capabilities : " + JSON.stringify(self.capabilities) + "\r\n";
  1344. str += "os : " + self.os + "\r\n";
  1345. str += "platform : " + self.platform + "\r\n";
  1346. cc.log(str);
  1347. }
  1348. };
  1349. //+++++++++++++++++++++++++something about sys end+++++++++++++++++++++++++++++
  1350. //+++++++++++++++++++++++++something about CCGame begin+++++++++++++++++++++++++++
  1351. /**
  1352. * Device oriented vertically, home button on the bottom
  1353. * @constant
  1354. * @type {Number}
  1355. */
  1356. cc.ORIENTATION_PORTRAIT = 0;
  1357. /**
  1358. * Device oriented vertically, home button on the top
  1359. * @constant
  1360. * @type {Number}
  1361. */
  1362. cc.ORIENTATION_PORTRAIT_UPSIDE_DOWN = 1;
  1363. /**
  1364. * Device oriented horizontally, home button on the right
  1365. * @constant
  1366. * @type {Number}
  1367. */
  1368. cc.ORIENTATION_LANDSCAPE_LEFT = 2;
  1369. /**
  1370. * Device oriented horizontally, home button on the left
  1371. * @constant
  1372. * @type {Number}
  1373. */
  1374. cc.ORIENTATION_LANDSCAPE_RIGHT = 3;
  1375. /**
  1376. * drawing primitive of game engine
  1377. * @type {cc.DrawingPrimitive}
  1378. */
  1379. cc._drawingUtil = null;
  1380. /**
  1381. * main Canvas 2D/3D Context of game engine
  1382. * @type {CanvasRenderingContext2D|WebGLRenderingContext}
  1383. */
  1384. cc._renderContext = null;
  1385. /**
  1386. * main Canvas of game engine
  1387. * @type {HTMLCanvasElement}
  1388. */
  1389. cc._canvas = null;
  1390. /**
  1391. * This Div element contain all game canvas
  1392. * @type {HTMLDivElement}
  1393. */
  1394. cc._gameDiv = null;
  1395. cc._rendererInitialized = false;
  1396. /**
  1397. * <p>
  1398. * setup game main canvas,renderContext,gameDiv and drawingUtil with argument <br/>
  1399. * <br/>
  1400. * can receive follow type of arguemnt: <br/>
  1401. * - empty: create a canvas append to document's body, and setup other option <br/>
  1402. * - string: search the element by document.getElementById(), <br/>
  1403. * if this element is HTMLCanvasElement, set this element as main canvas of engine, and set it's ParentNode as cc._gameDiv.<br/>
  1404. * if this element is HTMLDivElement, set it's ParentNode to cc._gameDiv, and create a canvas as main canvas of engine. <br/>
  1405. * </p>
  1406. * @function
  1407. * @example
  1408. * //setup with null
  1409. * cc._setup();
  1410. *
  1411. * // setup with HTMLCanvasElement, gameCanvas is Canvas element
  1412. * // declare like this: <canvas id="gameCanvas" width="800" height="450"></canvas>
  1413. * cc._setup("gameCanvas");
  1414. *
  1415. * //setup with HTMLDivElement, gameDiv is Div element
  1416. * // declare like this: <div id="Cocos2dGameContainer" width="800" height="450"></div>
  1417. * cc._setup("Cocos2dGameContainer");
  1418. */
  1419. cc._setupCalled = false;
  1420. cc._setup = function (el, width, height) {
  1421. // Avoid setup to be called twice.
  1422. if (cc._setupCalled) return;
  1423. else cc._setupCalled = true;
  1424. var win = window;
  1425. var lastTime = new Date();
  1426. var frameTime = 1000 / cc.game.config[cc.game.CONFIG_KEY.frameRate];
  1427. var stTime = function(callback){
  1428. var currTime = new Date().getTime();
  1429. var timeToCall = Math.max(0, frameTime - (currTime - lastTime));
  1430. var id = window.setTimeout(function() { callback(); },
  1431. timeToCall);
  1432. lastTime = currTime + timeToCall;
  1433. return id;
  1434. };
  1435. var ctTime = function(id){
  1436. clearTimeout(id);
  1437. };
  1438. if(cc.sys.os === cc.sys.OS_IOS && cc.sys.browserType === cc.sys.BROWSER_TYPE_WECHAT){
  1439. win.requestAnimFrame = stTime;
  1440. win.cancelAnimationFrame = ctTime;
  1441. }else if(cc.game.config[cc.game.CONFIG_KEY.frameRate] != 60){
  1442. win.requestAnimFrame = stTime;
  1443. win.cancelAnimationFrame = ctTime;
  1444. }else{
  1445. win.requestAnimFrame = win.requestAnimationFrame ||
  1446. win.webkitRequestAnimationFrame ||
  1447. win.mozRequestAnimationFrame ||
  1448. win.oRequestAnimationFrame ||
  1449. win.msRequestAnimationFrame ||
  1450. stTime;
  1451. win.cancelAnimationFrame = window.cancelAnimationFrame ||
  1452. window.cancelRequestAnimationFrame ||
  1453. window.msCancelRequestAnimationFrame ||
  1454. window.mozCancelRequestAnimationFrame ||
  1455. window.oCancelRequestAnimationFrame ||
  1456. window.webkitCancelRequestAnimationFrame ||
  1457. window.msCancelAnimationFrame ||
  1458. window.mozCancelAnimationFrame ||
  1459. window.webkitCancelAnimationFrame ||
  1460. window.oCancelAnimationFrame ||
  1461. ctTime;
  1462. }
  1463. var element = cc.$(el) || cc.$('#' + el);
  1464. var localCanvas, localContainer, localConStyle;
  1465. if (element.tagName == "CANVAS") {
  1466. width = width || element.width;
  1467. height = height || element.height;
  1468. //it is already a canvas, we wrap it around with a div
  1469. localContainer = cc.container = cc.newElement("DIV");
  1470. localCanvas = cc._canvas = element;
  1471. localCanvas.parentNode.insertBefore(localContainer, localCanvas);
  1472. localCanvas.appendTo(localContainer);
  1473. localContainer.setAttribute('id', 'Cocos2dGameContainer');
  1474. } else {//we must make a new canvas and place into this element
  1475. if (element.tagName != "DIV") {
  1476. cc.log("Warning: target element is not a DIV or CANVAS");
  1477. }
  1478. width = width || element.clientWidth;
  1479. height = height || element.clientHeight;
  1480. localContainer = cc.container = element;
  1481. localCanvas = cc._canvas = cc.$(cc.newElement("CANVAS"));
  1482. element.appendChild(localCanvas);
  1483. }
  1484. localCanvas.addClass("gameCanvas");
  1485. localCanvas.setAttribute("width", width || 480);
  1486. localCanvas.setAttribute("height", height || 320);
  1487. localCanvas.setAttribute("tabindex", 99);
  1488. localCanvas.style.outline = "none";
  1489. localConStyle = localContainer.style;
  1490. localConStyle.width = (width || 480) + "px";
  1491. localConStyle.height = (height || 320) + "px";
  1492. localConStyle.margin = "0 auto";
  1493. localConStyle.position = 'relative';
  1494. localConStyle.overflow = 'hidden';
  1495. localContainer.top = '100%';
  1496. if (cc._renderType == cc._RENDER_TYPE_WEBGL)
  1497. cc._renderContext = cc.webglContext = cc.create3DContext(localCanvas, {
  1498. 'stencil': true,
  1499. 'preserveDrawingBuffer': true,
  1500. 'antialias': !cc.sys.isMobile,
  1501. 'alpha': false});
  1502. if (cc._renderContext) {
  1503. win.gl = cc._renderContext; // global variable declared in CCMacro.js
  1504. cc._drawingUtil = new cc.DrawingPrimitiveWebGL(cc._renderContext);
  1505. cc._rendererInitialized = true;
  1506. cc.textureCache._initializingRenderer();
  1507. cc.shaderCache._init();
  1508. } else {
  1509. cc._renderContext = localCanvas.getContext("2d");
  1510. cc._mainRenderContextBackup = cc._renderContext;
  1511. cc._renderContext.translate(0, localCanvas.height);
  1512. cc._drawingUtil = cc.DrawingPrimitiveCanvas ? new cc.DrawingPrimitiveCanvas(cc._renderContext) : null;
  1513. }
  1514. cc._gameDiv = localContainer;
  1515. cc.log(cc.ENGINE_VERSION);
  1516. cc._setContextMenuEnable(false);
  1517. if (cc.sys.isMobile) {
  1518. var fontStyle = cc.newElement("style");
  1519. fontStyle.type = "text/css";
  1520. document.body.appendChild(fontStyle);
  1521. fontStyle.textContent = "body,canvas,div{ -moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;-khtml-user-select: none;"
  1522. + "-webkit-tap-highlight-color:rgba(0,0,0,0);}";
  1523. }
  1524. // Init singletons
  1525. /**
  1526. * @type {cc.EGLView}
  1527. * @name cc.view
  1528. * cc.view is the shared view object.
  1529. */
  1530. cc.view = cc.EGLView._getInstance();
  1531. // register system events
  1532. cc.inputManager.registerSystemEvent(cc._canvas);
  1533. /**
  1534. * @type {cc.Director}
  1535. * @name cc.director
  1536. */
  1537. cc.director = cc.Director._getInstance();
  1538. if (cc.director.setOpenGLView)
  1539. cc.director.setOpenGLView(cc.view);
  1540. /**
  1541. * @type {cc.Size}
  1542. * @name cc.winSize
  1543. * cc.winSize is the alias object for the size of the current game window.
  1544. */
  1545. cc.winSize = cc.director.getWinSize();
  1546. // Parsers
  1547. cc.saxParser = new cc.SAXParser();
  1548. /**
  1549. * @type {cc.PlistParser}
  1550. * @name cc.plistParser
  1551. * A Plist Parser
  1552. */
  1553. cc.plistParser = new cc.PlistParser();
  1554. };
  1555. cc._checkWebGLRenderMode = function () {
  1556. if (cc._renderType !== cc._RENDER_TYPE_WEBGL)
  1557. throw "This feature supports WebGL render mode only.";
  1558. };
  1559. cc._isContextMenuEnable = false;
  1560. /**
  1561. * enable/disable contextMenu for Canvas
  1562. * @param {Boolean} enabled
  1563. */
  1564. cc._setContextMenuEnable = function (enabled) {
  1565. cc._isContextMenuEnable = enabled;
  1566. cc._canvas.oncontextmenu = function () {
  1567. if (!cc._isContextMenuEnable) return false;
  1568. };
  1569. };
  1570. /**
  1571. * An object to boot the game.
  1572. * @memberof cc
  1573. * @global
  1574. * @type {Object}
  1575. * @name cc.game
  1576. */
  1577. cc.game = {
  1578. DEBUG_MODE_NONE: 0,
  1579. DEBUG_MODE_INFO: 1,
  1580. DEBUG_MODE_WARN: 2,
  1581. DEBUG_MODE_ERROR: 3,
  1582. DEBUG_MODE_INFO_FOR_WEB_PAGE: 4,
  1583. DEBUG_MODE_WARN_FOR_WEB_PAGE: 5,
  1584. DEBUG_MODE_ERROR_FOR_WEB_PAGE: 6,
  1585. EVENT_HIDE: "game_on_hide",
  1586. EVENT_SHOW: "game_on_show",
  1587. _eventHide: null,
  1588. _eventShow: null,
  1589. _onBeforeStartArr: [],
  1590. /**
  1591. * Key of config
  1592. * @constant
  1593. * @type {Object}
  1594. */
  1595. CONFIG_KEY: {
  1596. engineDir: "engineDir",
  1597. dependencies: "dependencies",
  1598. debugMode: "debugMode",
  1599. showFPS: "showFPS",
  1600. frameRate: "frameRate",
  1601. id: "id",
  1602. renderMode: "renderMode",
  1603. jsList: "jsList",
  1604. classReleaseMode: "classReleaseMode"
  1605. },
  1606. _prepareCalled: false,//whether the prepare function has been called
  1607. _prepared: false,//whether the engine has prepared
  1608. _paused: true,//whether the game is paused
  1609. _intervalId: null,//interval target of main
  1610. /**
  1611. * Config of game
  1612. * @type {Object}
  1613. */
  1614. config: null,
  1615. /**
  1616. * Callback when the scripts of engine have been load.
  1617. * @type {Function}
  1618. */
  1619. onStart: null,
  1620. /**
  1621. * Callback when game exits.
  1622. * @type {Function}
  1623. */
  1624. onStop: null,
  1625. /**
  1626. * Set frameRate of game.
  1627. * @param frameRate
  1628. */
  1629. setFrameRate: function (frameRate) {
  1630. var self = this, config = self.config, CONFIG_KEY = self.CONFIG_KEY;
  1631. config[CONFIG_KEY.frameRate] = frameRate;
  1632. if (self._intervalId)
  1633. window.cancelAnimationFrame(self._intervalId);
  1634. self._paused = true;
  1635. self._runMainLoop();
  1636. },
  1637. /**
  1638. * Run game.
  1639. * @private
  1640. */
  1641. _runMainLoop: function () {
  1642. var self = this, callback, config = self.config, CONFIG_KEY = self.CONFIG_KEY,
  1643. director = cc.director;
  1644. director.setDisplayStats(config[CONFIG_KEY.showFPS]);
  1645. callback = function () {
  1646. if (!self._paused) {
  1647. director.mainLoop();
  1648. self._intervalId = window.requestAnimFrame(callback);
  1649. }
  1650. };
  1651. window.requestAnimFrame(callback);
  1652. self._paused = false;
  1653. },
  1654. /**
  1655. * Run game.
  1656. */
  1657. run: function (id) {
  1658. var self = this;
  1659. var _run = function () {
  1660. if (id) {
  1661. self.config[self.CONFIG_KEY.id] = id;
  1662. }
  1663. if (!self._prepareCalled) {
  1664. self.prepare(function () {
  1665. self._prepared = true;
  1666. });
  1667. }
  1668. if (cc._supportRender) {
  1669. self._checkPrepare = setInterval(function () {
  1670. if (self._prepared) {
  1671. cc._setup(self.config[self.CONFIG_KEY.id]);
  1672. self._runMainLoop();
  1673. self._eventHide = self._eventHide || new cc.EventCustom(self.EVENT_HIDE);
  1674. self._eventHide.setUserData(self);
  1675. self._eventShow = self._eventShow || new cc.EventCustom(self.EVENT_SHOW);
  1676. self._eventShow.setUserData(self);
  1677. self.onStart();
  1678. clearInterval(self._checkPrepare);
  1679. }
  1680. }, 10);
  1681. }
  1682. };
  1683. document.body ?
  1684. _run() :
  1685. cc._addEventListener(window, 'load', function () {
  1686. this.removeEventListener('load', arguments.callee, false);
  1687. _run();
  1688. }, false);
  1689. },
  1690. /**
  1691. * Init config.
  1692. * @returns {*}
  1693. * @private
  1694. */
  1695. _initConfig: function () {
  1696. var self = this, CONFIG_KEY = self.CONFIG_KEY;
  1697. var _init = function (cfg) {
  1698. cfg[CONFIG_KEY.engineDir] = cfg[CONFIG_KEY.engineDir] || "frameworks/cocos2d-html5";
  1699. if(cfg[CONFIG_KEY.debugMode] == null)
  1700. cfg[CONFIG_KEY.debugMode] = 0;
  1701. cfg[CONFIG_KEY.frameRate] = cfg[CONFIG_KEY.frameRate] || 60;
  1702. if(cfg[CONFIG_KEY.renderMode] == null)
  1703. cfg[CONFIG_KEY.renderMode] = 1;
  1704. return cfg;
  1705. };
  1706. if (document["ccConfig"]) {
  1707. self.config = _init(document["ccConfig"]);
  1708. } else {
  1709. try {
  1710. var cocos_script = document.getElementsByTagName('script');
  1711. for(var i=0;i<cocos_script.length;i++){
  1712. var _t = cocos_script[i].getAttribute('cocos');
  1713. if(_t == '' || _t){break;}
  1714. }
  1715. var _src, txt, _resPath;
  1716. if(i < cocos_script.length){
  1717. _src = cocos_script[i].src;
  1718. if(_src){
  1719. _resPath = /(.*)\//.exec(_src)[0];
  1720. cc.loader.resPath = _resPath;
  1721. _src = cc.path.join(_resPath, 'project.json');
  1722. }
  1723. txt = cc.loader._loadTxtSync(_src);
  1724. }
  1725. if(!txt){
  1726. txt = cc.loader._loadTxtSync("project.json");
  1727. }
  1728. var data = JSON.parse(txt);
  1729. self.config = _init(data || {});
  1730. } catch (e) {
  1731. cc.log("Failed to read or parse project.json");
  1732. self.config = _init({});
  1733. }
  1734. }
  1735. //init debug move to CCDebugger
  1736. cc._initSys(self.config, CONFIG_KEY);
  1737. },
  1738. //cache for js and module that has added into jsList to be loaded.
  1739. _jsAddedCache: {},
  1740. _getJsListOfModule: function (moduleMap, moduleName, dir) {
  1741. var jsAddedCache = this._jsAddedCache;
  1742. if (jsAddedCache[moduleName]) return null;
  1743. dir = dir || "";
  1744. var jsList = [];
  1745. var tempList = moduleMap[moduleName];
  1746. if (!tempList) throw "can not find module [" + moduleName + "]";
  1747. var ccPath = cc.path;
  1748. for (var i = 0, li = tempList.length; i < li; i++) {
  1749. var item = tempList[i];
  1750. if (jsAddedCache[item]) continue;
  1751. var extname = ccPath.extname(item);
  1752. if (!extname) {
  1753. var arr = this._getJsListOfModule(moduleMap, item, dir);
  1754. if (arr) jsList = jsList.concat(arr);
  1755. } else if (extname.toLowerCase() == ".js") jsList.push(ccPath.join(dir, item));
  1756. jsAddedCache[item] = 1;
  1757. }
  1758. return jsList;
  1759. },
  1760. /**
  1761. * Prepare game.
  1762. * @param cb
  1763. */
  1764. prepare: function (cb) {
  1765. var self = this;
  1766. var config = self.config, CONFIG_KEY = self.CONFIG_KEY, engineDir = config[CONFIG_KEY.engineDir], loader = cc.loader;
  1767. if (!cc._supportRender) {
  1768. throw "The renderer doesn't support the renderMode " + config[CONFIG_KEY.renderMode];
  1769. }
  1770. self._prepareCalled = true;
  1771. var jsList = config[CONFIG_KEY.jsList] || [];
  1772. if (cc.Class) {//is single file
  1773. //load user's jsList only
  1774. loader.loadJsWithImg("", jsList, function (err) {
  1775. if (err) throw err;
  1776. self._prepared = true;
  1777. if (cb) cb();
  1778. });
  1779. } else {
  1780. //load cc's jsList first
  1781. var ccModulesPath = cc.path.join(engineDir, "moduleConfig.json");
  1782. loader.loadJson(ccModulesPath, function (err, modulesJson) {
  1783. if (err) throw err;
  1784. var modules = config["modules"] || [];
  1785. var moduleMap = modulesJson["module"];
  1786. var newJsList = [];
  1787. if (cc._renderType == cc._RENDER_TYPE_WEBGL) modules.splice(0, 0, "shaders");
  1788. else if (modules.indexOf("core") < 0) modules.splice(0, 0, "core");
  1789. for (var i = 0, li = modules.length; i < li; i++) {
  1790. var arr = self._getJsListOfModule(moduleMap, modules[i], engineDir);
  1791. if (arr) newJsList = newJsList.concat(arr);
  1792. }
  1793. newJsList = newJsList.concat(jsList);
  1794. cc.loader.loadJsWithImg(newJsList, function (err) {
  1795. if (err) throw err;
  1796. self._prepared = true;
  1797. if (cb) cb();
  1798. });
  1799. });
  1800. }
  1801. }
  1802. };
  1803. cc.game._initConfig();
  1804. //+++++++++++++++++++++++++something about CCGame end+++++++++++++++++++++++++++++
  1805. Function.prototype.bind = Function.prototype.bind || function (bind) {
  1806. var self = this;
  1807. return function () {
  1808. var args = Array.prototype.slice.call(arguments);
  1809. return self.apply(bind || null, args);
  1810. };
  1811. };