CCBoot.js 67 KB

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