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 /* to avoid flickr, nextScene MUST be here: after tick and before draw. 222 XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */ 223 if (this._nextScene) { 224 this.setNextScene(); 225 } 226 227 if (this._beforeVisitScene) 228 this._beforeVisitScene(); 229 230 // draw the scene 231 if (this._runningScene) { 232 if (renderer.childrenOrderDirty === true) { 233 cc.renderer.clearRenderCommands(); 234 cc.renderer.assignedZ = 0; 235 this._runningScene._renderCmd._curLevel = 0; //level start from 0; 236 this._runningScene.visit(); 237 renderer.resetFlag(); 238 } 239 else if (renderer.transformDirty() === true) { 240 renderer.transform(); 241 } 242 } 243 244 renderer.clear(); 245 246 // draw the notifications node 247 if (this._notificationNode) 248 this._notificationNode.visit(); 249 250 cc.eventManager.dispatchEvent(this._eventAfterVisit); 251 cc.g_NumberOfDraws = 0; 252 253 if (this._afterVisitScene) 254 this._afterVisitScene(); 255 256 renderer.rendering(cc._renderContext); 257 this._totalFrames++; 258 259 cc.eventManager.dispatchEvent(this._eventAfterDraw); 260 261 this._calculateMPF(); 262 }, 263 264 _beforeVisitScene: null, 265 _afterVisitScene: null, 266 267 /** 268 * End the life of director in the next frame 269 */ 270 end: function () { 271 this._purgeDirectorInNextLoop = true; 272 }, 273 274 /** 275 * Returns the size in pixels of the surface. It could be different than the screen size.<br/> 276 * High-res devices might have a higher surface size than the screen size. 277 * @return {Number} 278 */ 279 getContentScaleFactor: function () { 280 return this._contentScaleFactor; 281 }, 282 283 /** 284 * This object will be visited after the main scene is visited.<br/> 285 * This object MUST implement the "visit" selector.<br/> 286 * Useful to hook a notification object 287 * @return {cc.Node} 288 */ 289 getNotificationNode: function () { 290 return this._notificationNode; 291 }, 292 293 /** 294 * Returns the size of the WebGL view in points.<br/> 295 * It takes into account any possible rotation (device orientation) of the window 296 * @return {cc.Size} 297 */ 298 getWinSize: function () { 299 return cc.size(this._winSizeInPoints); 300 }, 301 302 /** 303 * Returns the size of the OpenGL view in pixels.<br/> 304 * It takes into account any possible rotation (device orientation) of the window.<br/> 305 * On Mac winSize and winSizeInPixels return the same value. 306 * @return {cc.Size} 307 */ 308 getWinSizeInPixels: function () { 309 return cc.size(this._winSizeInPoints.width * this._contentScaleFactor, this._winSizeInPoints.height * this._contentScaleFactor); 310 }, 311 312 /** 313 * getVisibleSize/getVisibleOrigin move to CCDirectorWebGL/CCDirectorCanvas 314 * getZEye move to CCDirectorWebGL 315 */ 316 317 /** 318 * Returns the visible size of the running scene 319 * @function 320 * @return {cc.Size} 321 */ 322 getVisibleSize: null, 323 324 /** 325 * Returns the visible origin of the running scene 326 * @function 327 * @return {cc.Point} 328 */ 329 getVisibleOrigin: null, 330 331 /** 332 * Returns the z eye, only available in WebGL mode 333 * @function 334 * @return {Number} 335 */ 336 getZEye: null, 337 338 /** 339 * Pause the director's ticker 340 */ 341 pause: function () { 342 if (this._paused) 343 return; 344 345 this._oldAnimationInterval = this._animationInterval; 346 // when paused, don't consume CPU 347 this.setAnimationInterval(1 / 4.0); 348 this._paused = true; 349 }, 350 351 /** 352 * Pops out a scene from the queue.<br/> 353 * This scene will replace the running one.<br/> 354 * The running scene will be deleted. If there are no more scenes in the stack the execution is terminated.<br/> 355 * ONLY call it if there is a running scene. 356 */ 357 popScene: function () { 358 359 cc.assert(this._runningScene, cc._LogInfos.Director_popScene); 360 361 this._scenesStack.pop(); 362 var c = this._scenesStack.length; 363 364 if (c === 0) 365 this.end(); 366 else { 367 this._sendCleanupToScene = true; 368 this._nextScene = this._scenesStack[c - 1]; 369 } 370 }, 371 372 /** 373 * Removes cached all cocos2d cached data. It will purge the cc.textureCache, cc.spriteFrameCache, cc.animationCache 374 */ 375 purgeCachedData: function () { 376 cc.animationCache._clear(); 377 cc.spriteFrameCache._clear(); 378 cc.textureCache._clear(); 379 }, 380 381 /** 382 * 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. 383 */ 384 purgeDirector: function () { 385 //cleanup scheduler 386 this.getScheduler().unscheduleAll(); 387 388 // Disable event dispatching 389 if (cc.eventManager) 390 cc.eventManager.setEnabled(false); 391 392 // don't release the event handlers 393 // They are needed in case the director is run again 394 395 if (this._runningScene) { 396 this._runningScene.onExitTransitionDidStart(); 397 this._runningScene.onExit(); 398 this._runningScene.cleanup(); 399 } 400 401 this._runningScene = null; 402 this._nextScene = null; 403 404 // remove all objects, but don't release it. 405 // runScene might be executed after 'end'. 406 this._scenesStack.length = 0; 407 408 this.stopAnimation(); 409 410 // Clear all caches 411 this.purgeCachedData(); 412 413 cc.checkGLErrorDebug(); 414 }, 415 416 /** 417 * Suspends the execution of the running scene, pushing it on the stack of suspended scenes.<br/> 418 * The new scene will be executed.<br/> 419 * Try to avoid big stacks of pushed scenes to reduce memory allocation.<br/> 420 * ONLY call it if there is a running scene. 421 * @param {cc.Scene} scene 422 */ 423 pushScene: function (scene) { 424 425 cc.assert(scene, cc._LogInfos.Director_pushScene); 426 427 this._sendCleanupToScene = false; 428 429 this._scenesStack.push(scene); 430 this._nextScene = scene; 431 }, 432 433 /** 434 * Run a scene. Replaces the running scene with a new one or enter the first scene. 435 * @param {cc.Scene} scene 436 */ 437 runScene: function (scene) { 438 439 cc.assert(scene, cc._LogInfos.Director_pushScene); 440 441 if (!this._runningScene) { 442 //start scene 443 this.pushScene(scene); 444 this.startAnimation(); 445 } else { 446 //replace scene 447 var i = this._scenesStack.length; 448 if (i === 0) { 449 this._sendCleanupToScene = true; 450 this._scenesStack[i] = scene; 451 this._nextScene = scene; 452 } else { 453 this._sendCleanupToScene = true; 454 this._scenesStack[i - 1] = scene; 455 this._nextScene = scene; 456 } 457 } 458 }, 459 460 /** 461 * Resume director after pause, if the current scene is not paused, nothing will happen. 462 */ 463 resume: function () { 464 if (!this._paused) { 465 return; 466 } 467 468 this.setAnimationInterval(this._oldAnimationInterval); 469 this._lastUpdate = Date.now(); 470 if (!this._lastUpdate) { 471 cc.log(cc._LogInfos.Director_resume); 472 } 473 474 this._paused = false; 475 this._deltaTime = 0; 476 }, 477 478 /** 479 * The size in pixels of the surface. It could be different than the screen size.<br/> 480 * High-res devices might have a higher surface size than the screen size. 481 * @param {Number} scaleFactor 482 */ 483 setContentScaleFactor: function (scaleFactor) { 484 if (scaleFactor !== this._contentScaleFactor) { 485 this._contentScaleFactor = scaleFactor; 486 } 487 }, 488 489 /** 490 * Enables or disables WebGL depth test.<br/> 491 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js 492 * @function 493 * @param {Boolean} on 494 */ 495 setDepthTest: null, 496 497 /** 498 * set color for clear screen.<br/> 499 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js 500 * @function 501 * @param {cc.Color} clearColor 502 */ 503 setClearColor: null, 504 /** 505 * Sets the default values based on the CCConfiguration info 506 */ 507 setDefaultValues: function () { 508 509 }, 510 511 /** 512 * Sets whether next delta time equals to zero 513 * @param {Boolean} nextDeltaTimeZero 514 */ 515 setNextDeltaTimeZero: function (nextDeltaTimeZero) { 516 this._nextDeltaTimeZero = nextDeltaTimeZero; 517 }, 518 519 /** 520 * Starts the registered next scene 521 */ 522 setNextScene: function () { 523 var runningIsTransition = false, newIsTransition = false; 524 if (cc.TransitionScene) { 525 runningIsTransition = this._runningScene ? this._runningScene instanceof cc.TransitionScene : false; 526 newIsTransition = this._nextScene ? this._nextScene instanceof cc.TransitionScene : false; 527 } 528 529 // If it is not a transition, call onExit/cleanup 530 if (!newIsTransition) { 531 var locRunningScene = this._runningScene; 532 if (locRunningScene) { 533 locRunningScene.onExitTransitionDidStart(); 534 locRunningScene.onExit(); 535 } 536 537 // issue #709. the root node (scene) should receive the cleanup message too 538 // otherwise it might be leaked. 539 if (this._sendCleanupToScene && locRunningScene) 540 locRunningScene.cleanup(); 541 } 542 543 this._runningScene = this._nextScene; 544 cc.renderer.childrenOrderDirty = true; 545 546 this._nextScene = null; 547 if ((!runningIsTransition) && (this._runningScene !== null)) { 548 this._runningScene.onEnter(); 549 this._runningScene.onEnterTransitionDidFinish(); 550 } 551 }, 552 553 /** 554 * Sets Notification Node 555 * @param {cc.Node} node 556 */ 557 setNotificationNode: function (node) { 558 cc.renderer.childrenOrderDirty = true; 559 if(this._notificationNode){ 560 this._notificationNode.onExitTransitionDidStart(); 561 this._notificationNode.onExit(); 562 this._notificationNode.cleanup(); 563 } 564 this._notificationNode = node; 565 if(!node) 566 return; 567 this._notificationNode.onEnter(); 568 this._notificationNode.onEnterTransitionDidFinish(); 569 }, 570 571 /** 572 * Returns the cc.director delegate. 573 * @return {cc.DirectorDelegate} 574 */ 575 getDelegate: function () { 576 return this._projectionDelegate; 577 }, 578 579 /** 580 * Sets the cc.director delegate. It shall implement the CCDirectorDelegate protocol 581 * @return {cc.DirectorDelegate} 582 */ 583 setDelegate: function (delegate) { 584 this._projectionDelegate = delegate; 585 }, 586 587 /** 588 * Sets the view, where everything is rendered, do not call this function.<br/> 589 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 590 * @function 591 * @param {cc.view} openGLView 592 */ 593 setOpenGLView: null, 594 595 /** 596 * Sets an OpenGL projection.<br/> 597 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 598 * @function 599 * @param {Number} projection 600 */ 601 setProjection: null, 602 603 /** 604 * Update the view port.<br/> 605 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 606 * @function 607 */ 608 setViewport: null, 609 610 /** 611 * Get the CCEGLView, where everything is rendered.<br/> 612 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 613 * @function 614 * @return {cc.view} 615 */ 616 getOpenGLView: null, 617 618 /** 619 * Sets an OpenGL projection.<br/> 620 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 621 * @function 622 * @return {Number} 623 */ 624 getProjection: null, 625 626 /** 627 * Enables/disables OpenGL alpha blending.<br/> 628 * Implementation can be found in CCDirectorCanvas.js/CCDirectorWebGL.js. 629 * @function 630 * @param {Boolean} on 631 */ 632 setAlphaBlending: null, 633 634 /** 635 * Returns whether or not the replaced scene will receive the cleanup message.<br> 636 * If the new scene is pushed, then the old scene won't receive the "cleanup" message.<br/> 637 * If the new scene replaces the old one, the it will receive the "cleanup" message. 638 * @return {Boolean} 639 */ 640 isSendCleanupToScene: function () { 641 return this._sendCleanupToScene; 642 }, 643 644 /** 645 * Returns current running Scene. Director can only run one Scene at the time 646 * @return {cc.Scene} 647 */ 648 getRunningScene: function () { 649 return this._runningScene; 650 }, 651 652 /** 653 * Returns the FPS value 654 * @return {Number} 655 */ 656 getAnimationInterval: function () { 657 return this._animationInterval; 658 }, 659 660 /** 661 * Returns whether or not to display the FPS informations 662 * @return {Boolean} 663 */ 664 isDisplayStats: function () { 665 return cc.profiler ? cc.profiler.isShowingStats() : false; 666 }, 667 668 /** 669 * Sets whether display the FPS on the bottom-left corner 670 * @param {Boolean} displayStats 671 */ 672 setDisplayStats: function (displayStats) { 673 if (cc.profiler) { 674 displayStats ? cc.profiler.showStats() : cc.profiler.hideStats(); 675 } 676 }, 677 678 /** 679 * Returns seconds per frame 680 * @return {Number} 681 */ 682 getSecondsPerFrame: function () { 683 return this._secondsPerFrame; 684 }, 685 686 /** 687 * Returns whether next delta time equals to zero 688 * @return {Boolean} 689 */ 690 isNextDeltaTimeZero: function () { 691 return this._nextDeltaTimeZero; 692 }, 693 694 /** 695 * Returns whether or not the Director is paused 696 * @return {Boolean} 697 */ 698 isPaused: function () { 699 return this._paused; 700 }, 701 702 /** 703 * Returns how many frames were called since the director started 704 * @return {Number} 705 */ 706 getTotalFrames: function () { 707 return this._totalFrames; 708 }, 709 710 /** 711 * Pops out all scenes from the queue until the root scene in the queue. <br/> 712 * This scene will replace the running one. <br/> 713 * Internally it will call "popToSceneStackLevel(1)" 714 */ 715 popToRootScene: function () { 716 this.popToSceneStackLevel(1); 717 }, 718 719 /** 720 * Pops out all scenes from the queue until it reaches "level". <br/> 721 * If level is 0, it will end the director. <br/> 722 * If level is 1, it will pop all scenes until it reaches to root scene. <br/> 723 * If level is <= than the current stack level, it won't do anything. 724 * @param {Number} level 725 */ 726 popToSceneStackLevel: function (level) { 727 cc.assert(this._runningScene, cc._LogInfos.Director_popToSceneStackLevel_2); 728 729 var locScenesStack = this._scenesStack; 730 var c = locScenesStack.length; 731 732 if (level === 0) { 733 this.end(); 734 return; 735 } 736 // stack overflow 737 if (level >= c) 738 return; 739 740 // pop stack until reaching desired level 741 while (c > level) { 742 var current = locScenesStack.pop(); 743 if (current.running) { 744 current.onExitTransitionDidStart(); 745 current.onExit(); 746 } 747 current.cleanup(); 748 c--; 749 } 750 this._nextScene = locScenesStack[locScenesStack.length - 1]; 751 this._sendCleanupToScene = true; 752 }, 753 754 /** 755 * Returns the cc.Scheduler associated with this director 756 * @return {cc.Scheduler} 757 */ 758 getScheduler: function () { 759 return this._scheduler; 760 }, 761 762 /** 763 * Sets the cc.Scheduler associated with this director 764 * @param {cc.Scheduler} scheduler 765 */ 766 setScheduler: function (scheduler) { 767 if (this._scheduler !== scheduler) { 768 this._scheduler = scheduler; 769 } 770 }, 771 772 /** 773 * Returns the cc.ActionManager associated with this director 774 * @return {cc.ActionManager} 775 */ 776 getActionManager: function () { 777 return this._actionManager; 778 }, 779 /** 780 * Sets the cc.ActionManager associated with this director 781 * @param {cc.ActionManager} actionManager 782 */ 783 setActionManager: function (actionManager) { 784 if (this._actionManager !== actionManager) { 785 this._actionManager = actionManager; 786 } 787 }, 788 789 /** 790 * Returns the delta time since last frame 791 * @return {Number} 792 */ 793 getDeltaTime: function () { 794 return this._deltaTime; 795 }, 796 797 _calculateMPF: function () { 798 var now = Date.now(); 799 this._secondsPerFrame = (now - this._lastUpdate) / 1000; 800 } 801 }); 802 803 /** 804 * The event projection changed of cc.Director 805 * @constant 806 * @type {string} 807 * @example 808 * cc.eventManager.addCustomListener(cc.Director.EVENT_PROJECTION_CHANGED, function(event) { 809 * cc.log("Projection changed."); 810 * }); 811 */ 812 cc.Director.EVENT_PROJECTION_CHANGED = "director_projection_changed"; 813 814 /** 815 * The event after update of cc.Director 816 * @constant 817 * @type {string} 818 * @example 819 * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_UPDATE, function(event) { 820 * cc.log("after update event."); 821 * }); 822 */ 823 cc.Director.EVENT_AFTER_UPDATE = "director_after_update"; 824 825 /** 826 * The event after visit of cc.Director 827 * @constant 828 * @type {string} 829 * @example 830 * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_VISIT, function(event) { 831 * cc.log("after visit event."); 832 * }); 833 */ 834 cc.Director.EVENT_AFTER_VISIT = "director_after_visit"; 835 836 /** 837 * The event after draw of cc.Director 838 * @constant 839 * @type {string} 840 * @example 841 * cc.eventManager.addCustomListener(cc.Director.EVENT_AFTER_DRAW, function(event) { 842 * cc.log("after draw event."); 843 * }); 844 */ 845 cc.Director.EVENT_AFTER_DRAW = "director_after_draw"; 846 847 /*************************************************** 848 * implementation of DisplayLinkDirector 849 **************************************************/ 850 cc.DisplayLinkDirector = cc.Director.extend(/** @lends cc.Director# */{ 851 invalid: false, 852 853 /** 854 * Starts Animation 855 */ 856 startAnimation: function () { 857 this._nextDeltaTimeZero = true; 858 this.invalid = false; 859 }, 860 861 /** 862 * Run main loop of director 863 */ 864 mainLoop: function () { 865 if (this._purgeDirectorInNextLoop) { 866 this._purgeDirectorInNextLoop = false; 867 this.purgeDirector(); 868 } 869 else if (!this.invalid) { 870 this.drawScene(); 871 } 872 }, 873 874 /** 875 * Stops animation 876 */ 877 stopAnimation: function () { 878 this.invalid = true; 879 }, 880 881 /** 882 * Sets animation interval 883 * @param {Number} value the animation interval desired 884 */ 885 setAnimationInterval: function (value) { 886 this._animationInterval = value; 887 if (!this.invalid) { 888 this.stopAnimation(); 889 this.startAnimation(); 890 } 891 } 892 }); 893 894 cc.Director.sharedDirector = null; 895 cc.Director.firstUseDirector = true; 896 897 cc.Director._getInstance = function () { 898 if (cc.Director.firstUseDirector) { 899 cc.Director.firstUseDirector = false; 900 cc.Director.sharedDirector = new cc.DisplayLinkDirector(); 901 cc.Director.sharedDirector.init(); 902 } 903 return cc.Director.sharedDirector; 904 }; 905 906 /** 907 * Default fps is 60 908 * @type {Number} 909 */ 910 cc.defaultFPS = 60; 911 912 //Possible OpenGL projections used by director 913 /** 914 * Constant for 2D projection (orthogonal projection) 915 * @constant 916 * @type {Number} 917 */ 918 cc.Director.PROJECTION_2D = 0; 919 920 /** 921 * Constant for 3D projection with a fovy=60, znear=0.5f and zfar=1500. 922 * @constant 923 * @type {Number} 924 */ 925 cc.Director.PROJECTION_3D = 1; 926 927 /** 928 * Constant for custom projection, if cc.Director's projection set to it, it calls "updateProjection" on the projection delegate. 929 * @constant 930 * @type {Number} 931 */ 932 cc.Director.PROJECTION_CUSTOM = 3; 933 934 /** 935 * Constant for default projection of cc.Director, default projection is 3D projection 936 * @constant 937 * @type {Number} 938 */ 939 cc.Director.PROJECTION_DEFAULT = cc.Director.PROJECTION_3D; 940