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