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 // 29 // POINT 30 // 31 //-------------------------------------------------------- 32 /** 33 * @class 34 * @param {Number} _x 35 * @param {Number} _y 36 * Constructor 37 */ 38 cc.Point = function (_x, _y) { 39 this.x = _x || 0; 40 this.y = _y || 0; 41 }; 42 43 cc._PointConst = function (x, y) { 44 this._x = x || 0; 45 this._y = y || 0; 46 47 this.setX = function (x) { 48 this._x = x; 49 }; 50 this.setY = function (y) { 51 this._y = y; 52 } 53 }; 54 55 cc._pConst = function (x, y) { 56 return new cc._PointConst(x, y); 57 }; 58 59 Object.defineProperties(cc._PointConst.prototype, { 60 x: { 61 get: function () { 62 return this._x; 63 }, 64 set: function () { 65 console.warn("Warning of _PointConst: Modification to const or private property is forbidden"); 66 }, 67 enumerable: true 68 }, 69 70 y: { 71 get: function () { 72 return this._y; 73 }, 74 set: function () { 75 console.warn("Warning of _PointConst: Modification to const or private property is forbidden"); 76 }, 77 enumerable: true 78 } 79 }); 80 81 /** 82 * @function 83 * @param {Number} x 84 * @param {Number} y 85 * @return {cc.Point} 86 */ 87 cc.PointMake = function (x, y) { 88 cc.log("cc.PointMake will be deprecated sooner or later. Use cc.p instead."); 89 return new cc.Point(x, y); 90 }; 91 92 /** 93 * Helper macro that creates a cc.Point. 94 * @param {Number} x 95 * @param {Number} y 96 */ 97 cc.p = function (x, y) { 98 // This can actually make use of "hidden classes" in JITs and thus decrease 99 // memory usage and overall performance drastically 100 //return new cc.Point(x, y); 101 // but this one will instead flood the heap with newly allocated hash maps 102 // giving little room for optimization by the JIT, 103 // note: we have tested this item on Chrome and firefox, it is faster than new cc.Point(x, y) 104 return {x: x, y: y}; 105 }; 106 107 // JSB compatbility: in JSB, cc._p reuses objects instead of creating new ones 108 cc._p = cc.p; 109 110 /** 111 * The "left bottom" point -- equivalent to cc.p(0, 0). 112 * @function 113 * @return {cc.Point} 114 */ 115 cc.PointZero = function () { 116 return cc.p(0, 0); 117 }; 118 119 /** 120 * @function 121 * @param {cc.Point} point1 122 * @param {cc.Point} point2 123 * @return {Boolean} 124 */ 125 cc.pointEqualToPoint = function (point1, point2) { 126 if (!point1 || !point2) 127 return false; 128 return ((point1.x === point2.x) && (point1.y === point2.y)); 129 }; 130 131 // deprecated 132 //cc.Point.CCPointEqualToPoint = cc.pointEqualToPoint; 133 134 135 //-------------------------------------------------------- 136 // 137 // SIZE 138 // 139 //-------------------------------------------------------- 140 141 /** 142 * @class 143 * @param {Number} _width 144 * @param {Number} _height 145 * Constructor 146 */ 147 cc.Size = function (_width, _height) { 148 this.width = _width || 0; 149 this.height = _height || 0; 150 }; 151 152 cc._SizeConst = function (width, height) { 153 this._width = width || 0; 154 this._height = height || 0; 155 156 this.setWidth = function (width) { 157 this._width = width; 158 }; 159 this.setHeight = function (height) { 160 this._height = height; 161 } 162 }; 163 164 cc._sizeConst = function (width, height) { 165 return new cc._SizeConst(width, height); 166 }; 167 168 Object.defineProperties(cc._SizeConst.prototype, { 169 width: { 170 get: function () { 171 return this._width; 172 }, 173 set: function () { 174 console.warn("Warning of _SizeConst: Modification to const or private property is forbidden"); 175 }, 176 enumerable: true 177 }, 178 179 height: { 180 get: function () { 181 return this._height; 182 }, 183 set: function () { 184 console.warn("Warning of _SizeConst: Modification to const or private property is forbidden"); 185 }, 186 enumerable: true 187 } 188 }); 189 190 /** 191 * @function 192 * @param {Number} width 193 * @param {Number} height 194 * @return {cc.Size} 195 */ 196 cc.SizeMake = function (width, height) { 197 cc.log("cc.SizeMake will be deprecated sooner or later. Use cc.size instead."); 198 return cc.size(width, height); 199 }; 200 201 /** 202 * @function 203 * @param {Number} w width 204 * @param {Number} h height 205 * @return {cc.Size} 206 */ 207 cc.size = function (w, h) { 208 // This can actually make use of "hidden classes" in JITs and thus decrease 209 // memory usage and overall peformance drastically 210 //return new cc.Size(w, h); 211 // but this one will instead flood the heap with newly allocated hash maps 212 // giving little room for optimization by the JIT 213 // note: we have tested this item on Chrome and firefox, it is faster than new cc.Size(w, h) 214 return { width: w, height: h}; 215 }; 216 217 // JSB compatbility: in JSB, cc._size reuses objects instead of creating new ones 218 cc._size = cc.size; 219 220 /** 221 * The "zero" size -- equivalent to cc.size(0, 0). 222 * @function 223 * @return {cc.Size} 224 */ 225 cc.SizeZero = function () { 226 return cc.size(0, 0); 227 }; 228 229 cc._zeroConsts = {pointZero: cc._pConst(0,0), sizeZero: cc._sizeConst(0,0)}; 230 231 Object.defineProperties(cc, { 232 POINT_ZERO:{ 233 get:function () { 234 return cc._zeroConsts.pointZero; 235 } 236 }, 237 SIZE_ZERO:{ 238 get:function () { 239 return cc._zeroConsts.sizeZero; 240 } 241 }, 242 RECT_ZERO:{ 243 get:function () { 244 return cc.rect(0, 0, 0, 0); 245 } 246 } 247 }); 248 249 250 /** 251 * @function 252 * @param {cc.Size} size1 253 * @param {cc.Size} size2 254 * @return {Boolean} 255 */ 256 cc.sizeEqualToSize = function (size1, size2) { 257 if (!size1 || !size2) 258 return false; 259 return ((size1.width == size2.width) && (size1.height == size2.height)); 260 }; 261 262 // deprecated 263 //cc.Size.CCSizeEqualToSize = cc.sizeEqualToSize; 264 265 //-------------------------------------------------------- 266 // 267 // RECT 268 // 269 //-------------------------------------------------------- 270 271 /** 272 * @class 273 * @param {Number|cc.Point|cc.Rect} [x1] a Number value as x or a cc.Point object as origin or a cc.Rect clone object 274 * @param {Number|cc.Size} [y1] x1 a Number value as y or a cc.Size object as size 275 * @param {Number} [width1] 276 * @param {Number} [height1] 277 * Constructor 278 */ 279 cc.Rect = function (x1, y1, width1, height1) { 280 var argLen =arguments.length; 281 if(argLen === 4){ 282 this._origin = new cc.Point(x1 || 0, y1 || 0); 283 this._size = new cc.Size(width1 || 0, height1 || 0); 284 return; 285 } 286 if(argLen === 1) { 287 this._origin = new cc.Point(x1._origin.x, x1._origin.y); 288 this._size = new cc.Size(x1._size.width, x1._size.height); 289 return; 290 } 291 if(argLen === 0) { 292 this._origin = new cc.Point(0, 0); 293 this._size = new cc.Size(0,0); 294 return; 295 } 296 if(argLen === 2) { 297 this._origin = new cc.Point(x1.x, x1.y); 298 this._size = new cc.Size(y1.width,y1.height); 299 return; 300 } 301 throw "unknown argument type"; 302 }; 303 304 /** 305 * @function 306 * @param {Number} x 307 * @param {Number} y 308 * @param {Number} width 309 * @param {Number} height 310 * @return {cc.Rect} 311 */ 312 cc.RectMake = function (x, y, width, height) { 313 cc.log("cc.RectMake will be deprecated sooner or later. Use cc.rect instead."); 314 return cc.rect(x, y, width, height); 315 }; 316 317 // backward compatible 318 cc.rect = function (x, y, w, h) { 319 var argLen =arguments.length; 320 if(argLen === 0) 321 return new cc.Rect(0,0,0,0); 322 323 if(argLen === 1) 324 return new cc.Rect(x.x, x.y, x.width, x.height); 325 326 if(argLen === 2) 327 return new cc.Rect(x.x, x.y, y.width, y.height); 328 329 if(argLen === 4) 330 return new cc.Rect(x,y,w,h); 331 332 throw "unknown argument type"; 333 }; 334 335 // JSB compatbility: in JSB, cc._rect reuses objects instead of creating new ones 336 cc._rect = cc.rect; 337 338 /** 339 * The "zero" rectangle -- equivalent to cc.rect(0, 0, 0, 0). 340 * @function 341 * @return {cc.Rect} 342 */ 343 cc.RectZero = function () { 344 return cc.rect(0, 0, 0, 0); 345 }; 346 347 /** 348 * @function 349 * @param {cc.Rect} rect1 350 * @param {cc.Rect} rect2 351 * @return {Boolean} 352 */ 353 cc.rectEqualToRect = function (rect1, rect2) { 354 if(!rect1 || !rect2) 355 return false; 356 return ((cc.pointEqualToPoint(rect1._origin, rect2._origin)) && 357 (cc.sizeEqualToSize(rect1._size, rect2._size))); 358 }; 359 360 cc._rectEqualToZero = function(rect){ 361 if(!rect) 362 return false; 363 return (rect.x === 0) && (rect.y === 0) && (rect.width === 0) && (rect.height === 0); 364 }; 365 366 /** 367 * @function 368 * @param {cc.Rect} rect1 369 * @param {cc.Rect} rect2 370 * @return {Boolean} 371 */ 372 cc.rectContainsRect = function (rect1, rect2) { 373 if (!rect1 || !rect2) 374 return false; 375 376 return !((rect1.x >= rect2.x) || (rect1.y >= rect2.y) || 377 ( rect1.x + rect1.width <= rect2.x + rect2.width) || 378 ( rect1.y + rect1.height <= rect2.y + rect2.height)); 379 }; 380 381 /** 382 * return the rightmost x-value of 'rect' 383 * @function 384 * @param {cc.Rect} rect 385 * @return {Number} 386 */ 387 cc.rectGetMaxX = function (rect) { 388 return (rect.x + rect.width); 389 }; 390 391 /** 392 * return the midpoint x-value of 'rect' 393 * @function 394 * @param {cc.Rect} rect 395 * @return {Number} 396 */ 397 cc.rectGetMidX = function (rect) { 398 return (rect.x + rect.width / 2.0); 399 }; 400 /** 401 * return the leftmost x-value of 'rect' 402 * @function 403 * @param {cc.Rect} rect 404 * @return {Number} 405 */ 406 cc.rectGetMinX = function (rect) { 407 return rect.x; 408 }; 409 410 /** 411 * Return the topmost y-value of `rect' 412 * @function 413 * @param {cc.Rect} rect 414 * @return {Number} 415 */ 416 cc.rectGetMaxY = function (rect) { 417 return(rect.y + rect.height); 418 }; 419 420 /** 421 * Return the midpoint y-value of `rect' 422 * @function 423 * @param {cc.Rect} rect 424 * @return {Number} 425 */ 426 cc.rectGetMidY = function (rect) { 427 return rect.y + rect.height / 2.0; 428 }; 429 430 /** 431 * Return the bottommost y-value of `rect' 432 * @function 433 * @param {cc.Rect} rect 434 * @return {Number} 435 */ 436 cc.rectGetMinY = function (rect) { 437 return rect.y; 438 }; 439 440 /** 441 * @function 442 * @param {cc.Rect} rect 443 * @param {cc.Point} point 444 * @return {Boolean} 445 */ 446 cc.rectContainsPoint = function (rect, point) { 447 return (point.x >= cc.rectGetMinX(rect) && point.x <= cc.rectGetMaxX(rect) && 448 point.y >= cc.rectGetMinY(rect) && point.y <= cc.rectGetMaxY(rect)) ; 449 }; 450 451 /** 452 * @function 453 * @param {cc.Rect} rectA 454 * @param {cc.Rect} rectB 455 * @return {Boolean} 456 */ 457 cc.rectIntersectsRect = function (rectA, rectB) { 458 return !(cc.rectGetMaxX(rectA) < cc.rectGetMinX(rectB) || 459 cc.rectGetMaxX(rectB) < cc.rectGetMinX(rectA) || 460 cc.rectGetMaxY(rectA) < cc.rectGetMinY(rectB) || 461 cc.rectGetMaxY(rectB) < cc.rectGetMinY(rectA)); 462 }; 463 464 /** 465 * @function 466 * @param {cc.Rect} rectA 467 * @param {cc.Rect} rectB 468 * @return {Boolean} 469 */ 470 cc.rectOverlapsRect = function (rectA, rectB) { 471 return !((rectA.x + rectA.width < rectB.x) || 472 (rectB.x + rectB.width < rectA.x) || 473 (rectA.y + rectA.height < rectB.y) || 474 (rectB.y + rectB.height < rectA.y)); 475 }; 476 477 /** 478 * Returns the smallest rectangle that contains the two source rectangles. 479 * @function 480 * @param {cc.Rect} rectA 481 * @param {cc.Rect} rectB 482 * @return {cc.Rect} 483 */ 484 cc.rectUnion = function (rectA, rectB) { 485 var rect = cc.rect(0, 0, 0, 0); 486 rect.x = Math.min(rectA.x, rectB.x); 487 rect.y = Math.min(rectA.y, rectB.y); 488 rect.width = Math.max(rectA.x + rectA.width, rectB.x + rectB.width) - rect.x; 489 rect.height = Math.max(rectA.y + rectA.height, rectB.y + rectB.height) - rect.y; 490 return rect; 491 }; 492 493 /** 494 * Returns the overlapping portion of 2 rectangles 495 * @function 496 * @param {cc.Rect} rectA 497 * @param {cc.Rect} rectB 498 * @return {cc.Rect} 499 */ 500 cc.rectIntersection = function (rectA, rectB) { 501 var intersection = cc.rect( 502 Math.max(cc.rectGetMinX(rectA), cc.rectGetMinX(rectB)), 503 Math.max(cc.rectGetMinY(rectA), cc.rectGetMinY(rectB)), 504 0, 0); 505 506 intersection.width = Math.min(cc.rectGetMaxX(rectA), cc.rectGetMaxX(rectB)) - cc.rectGetMinX(intersection); 507 intersection.height = Math.min(cc.rectGetMaxY(rectA), cc.rectGetMaxY(rectB)) - cc.rectGetMinY(intersection); 508 return intersection; 509 }; 510 511 // 512 // Rect JSB compatibility 513 // JSB uses: 514 // rect.x, rect.y, rect.width and rect.height 515 // while HTML5 uses: 516 // rect.origin, rect.size 517 // 518 cc.Rect.prototype.getX = function() { 519 return this._origin.x; 520 }; 521 cc.Rect.prototype.setX = function(x) { 522 this._origin.x = x; 523 }; 524 cc.Rect.prototype.getY = function() { 525 return this._origin.y; 526 }; 527 cc.Rect.prototype.setY = function(y) { 528 this._origin.y = y; 529 }; 530 cc.Rect.prototype.getWidth = function(){ 531 return this._size.width; 532 }; 533 cc.Rect.prototype.setWidth = function(w){ 534 this._size.width = w; 535 }; 536 cc.Rect.prototype.getHeight = function(){ 537 return this._size.height; 538 }; 539 cc.Rect.prototype.setHeight = function(h){ 540 this._size.height = h; 541 }; 542 543 Object.defineProperties(cc.Rect.prototype, 544 { 545 "x": { 546 get: function () { 547 return this.getX(); 548 }, 549 set: function (newValue) { 550 this.setX(newValue); 551 }, 552 enumerable: true, 553 configurable: true 554 }, 555 "y": { 556 get: function () { 557 return this.getY(); 558 }, 559 set: function (newValue) { 560 this.setY(newValue); 561 }, 562 enumerable: true, 563 configurable: true 564 }, 565 "width": { 566 get: function () { 567 return this.getWidth(); 568 }, 569 set: function (newValue) { 570 this.setWidth(newValue); 571 }, 572 enumerable: true, 573 configurable: true 574 }, 575 "height": { 576 get: function () { 577 return this.getHeight(); 578 }, 579 set: function (newValue) { 580 this.setHeight(newValue); 581 }, 582 enumerable: true, 583 configurable: true 584 } 585 } 586 ); 587 588 // Deprecated 589 /*cc.Rect.CCRectEqualToRect = cc.rectEqualToRect; 590 cc.Rect.CCRectContainsRect = cc.rectContainsRect; 591 cc.Rect.CCRectGetMaxX = cc.rectGetMaxX; 592 cc.Rect.CCRectGetMidX = cc.rectGetMidX; 593 cc.Rect.CCRectGetMinX = cc.rectGetMinX; 594 cc.Rect.CCRectGetMaxY = cc.rectGetMaxY; 595 cc.Rect.CCRectGetMidY = cc.rectGetMidY; 596 cc.Rect.CCRectGetMinY = cc.rectGetMinY; 597 cc.Rect.CCRectContainsPoint = cc.rectContainsPoint; 598 cc.Rect.CCRectIntersectsRect = cc.rectIntersectsRect; 599 cc.Rect.CCRectUnion = cc.rectUnion; 600 cc.Rect.CCRectIntersection = cc.rectIntersection;*/ 601 602