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 * @constant 29 * @type Number 30 */ 31 cc.TouchSelectorBeganBit = 1 << 0; 32 33 /** 34 * @constant 35 * @type Number 36 */ 37 cc.TouchSelectorMovedBit = 1 << 1; 38 39 /** 40 * @constant 41 * @type Number 42 */ 43 cc.TouchSelectorEndedBit = 1 << 2; 44 45 /** 46 * @constant 47 * @type Number 48 */ 49 cc.TouchSelectorCancelledBit = 1 << 3; 50 51 /** 52 * @constant 53 * @type Number 54 */ 55 cc.TouchSelectorAllBits = ( cc.TouchSelectorBeganBit | cc.TouchSelectorMovedBit | cc.TouchSelectorEndedBit | cc.TouchSelectorCancelledBit); 56 57 /** 58 * @constant 59 * @type Number 60 */ 61 cc.TOUCH_BEGAN = 0; 62 63 /** 64 * @constant 65 * @type Number 66 */ 67 cc.TOUCH_MOVED = 1; 68 69 /** 70 * @constant 71 * @type Number 72 */ 73 cc.TOUCH_ENDED = 2; 74 75 /** 76 * @constant 77 * @type Number 78 */ 79 cc.TOUCH_CANCELLED = 3; 80 81 /** 82 * @constant 83 * @type Number 84 */ 85 cc.TouchMax = 4; 86 87 /** 88 * @function 89 * @param {cc.TouchHandler} p1 90 * @param {cc.TouchHandler} p2 91 * @return {Boolean} 92 */ 93 cc.less = function (p1, p2) { 94 return p1.getPriority() > p2.getPriority(); 95 }; 96 97 /** 98 * @param {Number} type 99 * Constructor 100 */ 101 cc.TouchHandlerHelperData = function (type) { 102 // we only use the type 103 this.type = type; 104 }; 105 106 /** 107 * cc.TouchDispatcher. 108 * Singleton that handles all the touch events. 109 * The dispatcher dispatches events to the registered TouchHandlers. 110 * There are 2 different type of touch handlers: 111 * - Standard Touch Handlers 112 * - Targeted Touch Handlers 113 * 114 * The Standard Touch Handlers work like the CocoaTouch touch handler: a set of touches is passed to the delegate. 115 * On the other hand, the Targeted Touch Handlers only receive 1 touch at the time, and they can "swallow" touches (avoid the propagation of the event). 116 * 117 * Firstly, the dispatcher sends the received touches to the targeted touches. 118 * These touches can be swallowed by the Targeted Touch Handlers. If there are still remaining touches, then the remaining touches will be sent 119 * to the Standard Touch Handlers. 120 * @class 121 * @extends cc.Class 122 */ 123 cc.TouchDispatcher = cc.Class.extend(/** @lends cc.TouchDispatcher# */{ 124 _mousePressed:false, 125 _targetedHandlers:null, 126 _standardHandlers:null, 127 _locked:false, 128 _toAdd:false, 129 _toRemove:false, 130 _handlersToAdd:null, 131 _handlersToRemove:null, 132 _toQuit:false, 133 _dispatchEvents:false, 134 _handlerHelperData:[new cc.TouchHandlerHelperData(cc.TOUCH_BEGAN), new cc.TouchHandlerHelperData(cc.TOUCH_MOVED), 135 new cc.TouchHandlerHelperData(cc.TOUCH_ENDED), new cc.TouchHandlerHelperData(cc.TOUCH_CANCELLED)], 136 137 /** 138 * @return {Boolean} 139 */ 140 init:function () { 141 this._dispatchEvents = true; 142 this._targetedHandlers = []; 143 this._standardHandlers = []; 144 this._handlersToAdd = []; 145 this._handlersToRemove = []; 146 this._toRemove = false; 147 this._toAdd = false; 148 this._toQuit = false; 149 this._locked = false; 150 this._mousePressed = false; 151 cc.TouchDispatcher.registerHtmlElementEvent(cc.canvas); 152 return true; 153 }, 154 155 _setMousePressed:function (pressed) { 156 this._mousePressed = pressed; 157 }, 158 159 _getMousePressed:function () { 160 return this._mousePressed; 161 }, 162 163 /** 164 * Whether or not the events are going to be dispatched. Default: true 165 * @return {Boolean} 166 */ 167 isDispatchEvents:function () { 168 return this._dispatchEvents; 169 }, 170 171 /** 172 * @param {Boolean} dispatchEvents 173 */ 174 setDispatchEvents:function (dispatchEvents) { 175 this._dispatchEvents = dispatchEvents; 176 }, 177 178 /** 179 * Adds a standard touch delegate to the dispatcher's list. 180 * See StandardTouchDelegate description. 181 * IMPORTANT: The delegate will be retained. 182 * @param {cc.TouchDelegate} delegate 183 * @param {Number} priority 184 */ 185 addStandardDelegate:function (delegate, priority) { 186 var handler = cc.StandardTouchHandler.handlerWithDelegate(delegate, priority); 187 188 if (!this._locked) { 189 this._standardHandlers = this.forceAddHandler(handler, this._standardHandlers); 190 } else { 191 /* If handler is contained in m_pHandlersToRemove, if so remove it from m_pHandlersToRemove and retrun. 192 * Refer issue #752(cocos2d-x) 193 */ 194 if (this._handlersToRemove.indexOf(delegate) != -1) { 195 cc.ArrayRemoveObject(this._handlersToRemove, delegate); 196 return; 197 } 198 199 this._handlersToAdd.push(handler); 200 this._toAdd = true; 201 } 202 }, 203 204 /** 205 * @param {cc.TouchDelegate} delegate 206 * @param {Number} priority 207 * @param {Boolean} swallowsTouches 208 */ 209 addTargetedDelegate:function (delegate, priority, swallowsTouches) { 210 var handler = cc.TargetedTouchHandler.handlerWithDelegate(delegate, priority, swallowsTouches); 211 if (!this._locked) { 212 this._targetedHandlers = this.forceAddHandler(handler, this._targetedHandlers); 213 } else { 214 /* If handler is contained in m_pHandlersToRemove, if so remove it from m_pHandlersToRemove and retrun. 215 * Refer issue #752(cocos2d-x) 216 */ 217 if (this._handlersToRemove.indexOf(delegate) != -1) { 218 cc.ArrayRemoveObject(this._handlersToRemove, delegate); 219 return; 220 } 221 222 this._handlersToAdd.push(handler); 223 this._toAdd = true; 224 } 225 }, 226 227 /** 228 * Force add handler 229 * @param {cc.TouchHandler} handler 230 * @param {Array} array 231 * @return {Array} 232 */ 233 forceAddHandler:function (handler, array) { 234 var u = 0; 235 236 for (var i = 0; i < array.length; i++) { 237 var h = array[i]; 238 if (h) { 239 if (h.getPriority() < handler.getPriority()) { 240 ++u; 241 } 242 if (h.getDelegate() == handler.getDelegate()) { 243 cc.Assert(0, "TouchDispatcher.forceAddHandler()"); 244 return array; 245 } 246 } 247 } 248 return cc.ArrayAppendObjectToIndex(array, handler, u); 249 }, 250 251 /** 252 * Force remove all delegates 253 */ 254 forceRemoveAllDelegates:function () { 255 this._standardHandlers.length = 0; 256 this._targetedHandlers.length = 0; 257 }, 258 259 /** 260 * Removes a touch delegate. 261 * The delegate will be released 262 * @param {cc.TouchDelegate} delegate 263 */ 264 removeDelegate:function (delegate) { 265 if (delegate == null) { 266 return; 267 } 268 269 if (!this._locked) { 270 this.forceRemoveDelegate(delegate); 271 } else { 272 /* 273 * If handler is contained in m_pHandlersToAdd, if so remove it from m_pHandlersToAdd and return. 274 */ 275 var handler = this.findHandler(this._handlersToAdd, delegate); 276 if (handler) { 277 cc.ArrayRemoveObject(this._handlersToAdd, handler); 278 return; 279 } 280 281 this._handlersToRemove.push(delegate); 282 this._toRemove = true; 283 } 284 }, 285 286 /** 287 * Removes all touch delegates, releasing all the delegates 288 */ 289 removeAllDelegates:function () { 290 if (!this._locked) { 291 this.forceRemoveAllDelegates(); 292 } else { 293 this._toQuit = true; 294 } 295 }, 296 297 /** 298 * Changes the priority of a previously added delegate. The lower the number, the higher the priority 299 * @param {Number} priority 300 * @param {cc.TouchDelegate} delegate 301 */ 302 setPriority:function (priority, delegate) { 303 cc.Assert(delegate != null, "TouchDispatcher.setPriority():Arguments is null"); 304 305 var handler = this.findHandler(delegate); 306 307 cc.Assert(handler != null, "TouchDispatcher.setPriority():Cant find TouchHandler"); 308 309 if (handler.getPriority() != priority) { 310 handler.setPriority(priority); 311 312 this.rearrangeHandlers(this._targetedHandlers); 313 this.rearrangeHandlers(this._standardHandlers); 314 } 315 }, 316 317 /** 318 * @param {Array} touches 319 * @param {event} event 320 * @param {Number} index 321 */ 322 touches:function (touches, event, index) { 323 cc.Assert(index >= 0 && index < 4, "TouchDispatcher.touches()"); 324 325 this._locked = true; 326 327 // optimization to prevent a mutable copy when it is not necessary 328 var targetedHandlersCount = this._targetedHandlers.length; 329 var standardHandlersCount = this._standardHandlers.length; 330 var needsMutableSet = (targetedHandlersCount && standardHandlersCount); 331 332 var mutableTouches = (needsMutableSet ? touches.slice() : touches); 333 var helper = this._handlerHelperData[index]; 334 // 335 // process the target handlers 1st 336 // 337 if (targetedHandlersCount > 0) { 338 var touch; 339 for (var i = 0; i < touches.length; i++) { 340 touch = touches[i]; 341 var handler; 342 343 for (var j = 0; j < this._targetedHandlers.length; j++) { 344 handler = this._targetedHandlers[j]; 345 346 if (!handler) { 347 break; 348 } 349 350 var claimed = false; 351 if (index == cc.TOUCH_BEGAN) { 352 if (handler.getDelegate().onTouchBegan) { 353 claimed = handler.getDelegate().onTouchBegan(touch, event); 354 355 if (claimed) { 356 handler.getClaimedTouches().push(touch); 357 } 358 } 359 //} else if (handler.getClaimedTouches().indexOf(touch)> -1){ 360 } else if (handler.getClaimedTouches().length > 0) { 361 // moved ended cancelled 362 claimed = true; 363 switch (helper.type) { 364 case cc.TOUCH_MOVED: 365 if (cc.Browser.isMobile) { 366 if (handler.getDelegate().onTouchMoved) 367 handler.getDelegate().onTouchMoved(touch, event); 368 } else { 369 if (this._mousePressed) 370 if (handler.getDelegate().onTouchMoved) 371 handler.getDelegate().onTouchMoved(touch, event); 372 } 373 break; 374 case cc.TOUCH_ENDED: 375 if (handler.getDelegate().onTouchEnded) 376 handler.getDelegate().onTouchEnded(touch, event); 377 handler.getClaimedTouches().length = 0; 378 //cc.ArrayRemoveObject(handler.getClaimedTouches(),touch); 379 break; 380 case cc.TOUCH_CANCELLED: 381 if (handler.getDelegate().onTouchCancelled) 382 handler.getDelegate().onTouchCancelled(touch, event); 383 handler.getClaimedTouches().length = 0; 384 //cc.ArrayRemoveObject(handler.getClaimedTouches(),touch); 385 break; 386 } 387 } 388 389 if (claimed && handler.isSwallowsTouches()) { 390 if (needsMutableSet) { 391 cc.ArrayRemoveObject(mutableTouches, touch); 392 } 393 break; 394 } 395 } 396 } 397 } 398 399 // 400 // process standard handlers 2nd 401 // 402 if (standardHandlersCount > 0) { 403 for (i = 0; i < this._standardHandlers.length; i++) { 404 handler = this._standardHandlers[i]; 405 406 if (!handler) { 407 break; 408 } 409 410 switch (helper.type) { 411 case cc.TOUCH_BEGAN: 412 if (mutableTouches.length > 0) { 413 if (handler.getDelegate().onTouchesBegan) 414 handler.getDelegate().onTouchesBegan(mutableTouches, event); 415 } 416 break; 417 case cc.TOUCH_MOVED: 418 if (mutableTouches.length > 0) { 419 if (cc.Browser.isMobile) { 420 if (handler.getDelegate().onTouchesMoved) 421 handler.getDelegate().onTouchesMoved(mutableTouches, event); 422 } else { 423 if (this._mousePressed) 424 if (handler.getDelegate().onTouchesMoved) 425 handler.getDelegate().onTouchesMoved(mutableTouches, event); 426 } 427 } 428 break; 429 case cc.TOUCH_ENDED: 430 if (handler.getDelegate().onTouchesEnded) 431 handler.getDelegate().onTouchesEnded(mutableTouches, event); 432 break; 433 case cc.TOUCH_CANCELLED: 434 if (handler.getDelegate().onTouchesCancelled) 435 handler.getDelegate().onTouchesCancelled(mutableTouches, event); 436 break; 437 } 438 } 439 } 440 441 if (needsMutableSet) { 442 mutableTouches = null; 443 } 444 445 // 446 // Optimization. To prevent a [handlers copy] which is expensive 447 // the add/removes/quit is done after the iterations 448 // 449 this._locked = false; 450 if (this._toRemove) { 451 this._toRemove = false; 452 for (i = 0; i < this._handlersToRemove.length; i++) { 453 this.forceRemoveDelegate(this._handlersToRemove[i]); 454 } 455 this._handlersToRemove.length = 0; 456 } 457 458 if (this._toAdd) { 459 this._toAdd = false; 460 461 for (i = 0; i < this._handlersToAdd.length; i++) { 462 handler = this._handlersToAdd[i]; 463 if (!handler) { 464 break; 465 } 466 467 if (handler instanceof cc.TargetedTouchHandler) { 468 this._targetedHandlers = this.forceAddHandler(handler, this._targetedHandlers); 469 } else { 470 this._standardHandlers = this.forceAddHandler(handler, this._standardHandlers); 471 } 472 } 473 this._handlersToAdd.length = 0; 474 } 475 476 if (this._toQuit) { 477 this._toQuit = false; 478 this.forceRemoveAllDelegates(); 479 } 480 }, 481 482 /** 483 * @param {Array} touches 484 * @param {event} event 485 */ 486 touchesBegan:function (touches, event) { 487 if (this._dispatchEvents) { 488 this.touches(touches, event, cc.TOUCH_BEGAN); 489 } 490 }, 491 492 /** 493 * @param {Array} touches 494 * @param {event} event 495 */ 496 touchesMoved:function (touches, event) { 497 if (this._dispatchEvents) { 498 this.touches(touches, event, cc.TOUCH_MOVED); 499 } 500 }, 501 502 /** 503 * @param {Array} touches 504 * @param {event} event 505 */ 506 touchesEnded:function (touches, event) { 507 if (this._dispatchEvents) { 508 this.touches(touches, event, cc.TOUCH_ENDED); 509 } 510 }, 511 512 /** 513 * @param {Array} touches 514 * @param {event} event 515 */ 516 touchesCancelled:function (touches, event) { 517 if (this._dispatchEvents) { 518 this.touches(touches, event, cc.TOUCH_CANCELLED); 519 } 520 }, 521 522 /** 523 * @param {Array||cc.TouchDelegate} array array or delegate 524 * @param {cc.TouchDelegate} delegate 525 * @return {cc.TargetedTouchHandler|cc.StandardTouchHandler|Null} 526 */ 527 findHandler:function (array, delegate) { 528 switch (arguments.length) { 529 case 1: 530 delegate = arguments[0]; 531 for (var i = 0; i < this._targetedHandlers.length; i++) { 532 if (this._targetedHandlers[i].getDelegate() == delegate) { 533 return this._targetedHandlers[i]; 534 } 535 } 536 for (i = 0; i < this._standardHandlers.length; i++) { 537 if (this._standardHandlers[i].getDelegate() == delegate) { 538 return this._standardHandlers[i]; 539 } 540 } 541 return null; 542 break; 543 case 2: 544 cc.Assert(array != null && delegate != null, "TouchDispatcher.findHandler():Arguments is null"); 545 546 for (i = 0; i < array.length; i++) { 547 if (array[i].getDelegate() == delegate) { 548 return array[i]; 549 } 550 } 551 552 return null; 553 break; 554 default: 555 throw "Argument must be non-nil "; 556 break; 557 } 558 }, 559 560 /** 561 * @param {cc.TouchDelegate} delegate 562 */ 563 forceRemoveDelegate:function (delegate) { 564 var handler; 565 // XXX: remove it from both handlers ??? 566 // remove handler from m_pStandardHandlers 567 for (var i = 0; i < this._standardHandlers.length; i++) { 568 handler = this._standardHandlers[i]; 569 if (handler && handler.getDelegate() == delegate) { 570 cc.ArrayRemoveObject(this._standardHandlers, handler); 571 break; 572 } 573 } 574 575 for (i = 0; i < this._targetedHandlers.length; i++) { 576 handler = this._targetedHandlers[i]; 577 if (handler && handler.getDelegate() == delegate) { 578 cc.ArrayRemoveObject(this._targetedHandlers, handler); 579 break; 580 } 581 } 582 }, 583 584 /** 585 * @param {Array} array 586 */ 587 rearrangeHandlers:function (array) { 588 array.sort(cc.less); 589 } 590 }); 591 592 /** 593 * @type {cc.Point} 594 */ 595 cc.TouchDispatcher.preTouchPoint = cc.p(0, 0); 596 597 cc.TouchDispatcher.isRegisterEvent = false; 598 599 cc.getHTMLElementPosition = function (element) { 600 var pos = null; 601 if (element instanceof HTMLCanvasElement) { 602 pos = {left:0, top:0, width:element.width, height:element.height}; 603 } else { 604 pos = {left:0, top:0, width:parseInt(element.style.width), height:parseInt(element.style.height)}; 605 } 606 while (element != null) { 607 pos.left += element.offsetLeft; 608 pos.top += element.offsetTop; 609 element = element.offsetParent; 610 } 611 return pos; 612 }; 613 614 cc.ProcessMouseupEvent = function (element, event) { 615 var pos = cc.getHTMLElementPosition(element); 616 617 var tx = event.pageX; 618 var ty = event.pageY; 619 620 var mouseX = (tx - pos.left) / cc.Director.getInstance().getContentScaleFactor(); 621 var mouseY = (pos.height - (ty - pos.top)) / cc.Director.getInstance().getContentScaleFactor(); 622 623 var touch = new cc.Touch(mouseX, mouseY); 624 touch._setPrevPoint(cc.TouchDispatcher.preTouchPoint.x, cc.TouchDispatcher.preTouchPoint.y); 625 cc.TouchDispatcher.preTouchPoint.x = mouseX; 626 cc.TouchDispatcher.preTouchPoint.y = mouseY; 627 628 var posArr = []; 629 posArr.push(touch); 630 cc.Director.getInstance().getTouchDispatcher().touchesEnded(posArr, null); 631 }; 632 /** 633 * @param {HTMLCanvasElement|HTMLDivElement} element 634 */ 635 cc.TouchDispatcher.registerHtmlElementEvent = function (element) { 636 if (cc.TouchDispatcher.isRegisterEvent) 637 return; 638 639 if (!cc.Browser.isMobile) { 640 window.addEventListener('mousedown', function (event) { 641 cc.Director.getInstance().getTouchDispatcher()._setMousePressed(true); 642 }); 643 644 window.addEventListener('mouseup', function (event) { 645 cc.Director.getInstance().getTouchDispatcher()._setMousePressed(false); 646 647 var pos = cc.getHTMLElementPosition(element); 648 649 var tx = event.pageX; 650 var ty = event.pageY; 651 652 if (!cc.rectContainsPoint(new cc.Rect(pos.left, pos.top, pos.width, pos.height), cc.p(tx, ty))) { 653 var mouseX = (tx - pos.left) / cc.Director.getInstance().getContentScaleFactor(); 654 var mouseY = (pos.height - (ty - pos.top)) / cc.Director.getInstance().getContentScaleFactor(); 655 656 var touch = new cc.Touch(mouseX, mouseY); 657 touch._setPrevPoint(cc.TouchDispatcher.preTouchPoint.x, cc.TouchDispatcher.preTouchPoint.y); 658 cc.TouchDispatcher.preTouchPoint.x = mouseX; 659 cc.TouchDispatcher.preTouchPoint.y = mouseY; 660 661 var posArr = []; 662 posArr.push(touch); 663 cc.Director.getInstance().getTouchDispatcher().touchesEnded(posArr, null); 664 } 665 }); 666 667 //register canvas mouse event 668 element.addEventListener("mousedown", function (event) { 669 var pos = cc.getHTMLElementPosition(element); 670 671 var tx = event.pageX; 672 var ty = event.pageY; 673 674 var mouseX = (tx - pos.left) / cc.Director.getInstance().getContentScaleFactor(); 675 var mouseY = (pos.height - (ty - pos.top)) / cc.Director.getInstance().getContentScaleFactor(); 676 677 var touch = new cc.Touch(mouseX, mouseY); 678 touch._setPrevPoint(cc.TouchDispatcher.preTouchPoint.x, cc.TouchDispatcher.preTouchPoint.y); 679 cc.TouchDispatcher.preTouchPoint.x = mouseX; 680 cc.TouchDispatcher.preTouchPoint.y = mouseY; 681 682 var posArr = []; 683 posArr.push(touch); 684 cc.Director.getInstance().getTouchDispatcher().touchesBegan(posArr, null); 685 }); 686 687 element.addEventListener("mouseup", function (event) { 688 cc.ProcessMouseupEvent(element, event); 689 }); 690 691 element.addEventListener("mousemove", function (event) { 692 var pos = cc.getHTMLElementPosition(element); 693 694 var tx = event.pageX; 695 var ty = event.pageY; 696 697 var mouseX = (tx - pos.left) / cc.Director.getInstance().getContentScaleFactor(); 698 var mouseY = (pos.height - (ty - pos.top)) / cc.Director.getInstance().getContentScaleFactor(); 699 700 var touch = new cc.Touch(mouseX, mouseY); 701 702 //TODO this feature only chrome support 703 //if((event.button == 0) && (event.which == 1)) 704 // touch._setPressed(true); 705 706 touch._setPrevPoint(cc.TouchDispatcher.preTouchPoint.x, cc.TouchDispatcher.preTouchPoint.y); 707 cc.TouchDispatcher.preTouchPoint.x = mouseX; 708 cc.TouchDispatcher.preTouchPoint.y = mouseY; 709 710 var posArr = []; 711 posArr.push(touch); 712 713 cc.Director.getInstance().getTouchDispatcher().touchesMoved(posArr, null); 714 }); 715 } else { 716 //register canvas touch event 717 element.addEventListener("touchstart", function (event) { 718 if (!event.touches) 719 return; 720 721 var posArr = []; 722 var pos = cc.getHTMLElementPosition(element); 723 724 pos.left -= document.body.scrollLeft; 725 pos.top -= document.body.scrollTop; 726 for (var i = 0; i < event.touches.length; i++) { 727 var tx = event.touches[i].pageX; 728 var ty = event.touches[i].pageY; 729 if (event.touches[i]) { 730 tx = event.touches[i].clientX; 731 ty = event.touches[i].clientY; 732 } 733 var mouseX = (tx - pos.left) / cc.Director.getInstance().getContentScaleFactor(); 734 var mouseY = (pos.height - (ty - pos.top)) / cc.Director.getInstance().getContentScaleFactor(); 735 var touch = null; 736 if (event.touches[i].hasOwnProperty("identifier")) 737 touch = new cc.Touch(mouseX, mouseY, event.touches[i].identifier); 738 else 739 touch = new cc.Touch(mouseX, mouseY); 740 741 touch._setPrevPoint(cc.TouchDispatcher.preTouchPoint.x, cc.TouchDispatcher.preTouchPoint.y); 742 cc.TouchDispatcher.preTouchPoint.x = mouseX; 743 cc.TouchDispatcher.preTouchPoint.y = mouseY; 744 745 posArr.push(touch); 746 } 747 cc.Director.getInstance().getTouchDispatcher().touchesBegan(posArr, null); 748 event.stopPropagation(); 749 event.preventDefault(); 750 }, false); 751 752 element.addEventListener("touchmove", function (event) { 753 if (!event.touches) 754 return; 755 756 var posArr = []; 757 var pos = cc.getHTMLElementPosition(element); 758 759 pos.left -= document.body.scrollLeft; 760 pos.top -= document.body.scrollTop; 761 for (var i = 0; i < event.touches.length; i++) { 762 var tx = event.touches[i].pageX; 763 var ty = event.touches[i].pageY; 764 if (event.touches[i]) { 765 tx = event.touches[i].clientX; 766 ty = event.touches[i].clientY; 767 } 768 var mouseX = (tx - pos.left) / cc.Director.getInstance().getContentScaleFactor(); 769 var mouseY = (pos.height - (ty - pos.top)) / cc.Director.getInstance().getContentScaleFactor(); 770 771 var touch = null; 772 if (event.touches[i].hasOwnProperty("identifier")) 773 touch = new cc.Touch(mouseX, mouseY, event.touches[i].identifier); 774 else 775 touch = new cc.Touch(mouseX, mouseY); 776 touch._setPrevPoint(cc.TouchDispatcher.preTouchPoint.x, cc.TouchDispatcher.preTouchPoint.y); 777 cc.TouchDispatcher.preTouchPoint.x = mouseX; 778 cc.TouchDispatcher.preTouchPoint.y = mouseY; 779 780 posArr.push(touch); 781 } 782 cc.Director.getInstance().getTouchDispatcher().touchesMoved(posArr, null); 783 event.stopPropagation(); 784 event.preventDefault(); 785 }, false); 786 787 element.addEventListener("touchend", function (event) { 788 if (!event.touches) 789 return; 790 791 var posArr = []; 792 var pos = cc.getHTMLElementPosition(element); 793 794 pos.left -= document.body.scrollLeft; 795 pos.top -= document.body.scrollTop; 796 797 var fireTouches = event.touches; 798 if (!fireTouches || (fireTouches.length == 0)) { 799 fireTouches = event.changedTouches; 800 } 801 for (var i = 0; i < fireTouches.length; i++) { 802 var tx = fireTouches[i].pageX; 803 var ty = fireTouches[i].pageY; 804 if (fireTouches[i]) { 805 tx = fireTouches[i].clientX; 806 ty = fireTouches[i].clientY; 807 } 808 809 var mouseX = (tx - pos.left) / cc.Director.getInstance().getContentScaleFactor(); 810 var mouseY = (pos.height - (ty - pos.top)) / cc.Director.getInstance().getContentScaleFactor(); 811 812 var touch = null; 813 if (fireTouches[i].hasOwnProperty("identifier")) 814 touch = new cc.Touch(mouseX, mouseY, fireTouches[i].identifier); 815 else 816 touch = new cc.Touch(mouseX, mouseY); 817 818 touch._setPrevPoint(cc.TouchDispatcher.preTouchPoint.x, cc.TouchDispatcher.preTouchPoint.y); 819 cc.TouchDispatcher.preTouchPoint.x = mouseX; 820 cc.TouchDispatcher.preTouchPoint.y = mouseY; 821 822 posArr.push(touch); 823 } 824 cc.Director.getInstance().getTouchDispatcher().touchesEnded(posArr, null); 825 event.stopPropagation(); 826 event.preventDefault(); 827 }, false); 828 829 element.addEventListener("touchcancel", function (event) { 830 if (!event.touches) 831 return; 832 833 var posArr = []; 834 var pos = cc.getHTMLElementPosition(element); 835 836 pos.left -= document.body.scrollLeft; 837 pos.top -= document.body.scrollTop; 838 839 for (var i = 0; i < event.touches.length; i++) { 840 var tx = event.touches[i].pageX; 841 var ty = event.touches[i].pageY; 842 if (event.touches[i]) { 843 tx = event.touches[i].clientX; 844 ty = event.touches[i].clientY; 845 } 846 var mouseX = (tx - pos.left) / cc.Director.getInstance().getContentScaleFactor(); 847 var mouseY = (pos.height - (ty - pos.top)) / cc.Director.getInstance().getContentScaleFactor(); 848 849 var touch = null; 850 if (event.touches[i].hasOwnProperty("identifier")) 851 touch = new cc.Touch(mouseX, mouseY, event.touches[i].identifier); 852 else 853 touch = new cc.Touch(mouseX, mouseY); 854 touch._setPrevPoint(cc.TouchDispatcher.preTouchPoint.x, cc.TouchDispatcher.preTouchPoint.y); 855 cc.TouchDispatcher.preTouchPoint.x = mouseX; 856 cc.TouchDispatcher.preTouchPoint.y = mouseY; 857 858 posArr.push(touch); 859 } 860 cc.Director.getInstance().getTouchDispatcher().touchesCancelled(posArr, null); 861 event.stopPropagation(); 862 event.preventDefault(); 863 }, false); 864 } 865 866 cc.TouchDispatcher.isRegisterEvent = true; 867 }; 868