1 /**************************************************************************** 2 Copyright (c) 2008-2010 Ricardo Quesada 3 Copyright (c) 2011-2012 cocos2d-x.org 4 Copyright (c) 2013-2014 Chukong Technologies 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 cc.g_NumberOfDraws = 0; 28 29 cc.GLToClipTransform = function (transformOut) { 30 //var projection = new cc.math.Matrix4(); 31 //cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, projection); 32 cc.kmGLGetMatrix(cc.KM_GL_PROJECTION, transformOut); 33 34 var modelview = new cc.math.Matrix4(); 35 cc.kmGLGetMatrix(cc.KM_GL_MODELVIEW, modelview); 36 37 transformOut.multiply(modelview); 38 }; 39 //---------------------------------------------------------------------------------------------------------------------- 40 41 /** 42 * <p> 43 * ATTENTION: USE cc.director INSTEAD OF cc.Director.<br/> 44 * cc.director is a singleton object which manage your game's logic flow.<br/> 45 * Since the cc.director is a singleton, you don't need to call any constructor or create functions,<br/> 46 * the standard way to use it is by calling:<br/> 47 * - cc.director.methodName(); <br/> 48 * 49 * It creates and handle the main Window and manages how and when to execute the Scenes.<br/> 50 * <br/> 51 * The cc.director is also responsible for:<br/> 52 * - initializing the OpenGL context<br/> 53 * - setting the OpenGL pixel format (default on is RGB565)<br/> 54 * - setting the OpenGL pixel format (default on is RGB565)<br/> 55 * - setting the OpenGL buffer depth (default one is 0-bit)<br/> 56 - setting the color for clear screen (default one is BLACK)<br/> 57 * - setting the projection (default one is 3D)<br/> 58 * - setting the orientation (default one is Portrait)<br/> 59 * <br/> 60 * <br/> 61 * The cc.director also sets the default OpenGL context:<br/> 62 * - GL_TEXTURE_2D is enabled<br/> 63 * - GL_VERTEX_ARRAY is enabled<br/> 64 * - GL_COLOR_ARRAY is enabled<br/> 65 * - GL_TEXTURE_COORD_ARRAY is enabled<br/> 66 * </p> 67 * <p> 68 * cc.director also synchronizes timers with the refresh rate of the display.<br/> 69 * Features and Limitations:<br/> 70 * - Scheduled timers & drawing are synchronizes with the refresh rate of the display<br/> 71 * - Only supports animation intervals of 1/60 1/30 & 1/15<br/> 72 * </p> 73 * @class 74 * @name cc.Director 75 */ 76 cc.Director = cc.Class.extend(/** @lends cc.Director# */{ 77 //Variables 78 _landscape: false, 79 _nextDeltaTimeZero: false, 80 _paused: false, 81 _purgeDirectorInNextLoop: false, 82 _sendCleanupToScene: false, 83 _animationInterval: 0.0, 84 _oldAnimationInterval: 0.0, 85 _projection: 0, 86 _contentScaleFactor: 1.0, 87 88 _deltaTime: 0.0, 89 90 _winSizeInPoints: null, 91 92 _lastUpdate: null, 93 _nextScene: null, 94 _notificationNode: null, 95 _openGLView: null, 96 _scenesStack: null, 97 _projectionDelegate: null, 98 _runningScene: null, 99 100 _totalFrames: 0, 101 _secondsPerFrame: 0, 102 103 _dirtyRegion: null, 104 105 _scheduler: null, 106 _actionManager: null, 107 _eventProjectionChanged: null, 108 _eventAfterUpdate: null, 109 _eventAfterVisit: null, 110 _eventAfterDraw: null, 111 112 ctor: function () { 113 var self = this; 114 self._lastUpdate = Date.now(); 115 cc.eventManager.addCustomListener(cc.game.EVENT_SHOW, function () { 116 self._lastUpdate = Date.now(); 117 }); 118 }, 119 120 init: function () { 121 // scenes 122 this._oldAnimationInterval = this._animationInterval = 1.0 / cc.defaultFPS; 123 this._scenesStack = []; 124 // Set default projection (3D) 125 this._projection = cc.Director.PROJECTION_DEFAULT; 126 // projection delegate if "Custom" projection is used 127 this._projectionDelegate = null; 128 129 // FPS 130 this._totalFrames = 0; 131 this._lastUpdate = Date.now(); 132 133 //Paused? 134 this._paused = false; 135 136 //purge? 137 this._purgeDirectorInNextLoop = false; 138 139 this._winSizeInPoints = cc.size(0, 0); 140 141 this._openGLView = null; 142 this._contentScaleFactor = 1.0; 143 144 //scheduler 145 this._scheduler = new cc.Scheduler(); 146 //action manager 147 if(cc.ActionManager){ 148 this._actionManager = new cc.ActionManager(); 149 this._scheduler.scheduleUpdate(this._actionManager, cc.Scheduler.PRIORITY_SYSTEM, false); 150 }else{ 151 this._actionManager = null; 152 } 153 154 this._eventAfterUpdate = new cc.EventCustom(cc.Director.EVENT_AFTER_UPDATE); 155 this._eventAfterUpdate.setUserData(this); 156 this._eventAfterVisit = new cc.EventCustom(cc.Director.EVENT_AFTER_VISIT); 157 this._eventAfterVisit.setUserData(this); 158 this._eventAfterDraw = new cc.EventCustom(cc.Director.EVENT_AFTER_DRAW); 159 this._eventAfterDraw.setUserData(this); 160 this._eventProjectionChanged = new cc.EventCustom(cc.Director.EVENT_PROJECTION_CHANGED); 161 this._eventProjectionChanged.setUserData(this); 162 163 return true; 164 }, 165 166 /** 167 * calculates delta time since last time it was called 168 */ 169 calculateDeltaTime: function () { 170 var now = Date.now(); 171 172 // new delta time. 173 if (this._nextDeltaTimeZero) { 174 this._deltaTime = 0; 175 this._nextDeltaTimeZero = false; 176 } else { 177 this._deltaTime = (now - this._lastUpdate) / 1000; 178 } 179 180 if ((cc.game.config[cc.game.CONFIG_KEY.debugMode] > 0) && (this._deltaTime > 0.2)) 181 this._deltaTime = 1 / 60.0; 182 183 this._lastUpdate = now; 184 }, 185 186 /** 187 * Converts a view coordinate to an WebGL coordinate<br/> 188 * Useful to convert (multi) touches coordinates to the current layout (portrait or landscape)<br/> 189 * Implementation can be found in CCDirectorWebGL 190 * @function 191 * @param {cc.Point} uiPoint 192 * @return {cc.Point} 193 */ 194 convertToGL: null, 195 196 /** 197 * Converts an WebGL coordinate to a view coordinate<br/> 198 * Useful to convert node points to window points for calls such as glScissor<br/> 199 * Implementation can be found in CCDirectorWebGL 200 * @function 201 * @param {cc.Point} glPoint 202 * @return {cc.Point} 203 */ 204 convertToUI: null, 205 206 /** 207 * Draw the scene. This method is called every frame. Don't call it manually. 208 */ 209 drawScene: function () { 210 var renderer = cc.renderer; 211 212 // calculate "global" dt 213 this.calculateDeltaTime(); 214 215 //tick before glClear: issue #533 216 if (!this._paused) { 217 this._scheduler.update(this._deltaTime); 218 cc.eventManager.dispatchEvent(this._eventAfterUpdate); 219 } 220 221 renderer.clear(); 222 223 /* to avoid flickr, nextScene MUST be here: after tick and before draw. 224 XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */ 225 if (this._nextScene) { 226 this.setNextScene(); 227 } 228 229 if (this._beforeVisitScene) 230 this._beforeVisitScene(); 231 232 // draw the scene 233 if (this._runningScene) { 234 if (renderer.childrenOrderDirty === true) { 235 cc.renderer.clearRenderCommands(); 236 this._runningScene._renderCmd._curLevel = 0; //level start from 0; 237 this._runningScene.visit(); 238 renderer.resetFlag(); 239 } else if (renderer.transformDirty() === true) 240 renderer.transform(); 241 } 242 243 // draw the notifications node 244 if (this._notificationNode) 245 this._notificationNode.visit(); 246 247 cc.eventManager.dispatchEvent(this._eventAfterVisit); 248 cc.g_NumberOfDraws = 0; 249 250 if (this._afterVisitScene) 251 this._afterVisitScene(); 252 253 renderer.rendering(cc._renderContext); 254 this._totalFrames++; 255 256 cc.eventManager.dispatchEvent(this._eventAfterDraw); 257 258 this._calculateMPF(); 259 }, 260 261 _beforeVisitScene: null, 262 _afterVisitScene: null, 263 264 /** 265 * End the life of director in the next frame 266 */ 267 end: function () { 268 this._purgeDirectorInNextLoop = true; 269 }, 270 271 /** 272 * Returns the size in pixels of the surface. It could be different than the screen size.<br/> 273 * High-res devices might have a higher surface size than the screen size. 274 * @return {Number} 275 */ 276 getContentScaleFactor: function () { 277 return this._contentScaleFactor; 278 }, 279 280 /** 281 * This object will be visited after the main scene is visited.<br/> 282 * This object MUST implement the "visit" selector.<br/> 283 * Useful to hook a notification object 284 * @return {cc.Node} 285 */ 286 getNotificationNode: function () { 287 return this._notificationNode; 288 }, 289 290 /** 291 * Returns the size of the WebGL view in points.<br/> 292 * It takes into account any possible rotation (device orientation) of the window 293 * @return {cc.Size} 294 */ 295 getWinSize: function () { 296 return cc.size(this._winSizeInPoints); 297 }, 298 299 /** 300 * Returns the size of the OpenGL view in pixels.<br/> 301 * It takes into account any possible rotation (device orientation) of the window.<br/> 302 * On Mac winSize and winSizeInPixels return the same value. 303 * @return {cc.Size} 304 */ 305 getWinSizeInPixels: function () { 306 return cc.size(this._winSizeInPoints.width * this._contentScaleFactor, this._winSizeInPoints.height * this._contentScaleFactor); 307 }, 308 309 /** 310 * getVisibleSize/getVisibleOrigin move to CCDirectorWebGL/CCDirectorCanvas 311 * getZEye move to CCDirectorWebGL 312 */ 313 314 /** 315 * Returns the visible size of the running scene 316 * @function 317 * @return {cc.Size} 318 */ 319 getVisibleSize: null, 320 321 /** 322 * Returns the visible origin of the running scene 323 * @function 324 * @return {cc.Point} 325 */ 326 getVisibleOrigin: null, 327 328 /** 329 * Returns the z eye, only available in WebGL mode 330 * @function 331 * @return {Number} 332 */ 333 getZEye: null, 334 335 /** 336 * Pause the director's ticker 337 */ 338 pause: function () { 339 if (this._paused) 340 return; 341 342 this._oldAnimationInterval = this._animationInterval; 343 // when paused, don't consume CPU 344 this.setAnimationInterval(1 / 4.0); 345 this._paused = true; 346 }, 347 348 /** 349 * Pops out a scene from the queue.<br/> 350 * This scene will replace the running one.<br/> 351 * The running scene will be deleted. If there are no more scenes in the stack the execution is terminated.<br/> 352 * ONLY call it if there is a running scene. 353 */ 354 popScene: function () { 355 356 cc.assert(this._runningScene, cc._LogInfos.Director_popScene); 357 358 this._scenesStack.pop(); 359 var c = this._scenesStack.length; 360 361 if (c === 0) 362 this.end(); 363 else { 364 this._sendCleanupToScene = true; 365 this._nextScene = this._scenesStack[c - 1]; 366 } 367 }, 368 369 /** 370 * Removes cached all cocos2d cached data. It will purge the cc.textureCache, cc.spriteFrameCache, cc.animationCache 371 */ 372 purgeCachedData: function () { 373 cc.animationCache._clear(); 374 cc.spriteFrameCache._clear(); 375 cc.textureCache._clear(); 376 }, 377 378 /** 379 * Purge the cc.director itself, including unschedule all schedule, remove all event listeners, clean up and exit the running scene, stops all animations, clear cached data. 380 */ 381 purgeDirector: function () { 382 //cleanup scheduler 383 this.getScheduler().unscheduleAll(); 384 385 // Disable event dispatching 386 if (cc.eventManager) 387 cc.eventManager.setEnabled(false); 388 389 // don't release the event handlers 390 // They are needed in case the director is run again 391 392 if (this._runningScene) { 393 this._runningScene.onExitTransitionDidStart(); 394 this._runningScene.onExit(); 395 this._runningScene.cleanup(); 396 } 397 398 this._runningScene = null; 399 this._nextScene = null; 400 401 // remove all objects, but don't release it. 402 // runScene might be executed after 'end'. 403 this._scenesStack.length = 0; 404 405 this.stopAnimation(); 406 407 // Clear all caches 408 this.purgeCachedData(); 409 410 cc.checkGLErrorDebug(); 411 }, 412 413 /** 414 * Suspends the execution of the running scene, pushing it on the stack of suspended scenes.<br/> 415 * The new scene will be executed.<br/> 416 * Try to avoid big stacks of pushed scenes to reduce memory allocation.<br/> 417 * ONLY call it if there is a running scene. 418 * @param {cc.Scene} scene 419 */ 420 pushScene: function (scene) { 421 422 cc.assert(scene, cc._LogInfos.Director_pushScene); 423 424 this._sendCleanupToScene = false; 425 426 this._scenesStack.push(scene); 427 this._nextScene = scene; 428 }, 429 430 /** 431 * Run a scene. Replaces the running scene with a new one or enter the first scene. 432 * @param {cc.Scene} scene 433 */ 434 runScene: function (scene) { 435 436 cc.assert(scene, cc._LogInfos.Director_pushScene); 437 438 if (!this._runningScene) { 439 //start scene 440 this.pushScene(scene); 441 this.startAnimation(); 442 } else { 443 //replace scene 444 var i = this._scenesStack.length; 445 if (i === 0) { 446 this._sendCleanupToScene = true; 447 this._scenesStack[i] = scene; 448 this._nextScene = scene; 449 } else { 450 this._sendCleanupToScene = true; 451 this._scenesStack[i - 1] = scene; 452 this._nextScene = scene; 453 } 454 } 455 }, 456 457 /** 458 * Resume director after pause, if the current scene is not paused, nothing will happen. 459 */ 460 resume: function () { 461 if (!this._paused) { 462 return; 463 } 464 465 this.setAnimationInterval(this._oldAnimationInterval); 466 this._lastUpdate = Date.now(); 467 if (!this._lastUpdate) { 468 cc.log(cc._LogInfos.Director_resume); 469 } 470 471 this._paused = false; 472 this._deltaTime = 0; 473 }, 474 475 /** 476 * The size in pixels of the surface. It could be different than the screen size.<br/> 477 * High-res devices might have a higher surface size than the screen size. 478 * @param {Number} scaleFactor 479 */ 480 setContentScaleFactor: function (scaleFactor) { 481 if (scaleFactor !== this._contentScaleFactor) { 482 this._contentScaleFactor = scaleFactor; 483 } 484 }, 485 486 /** 487 * Enables or disables WebGL depth test.<br/> 488 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js 489 * @function 490 * @param {Boolean} on 491 */ 492 setDepthTest: null, 493 494 /** 495 * set color for clear screen.<br/> 496 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js 497 * @function 498 * @param {cc.color} clearColor 499 */ 500 setClearColor: null, 501 /** 502 * Sets the default values based on the CCConfiguration info 503 */ 504 setDefaultValues: function () { 505 506 }, 507 508 /** 509 * Sets whether next delta time equals to zero 510 * @param {Boolean} nextDeltaTimeZero 511 */ 512 setNextDeltaTimeZero: function (nextDeltaTimeZero) { 513 this._nextDeltaTimeZero = nextDeltaTimeZero; 514 }, 515 516 /** 517 * Starts the registered next scene 518 */ 519 setNextScene: function () { 520 var runningIsTransition = false, newIsTransition = false; 521 if (cc.TransitionScene) { 522 runningIsTransition = this._runningScene ? this._runningScene instanceof cc.TransitionScene : false; 523 newIsTransition = this._nextScene ? this._nextScene instanceof cc.TransitionScene : false; 524 } 525 526 // If it is not a transition, call onExit/cleanup 527 if (!newIsTransition) { 528 var locRunningScene = this._runningScene; 529 if (locRunningScene) { 530 locRunningScene.onExitTransitionDidStart(); 531 locRunningScene.onExit(); 532 } 533 534 // issue #709. the root node (scene) should receive the cleanup message too 535 // otherwise it might be leaked. 536 if (this._sendCleanupToScene && locRunningScene) 537 locRunningScene.cleanup(); 538 } 539 540 this._runningScene = this._nextScene; 541 cc.renderer.childrenOrderDirty = true; 542 543 this._nextScene = null; 544 if ((!runningIsTransition) && (this._runningScene !== null)) { 545 this._runningScene.onEnter(); 546 this._runningScene.onEnterTransitionDidFinish(); 547 } 548 }, 549 550 /** 551 * Sets Notification Node 552 * @param {cc.Node} node 553 */ 554 setNotificationNode: function (node) { 555 cc.renderer.childrenOrderDirty = true; 556 if(this._notificationNode){ 557 this._notificationNode.onExitTransitionDidStart(); 558 this._notificationNode.onExit(); 559 this._notificationNode.cleanup(); 560 } 561 this._notificationNode = node; 562 if(!node) 563 return; 564 this._notificationNode.onEnter(); 565 this._notificationNode.onEnterTransitionDidFinish(); 566 }, 567 568 /** 569 * Returns the cc.director delegate. 570 * @return {cc.DirectorDelegate} 571 */ 572 getDelegate: function () { 573 return this._projectionDelegate; 574 }, 575 576 /** 577 * Sets the cc.director delegate. It shall implement the CCDirectorDelegate protocol 578 * @return {cc.DirectorDelegate} 579 */ 580 setDelegate: function (delegate) { 581 this._projectionDelegate = delegate; 582 }, 583 584 /** 585 * Sets the view, where everything is rendered, do not call this function.<br/> 586 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 587 * @function 588 * @param {cc.view} openGLView 589 */ 590 setOpenGLView: null, 591 592 /** 593 * Sets an OpenGL projection.<br/> 594 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 595 * @function 596 * @param {Number} projection 597 */ 598 setProjection: null, 599 600 /** 601 * Update the view port.<br/> 602 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 603 * @function 604 */ 605 setViewport: null, 606 607 /** 608 * Get the CCEGLView, where everything is rendered.<br/> 609 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 610 * @function 611 * @return {cc.view} 612 */ 613 getOpenGLView: null, 614 615 /** 616 * Sets an OpenGL projection.<br/> 617 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 618 * @function 619 * @return {Number} 620 */ 621 getProjection: null, 622 623 /** 624 * Enables/disables OpenGL alpha blending.<br/> 625 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 626 * @function 627 * @param {Boolean} on 628 */ 629 setAlphaBlending: null, 630 631 /** 632 * Returns whether or not the replaced scene will receive the cleanup message.<br> 633 * If the new scene is pushed, then the old scene won't receive the "cleanup" message.<br/> 634 * If the new scene replaces the old one, the it will receive the "cleanup" message. 635 * @return {Boolean} 636 */ 637 isSendCleanupToScene: function () { 638 return this._sendCleanupToScene; 639 }, 640 641 /** 642 * Returns current running Scene. Director can only run one Scene at the time 643 * @return {cc.Scene} 644 */ 645 getRunningScene: function () { 646 return this._runningScene; 647 }, 648 649 /** 650 * Returns the FPS value 651 * @return {Number} 652 */ 653 getAnimationInterval: function () { 654 return this._animationInterval; 655 }, 656 657 /** 658 * Returns whether or not to display the FPS informations 659 * @return {Boolean} 660 */ 661 isDisplayStats: function () { 662 return cc.profiler ? cc.profiler.isShowingStats() : false; 663 }, 664 665 /** 666 * Sets whether display the FPS on the bottom-left corner 667 * @param {Boolean} displayStats 668 */ 669 setDisplayStats: function (displayStats) { 670 if (cc.profiler) { 671 displayStats ? cc.profiler.showStats() : cc.profiler.hideStats(); 672 } 673 }, 674 675 /** 676 * Returns seconds per frame 677 * @return {Number} 678 */ 679 getSecondsPerFrame: function () { 680 return this._secondsPerFrame; 681 }, 682 683 /** 684 * Returns whether next delta time equals to zero 685 * @return {Boolean} 686 */ 687 isNextDeltaTimeZero: function () { 688 return this._nextDeltaTimeZero; 689 }, 690 691 /** 692 * Returns whether or not the Director is paused 693 * @return {Boolean} 694 */ 695 isPaused: function () { 696 return this._paused; 697 }, 698 699 /** 700 * Returns how many frames were called since the director started 701 * @return {Number} 702 */ 703 getTotalFrames: function () { 704 return this._totalFrames; 705 }, 706 707 /** 708 * Pops out all scenes from the queue until the root scene in the queue. <br/> 709 * This scene will replace the running one. <br/> 710 * Internally it will call "popToSceneStackLevel(1)" 711 */ 712 popToRootScene: function () { 713 this.popToSceneStackLevel(1); 714 }, 715 716 /** 717 * Pops out all scenes from the queue until it reaches "level". <br/> 718 * If level is 0, it will end the director. <br/> 719 * If level is 1, it will pop all scenes until it reaches to root scene. <br/> 720 * If level is <= than the current stack level, it won't do anything. 721 * @param {Number} level 722 */ 723 popToSceneStackLevel: function (level) { 724 cc.assert(this._runningScene, cc._LogInfos.Director_popToSceneStackLevel_2); 725 726 var locScenesStack = this._scenesStack; 727 var c = locScenesStack.length; 728 729 if (level === 0) { 730 this.end(); 731 return; 732 } 733 // stack overflow 734 if (level >= c) 735 return; 736 737 // pop stack until reaching desired level 738 while (c > level) { 739 var current = locScenesStack.pop(); 740 if (current.running) { 741 current.onExitTransitionDidStart(); 742 current.onExit(); 743 } 744 current.cleanup(); 745 c--; 746 } 747 this._nextScene = locScenesStack[locScenesStack.length - 1]; 748 this._sendCleanupToScene = true; 749 }, 750 751 /** 752 * Returns the cc.Scheduler associated with this director 753 * @return {cc.Scheduler} 754 */ 755 getScheduler: function () { 756 return this._scheduler; 757 }, 758 759 /** 760 * Sets the cc.Scheduler associated with this director 761 * @param {cc.Scheduler} scheduler 762 */ 763 setScheduler: function (scheduler) { 764 if (this._scheduler !== scheduler) { 765 this._scheduler = scheduler; 766 } 767 }, 768 769 /** 770 * Returns the cc.ActionManager associated with this director 771 * @return {cc.ActionManager} 772 */ 773 getActionManager: function () { 774 return this._actionManager; 775 }, 776 /** 777 * Sets the cc.ActionManager associated with this director 778 * @param {cc.ActionManager} actionManager 779 */ 780 setActionManager: function (actionManager) { 781 if (this._actionManager !== actionManager) { 782 this._actionManager = actionManager; 783 } 784 }, 785 786 /** 787 * Returns the delta time since last frame 788 * @return {Number} 789 */ 790 getDeltaTime: function () { 791 return this._deltaTime; 792 }, 793 794 _calculateMPF: function () { 795 var now = Date.now(); 796 this._secondsPerFrame = (now - this._lastUpdate) / 1000; 797 } 798 }); 799 800 /** 801 * The event projection changed of cc.Director 802 * @constant 803 * @type {string} 804 * @example 805 * cc.eventManager.addCustomListener(cc.Director.EVENT_PROJECTION_CHANGED, function(event) { 806 * cc.log("Projection changed."); 807 * }); 808 */ 809 cc.Director.EVENT_PROJECTION_CHANGED = "director_projection_changed"; 810 811 /** 812 * The event after update of cc.Director 813 * @constant 814 * @type {string} 815 * @example 816 * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_UPDATE, function(event) { 817 * cc.log("after update event."); 818 * }); 819 */ 820 cc.Director.EVENT_AFTER_UPDATE = "director_after_update"; 821 822 /** 823 * The event after visit of cc.Director 824 * @constant 825 * @type {string} 826 * @example 827 * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_VISIT, function(event) { 828 * cc.log("after visit event."); 829 * }); 830 */ 831 cc.Director.EVENT_AFTER_VISIT = "director_after_visit"; 832 833 /** 834 * The event after draw of cc.Director 835 * @constant 836 * @type {string} 837 * @example 838 * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_DRAW, function(event) { 839 * cc.log("after draw event."); 840 * }); 841 */ 842 cc.Director.EVENT_AFTER_DRAW = "director_after_draw"; 843 844 /*************************************************** 845 * implementation of DisplayLinkDirector 846 **************************************************/ 847 cc.DisplayLinkDirector = cc.Director.extend(/** @lends cc.Director# */{ 848 invalid: false, 849 850 /** 851 * Starts Animation 852 */ 853 startAnimation: function () { 854 this._nextDeltaTimeZero = true; 855 this.invalid = false; 856 }, 857 858 /** 859 * Run main loop of director 860 */ 861 mainLoop: function () { 862 if (this._purgeDirectorInNextLoop) { 863 this._purgeDirectorInNextLoop = false; 864 this.purgeDirector(); 865 } 866 else if (!this.invalid) { 867 this.drawScene(); 868 } 869 }, 870 871 /** 872 * Stops animation 873 */ 874 stopAnimation: function () { 875 this.invalid = true; 876 }, 877 878 /** 879 * Sets animation interval 880 * @param {Number} value the animation interval desired 881 */ 882 setAnimationInterval: function (value) { 883 this._animationInterval = value; 884 if (!this.invalid) { 885 this.stopAnimation(); 886 this.startAnimation(); 887 } 888 } 889 }); 890 891 cc.Director.sharedDirector = null; 892 cc.Director.firstUseDirector = true; 893 894 cc.Director._getInstance = function () { 895 if (cc.Director.firstUseDirector) { 896 cc.Director.firstUseDirector = false; 897 cc.Director.sharedDirector = new cc.DisplayLinkDirector(); 898 cc.Director.sharedDirector.init(); 899 } 900 return cc.Director.sharedDirector; 901 }; 902 903 /** 904 * Default fps is 60 905 * @type {Number} 906 */ 907 cc.defaultFPS = 60; 908 909 //Possible OpenGL projections used by director 910 /** 911 * Constant for 2D projection (orthogonal projection) 912 * @constant 913 * @type {Number} 914 */ 915 cc.Director.PROJECTION_2D = 0; 916 917 /** 918 * Constant for 3D projection with a fovy=60, znear=0.5f and zfar=1500. 919 * @constant 920 * @type {Number} 921 */ 922 cc.Director.PROJECTION_3D = 1; 923 924 /** 925 * Constant for custom projection, if cc.Director's projection set to it, it calls "updateProjection" on the projection delegate. 926 * @constant 927 * @type {Number} 928 */ 929 cc.Director.PROJECTION_CUSTOM = 3; 930 931 /** 932 * Constant for default projection of cc.Director, default projection is 3D projection 933 * @constant 934 * @type {Number} 935 */ 936 cc.Director.PROJECTION_DEFAULT = cc.Director.PROJECTION_3D;