1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 /** 28 * copy an new object 29 * @function 30 * @param {object|Array} obj source object 31 * @return {Array|object} 32 */ 33 cc.clone = function (obj) { 34 // Cloning is better if the new object is having the same prototype chain 35 // as the copied obj (or otherwise, the cloned object is certainly going to 36 // have a different hidden class). Play with C1/C2 of the 37 // PerformanceVirtualMachineTests suite to see how this makes an impact 38 // under extreme conditions. 39 // 40 // Object.create(Object.getPrototypeOf(obj)) doesn't work well because the 41 // prototype lacks a link to the constructor (Carakan, V8) so the new 42 // object wouldn't have the hidden class that's associated with the 43 // constructor (also, for whatever reasons, utilizing 44 // Object.create(Object.getPrototypeOf(obj)) + Object.defineProperty is even 45 // slower than the original in V8). Therefore, we call the constructor, but 46 // there is a big caveat - it is possible that the this.init() in the 47 // constructor would throw with no argument. It is also possible that a 48 // derived class forgets to set "constructor" on the prototype. We ignore 49 // these possibities for and the ultimate solution is a standardized 50 // Object.clone(<object>). 51 var newObj = (obj.constructor) ? new obj.constructor : {}; 52 53 // Assuming that the constuctor above initialized all properies on obj, the 54 // following keyed assignments won't turn newObj into dictionary mode 55 // becasue they're not *appending new properties* but *assigning existing 56 // ones* (note that appending indexed properties is another story). See 57 // CCClass.js for a link to the devils when the assumption fails. 58 for (var key in obj) { 59 var copy = obj[key]; 60 // Beware that typeof null == "object" ! 61 if (((typeof copy) == "object") && copy && 62 !(copy instanceof cc.Node) && !(copy instanceof HTMLElement)) { 63 newObj[key] = cc.clone(copy); 64 } else { 65 newObj[key] = copy; 66 } 67 } 68 return newObj; 69 }; 70 71 /** 72 * Function added for JS bindings compatibility. Not needed in cocos2d-html5. 73 * @function 74 * @param {object} jsObj subclass 75 * @param {object} superclass 76 */ 77 cc.associateWithNative = function (jsObj, superclass) { 78 }; 79 80 /** 81 * Is show bebug info on web page 82 * @constant 83 * @type {Boolean} 84 */ 85 cc.IS_SHOW_DEBUG_ON_PAGE = cc.IS_SHOW_DEBUG_ON_PAGE || false; 86 87 cc._logToWebPage = function (message) { 88 var logList = document.getElementById("logInfoList"); 89 if (!logList) { 90 var logDiv = document.createElement("Div"); 91 logDiv.setAttribute("id", "logInfoDiv"); 92 cc.canvas.parentNode.appendChild(logDiv); 93 logDiv.setAttribute("width", "200"); 94 logDiv.setAttribute("height", cc.canvas.height); 95 logDiv.style.zIndex = "99999"; 96 logDiv.style.position = "absolute"; 97 logDiv.style.top = "0"; 98 logDiv.style.left = "0"; 99 100 logList = document.createElement("ul"); 101 logDiv.appendChild(logList); 102 logList.setAttribute("id", "logInfoList"); 103 logList.style.height = cc.canvas.height + "px"; 104 logList.style.color = "#fff"; 105 logList.style.textAlign = "left"; 106 logList.style.listStyle = "disc outside"; 107 logList.style.fontSize = "12px"; 108 logList.style.fontFamily = "arial"; 109 logList.style.padding = "0 0 0 20px"; 110 logList.style.margin = "0"; 111 logList.style.textShadow = "0 0 3px #000"; 112 logList.style.zIndex = "99998"; 113 logList.style.position = "absolute"; 114 logList.style.top = "0"; 115 logList.style.left = "0"; 116 logList.style.overflowY = "hidden"; 117 118 var tempDiv = document.createElement("Div"); 119 logDiv.appendChild(tempDiv); 120 tempDiv.style.width = "200px"; 121 tempDiv.style.height = cc.canvas.height + "px"; 122 tempDiv.style.opacity = "0.1"; 123 tempDiv.style.background = "#fff"; 124 tempDiv.style.border = "1px solid #dfdfdf"; 125 tempDiv.style.borderRadius = "8px"; 126 } 127 var addMessage = document.createElement("li"); 128 //var now = new Date(); 129 //addMessage.innerHTML = now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds() + " " + now.getMilliseconds() + " " + message; 130 addMessage.innerHTML = message; 131 if (logList.childNodes.length == 0) { 132 logList.appendChild(addMessage); 133 } else { 134 logList.insertBefore(addMessage, logList.childNodes[0]); 135 } 136 }; 137 138 /** 139 * Output Debug message. 140 * @function 141 * @param {String} message 142 */ 143 cc.log = function (message) { 144 if (!cc.IS_SHOW_DEBUG_ON_PAGE) { 145 console.log.apply(console, arguments); 146 } else { 147 cc._logToWebPage(message); 148 } 149 }; 150 151 /** 152 * Pop out a message box 153 * @param {String} message 154 * @function 155 */ 156 cc.MessageBox = function (message) { 157 console.log(message); 158 }; 159 160 /** 161 * Output Assert message. 162 * @function 163 * @param {Boolean} cond If cond is false, assert. 164 * @param {String} message 165 */ 166 cc.Assert = function (cond, message) { 167 if (console.assert) 168 console.assert(cond, message); 169 else { 170 if (!cond) { 171 if (message) 172 alert(message); 173 } 174 } 175 }; 176 177 /** 178 * Update Debug setting. 179 * @function 180 */ 181 cc.initDebugSetting = function () { 182 // cocos2d debug 183 if (cc.COCOS2D_DEBUG == 0) { 184 cc.log = function () { 185 }; 186 cc.logINFO = function () { 187 }; 188 cc.logERROR = function () { 189 }; 190 cc.Assert = function () { 191 }; 192 } else if (cc.COCOS2D_DEBUG == 1) { 193 cc.logINFO = cc.log; 194 cc.logERROR = function () { 195 }; 196 } else if (cc.COCOS2D_DEBUG > 1) { 197 cc.logINFO = cc.log; 198 cc.logERROR = cc.log; 199 }// COCOS2D_DEBUG 200 }; 201 202 // Enum the language type supportted now 203 /** 204 * English language code 205 * @constant 206 * @type Number 207 */ 208 cc.LANGUAGE_ENGLISH = 0; 209 210 /** 211 * Chinese language code 212 * @constant 213 * @type Number 214 */ 215 cc.LANGUAGE_CHINESE = 1; 216 217 /** 218 * French language code 219 * @constant 220 * @type Number 221 */ 222 cc.LANGUAGE_FRENCH = 2; 223 224 /** 225 * Italian language code 226 * @constant 227 * @type Number 228 */ 229 cc.LANGUAGE_ITALIAN = 3; 230 231 /** 232 * German language code 233 * @constant 234 * @type Number 235 */ 236 cc.LANGUAGE_GERMAN = 4; 237 238 /** 239 * Spanish language code 240 * @constant 241 * @type Number 242 */ 243 cc.LANGUAGE_SPANISH = 5; 244 245 /** 246 * Russian language code 247 * @constant 248 * @type Number 249 */ 250 cc.LANGUAGE_RUSSIAN = 6; 251 252 /** 253 * Korean language code 254 * @constant 255 * @type Number 256 */ 257 cc.LANGUAGE_KOREAN = 7; 258 259 /** 260 * Japanese language code 261 * @constant 262 * @type Number 263 */ 264 cc.LANGUAGE_JAPANESE = 8; 265 266 /** 267 * Hungarian language code 268 * @constant 269 * @type Number 270 */ 271 cc.LANGUAGE_HUNGARIAN = 9; 272 273 /** 274 * Portuguese language code 275 * @constant 276 * @type Number 277 */ 278 cc.LANGUAGE_PORTUGUESE = 10; 279 280 /** 281 * Arabic language code 282 * @constant 283 * @type Number 284 */ 285 cc.LANGUAGE_ARABIC = 11; 286 287 /** 288 * Norwegian language code 289 * @constant 290 * @type Number 291 */ 292 cc.LANGUAGE_NORWEGIAN = 12; 293 294 /** 295 * Polish language code 296 * @constant 297 * @type Number 298 */ 299 cc.LANGUAGE_POLISH = 13; 300 301 /** 302 * keymap 303 * @example 304 * //Example 305 * //to mark a keydown 306 * cc.keyDown[65] = true; 307 * //or 308 * cc.keyMap[cc.KEY.a] 309 * 310 * //to mark a keyup 311 * do cc.keyDown[65] = false; 312 * 313 * //to find out if a key is down, check 314 * if(cc.keyDown[65]) 315 * //or 316 * if,(cc.keyDown[cc.KEY.space]) 317 * //if its undefined or false or null, its not pressed 318 * @constant 319 * @type object 320 */ 321 cc.KEY = { 322 backspace:8, 323 tab:9, 324 enter:13, 325 shift:16, //should use shiftkey instead 326 ctrl:17, //should use ctrlkey 327 alt:18, //should use altkey 328 pause:19, 329 capslock:20, 330 escape:27, 331 pageup:33, 332 pagedown:34, 333 end:35, 334 home:36, 335 left:37, 336 up:38, 337 right:39, 338 down:40, 339 insert:45, 340 Delete:46, 341 0:48, 342 1:49, 343 2:50, 344 3:51, 345 4:52, 346 5:53, 347 6:54, 348 7:55, 349 8:56, 350 9:57, 351 a:65, 352 b:66, 353 c:67, 354 d:68, 355 e:69, 356 f:70, 357 g:71, 358 h:72, 359 i:73, 360 j:74, 361 k:75, 362 l:76, 363 m:77, 364 n:78, 365 o:79, 366 p:80, 367 q:81, 368 r:82, 369 s:83, 370 t:84, 371 u:85, 372 v:86, 373 w:87, 374 x:88, 375 y:89, 376 z:90, 377 num0:96, 378 num1:97, 379 num2:98, 380 num3:99, 381 num4:100, 382 num5:101, 383 num6:102, 384 num7:103, 385 num8:104, 386 num9:105, 387 '*':106, 388 '+':107, 389 '-':109, 390 'numdel':110, 391 '/':111, 392 f1:112, //f1-f12 dont work on ie 393 f2:113, 394 f3:114, 395 f4:115, 396 f5:116, 397 f6:117, 398 f7:118, 399 f8:119, 400 f9:120, 401 f10:121, 402 f11:122, 403 f12:123, 404 numlock:144, 405 scrolllock:145, 406 semicolon:186, 407 ',':186, 408 equal:187, 409 '=':187, 410 ';':188, 411 comma:188, 412 dash:189, 413 '.':190, 414 period:190, 415 forwardslash:191, 416 grave:192, 417 '[':219, 418 openbracket:219, 419 ']':221, 420 closebracket:221, 421 backslash:220, 422 quote:222, 423 space:32 424 }; 425 426 427 /** 428 * Image Format:JPG 429 * @constant 430 * @type Number 431 */ 432 cc.FMT_JPG = 0; 433 434 /** 435 * Image Format:PNG 436 * @constant 437 * @type Number 438 */ 439 cc.FMT_PNG = 1; 440 441 /** 442 * Image Format:TIFF 443 * @constant 444 * @type Number 445 */ 446 cc.FMT_TIFF = 2; 447 448 /** 449 * Image Format:RAWDATA 450 * @constant 451 * @type Number 452 */ 453 cc.FMT_RAWDATA = 3; 454 455 /** 456 * Image Format:WEBP 457 * @constant 458 * @type Number 459 */ 460 cc.FMT_WEBP = 4; 461 462 /** 463 * Image Format:UNKNOWN 464 * @constant 465 * @type Number 466 */ 467 cc.FMT_UNKNOWN = 5; 468 469 cc.getImageFormatByData = function (imgData) { 470 // if it is a png file buffer. 471 if (imgData.length > 8) { 472 if (imgData[0] == 0x89 473 && imgData[1] == 0x50 474 && imgData[2] == 0x4E 475 && imgData[3] == 0x47 476 && imgData[4] == 0x0D 477 && imgData[5] == 0x0A 478 && imgData[6] == 0x1A 479 && imgData[7] == 0x0A) { 480 return cc.FMT_PNG; 481 } 482 } 483 484 // if it is a tiff file buffer. 485 if (imgData.length > 2) { 486 if ((imgData[0] == 0x49 && imgData[1] == 0x49) 487 || (imgData[0] == 0x4d && imgData[1] == 0x4d) 488 || (imgData[0] == 0xff && imgData[1] == 0xd8)) { 489 return cc.FMT_TIFF; 490 } 491 } 492 493 return cc.FMT_UNKNOWN; 494 }; 495 496 497 498 var CCNS_REG1 = /^\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*$/; 499 var CCNS_REG2 = /^\s*\{\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*,\s*\{\s*([\-]?\d+[.]?\d*)\s*,\s*([\-]?\d+[.]?\d*)\s*\}\s*\}\s*$/ 500 /** 501 * Returns a Core Graphics rectangle structure corresponding to the data in a given string. <br/> 502 * The string is not localized, so items are always separated with a comma. <br/> 503 * If the string is not well-formed, the function returns cc.RectZero. 504 * @function 505 * @param {String} content content A string object whose contents are of the form "{{x,y},{w, h}}",<br/> 506 * where x is the x coordinate, y is the y coordinate, w is the width, and h is the height. <br/> 507 * These components can represent integer or float values. 508 * @return {cc.Rect} A Core Graphics structure that represents a rectangle. 509 * Constructor 510 * @example 511 * // example 512 * var rect = cc.RectFromString("{{3,2},{4,5}}"); 513 */ 514 cc.RectFromString = function (content) { 515 var result = CCNS_REG2.exec(content); 516 if(!result) return cc.RectZero(); 517 return cc.rect(parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]), parseFloat(result[4])); 518 }; 519 520 /** 521 * Returns a Core Graphics point structure corresponding to the data in a given string. 522 * @function 523 * @param {String} content A string object whose contents are of the form "{x,y}", 524 * where x is the x coordinate and y is the y coordinate.<br/> 525 * The x and y values can represent integer or float values. <br/> 526 * The string is not localized, so items are always separated with a comma.<br/> 527 * @return {cc.Point} A Core Graphics structure that represents a point.<br/> 528 * If the string is not well-formed, the function returns cc.PointZero. 529 * Constructor 530 * @example 531 * //example 532 * var point = cc.PointFromString("{3.0,2.5}"); 533 */ 534 cc.PointFromString = function (content) { 535 var result = CCNS_REG1.exec(content); 536 if(!result) return cc.PointZero(); 537 return cc.p(parseFloat(result[1]), parseFloat(result[2])); 538 }; 539 540 /** 541 * Returns a Core Graphics size structure corresponding to the data in a given string. 542 * @function 543 * @param {String} content A string object whose contents are of the form "{w, h}",<br/> 544 * where w is the width and h is the height.<br/> 545 * The w and h values can be integer or float values. <br/> 546 * The string is not localized, so items are always separated with a comma.<br/> 547 * @return {cc.Size} A Core Graphics structure that represents a size.<br/> 548 * If the string is not well-formed, the function returns cc.SizeZero. 549 * @example 550 * // example 551 * var size = cc.SizeFromString("{3.0,2.5}"); 552 */ 553 cc.SizeFromString = function (content) { 554 var result = CCNS_REG1.exec(content); 555 if(!result) return cc.SizeZero(); 556 return cc.size(parseFloat(result[1]), parseFloat(result[2])); 557 }; 558 559 /** 560 * 561 * @param {Function} selector 562 * @param {cc.Node} target 563 * @param {Object|Number|String} data 564 */ 565 cc.doCallback = function (selector, target, data) { 566 if(!selector) 567 return ; 568 if (target && (typeof(selector) == "string")) { 569 target[selector](data); 570 } else if (target && (typeof(selector) == "function")) { 571 selector.call(target, data); 572 } else { 573 selector(data); 574 } 575 };