Cocos2d-X3.0 root question (9) ----- scene switching (TransitionScene) Source Code Analysis

Source: Internet
Author: User

Cocos2d-X3.0 root question (9) ----- scene switching (TransitionScene) Source Code Analysis
Copy code 1 class CC_DLL TransitionScene: public Scene 2 {3 public: 4/** Orientation Type used by some transitions 5 */6 enum class Orientation 7 {8 // An horizontal orientation where the Left is nearer 9 LEFT_OVER = 0, 10 // An horizontal orientation where the Right is nearer11 RIGHT_OVER = // A vertical orientation where the Up is nearer13 UP_OVER = // A vertica L orientation where the Bottom is nearer15 DOWN_OVER = 1,16}; 17 18/** creates a base transition with duration and incoming scene */19 static TransitionScene * create (float t, scene * scene); 20 21/** called after the transition finishes */22 void finish (void ); 23 24/** used by some transitions to hide the outer scene */25 void hideOutShowIn (void); 26 27 // 28 // Overrides29 // 30 virtual void draw (R Enderer * renderer, const kmMat4 & transform, bool transformUpdated) override; 31 virtual void onEnter () override; 32 virtual void onExit () override; 33 virtual void cleanup () override; 34 35 CC_CONSTRUCTOR_ACCESS: 36 TransitionScene (); 37 virtual ~ TransitionScene (); 38 39/** initializes a transition with duration and incoming scene */40 bool initWithDuration (float t, Scene * scene); 41 42 protected: 43 virtual void sceneOrder (); 44 void setNewScene (float dt); 45 46 Scene * _ inScene; 47 Scene * _ outScene; 48 float _ duration; 49 bool _ isInSceneOnTop; 50 bool _ isSendCleanupToScene; 51 52 private: 53 CC_DISALLOW_COPY_AND_ASSIGN (TransitionScene); 54}; Copying code this class does not Large. We can see from the Class header information inheritance relationship that the scenario switching class is actually a scenario. The old rule is to analyze the member variables first. The TransitionScene class has a total of five member variables. These five variables can be guessed from the variable name. 1 Scene * _ inScene; // The scenario pointer for scenario switching. 2 Scene * _ outScene; // The scenario pointer 3 float _ duration cut out by scenario switching; // The time required for scenario switching: 4 bool _ isInSceneOnTop; // The scene switching description specifies the rendering hierarchy between the scene and the scene. true indicates that the scene is at the top five bool _ isSendCleanupToScene of the scene; // indicates whether the clear command has been sent to the switch-out scenario. Here, we can guess what kind of process the TransitionScene class uses to implement scenario switching. TransitionScene is an intermediary scenario with the left hand side of the scenario to be switched in (_ inScene ), with the scene (_ outScene) to be switched out in the right hand, let the two scenes into the scene on their own to complete the process of switching in a gorgeous way, and finally exit the intermediary scenario, place the stage in a new scenario. We have guessed the principle of implementing scenario switching in TransitionScene. We are curious about the specific process of implementing scenario switching and scenario switching in TransitionScene? Are we guessing that the switching principle is correct? Let's continue to look at the source code to find the answer. We start with the method for creating TransitionScene. The constructor of TransitionScene is an empty function ignored. Let's take a look at the static method TransitionScene: Create to start analysis. Copy code 1 TransitionScene * TransitionScene: create (float t, Scene * scene) 2 {3 TransitionScene * pScene = new TransitionScene (); 4 if (pScene & pScene-> initWithDuration (t, scene) 5 {6 pScene-> autorelease (); 7 return pScene; 8} 9 CC_SAFE_DELETE (pScene ); 10 return nullptr; 11} copy the code to see the structure of the create FUNCTION familiar can no longer be familiar with, in the basic year of Cocos2d-x Node class and subclass creation is this structure. Next, let's take a look at the initWithDuration initialization method. Copy code 1 bool TransitionScene: initWithDuration (float t, Scene * scene) 2 {3 CCASSERT (scene! = Nullptr, "Argument scene must be non-nil"); 4 5 if (Scene: init () 6 {7 _ duration = t; 8 9 // retain10 _ inScene = scene; 11 _ inScene-> retain (); 12 _ outScene = Director: getInstance ()-> getRunningScene (); 13 if (_ outScene = nullptr) 14 {15 _ outScene = Scene: create (); 16} 17 _ outScene-> retain (); 18 19 CCASSERT (_ inScene! = _ OutScene, "Incoming scene must be different from the outgoing scene"); 20 21 sceneOrder (); 22 23 return true; 24} 25 else26 {27 return false; 28} 29} copy the code to judge from the parameter of this function. The purpose of this initialization function is, you can specify the duration of scenario switching and the scenario pointer to be switched to initialize an instance of a scenario switching mediation scenario (TransitionScene. The base class Scene initialization method is called during the initial process of the TransitionScene instance. Scene: init assigns _ duration = t to the passed-in duration parameter and _ inScene = scene to the cut-in scenario. Note that a reference to the cut-in scenario is added here, because a single cut-in scenario is referenced in the mediation scenario, a reference count is added. The output scenario value indicates that the current Director class is running through Director: getInstance ()-> getRunningScene (); we can get the value assigned to _ outScene for the currently running scenario. If there is no running scenario, an empty scenario will be created as the output scenario, in addition, a pair is added to the reference count of the scene. After the sceneOrder () function is called, the name of this function indicates that the scenario is sorted once. What have you done? The following is an analysis of sceneOrder. Void TransitionScene: sceneOrder () {_ isInSceneOnTop = true;} sceneOrder this is a virtual function. The process is simple, but the mark _ isInSceneOnTop is set, to specify the hierarchy between the scene and the scene. After creating a TransitionScene instance, we have analyzed how the scenario switching process is implemented. Take a look at the TransitionScene Class header file and find the following functions. Virtual void draw (Renderer * renderer, const kmMat4 & transform, bool transformUpdated) override; virtual void onEnter () override; virtual void onExit () override; virtual void cleanup () override; the role of the four functions in naming is to call the clearup clearing method when the draw Rendering Method onEnter mediation scenario enters the stage and the onExit mediation scenario exits the stage. For one analysis, read the onEnter copy code void TransitionScene: onEnter () {Scene: onEnter (); // disable events while transitions _ eventDispatcher-> setEnabled (false ); // outScene shocould not receive the onEnter callback // only the onExitTransitionDidStart _ outScene-> onExitTransitionDidStart (); _ inScene-> onEnter ();} copy code function Process Analysis: call the onEnter of the Scene base class to set the event distributor to unavailable. Scene switching is an animation process in which events are not processed to avoid unexpected errors. Call the onExitTransitionDidStart method of the cut-out scenario. Friends who have read the previous chapters should still be impressed. This method is defined in the Node base class, and the function meaning is the callback method at the beginning of Scene Change. When the intermediary scenario enters the stage, of course, this method is called here when the current scenario leaves. It makes sense to call the onEnter for the scenario. There is no problem at all. When the scenario is switched out, it begins to leave, this is the process in which the intermediary scenario is exchanged between the left and right hands. Let's look at the onExit method again. Copy the code void TransitionScene: onExit () {Scene: onExit (); // enable events while transitions _ eventDispatcher-> setEnabled (true); _ outScene-> onExit (); // _ inScene shocould not receive the onEnter callback // only the onEnterTransitionDidFinish _ inScene-> onEnterTransitionDidFinish ();} copying code function Process Analysis: calls the onExit method of the base class Scene. The availability of the event distributor is restored. Call the exit callback of the cut-out scenario. Call the complete callback of the switch-in scenario. We can compare the onEnter and onExit methods. Through analysis, we can understand the sequence of function calls from the scene to the stage. Here we will summarize it. Enter the stage ----> exit the stage. (The stage here can be understood as the area that can be displayed on the screen) onEnter (enter the stage) ---> onEnterTransitionDidFinish (enter complete) ---> onExitTransitionDidStart (start to exit the stage) ---> onExit (exit) understands the sequence of function calls for the scenario to enter the stage, so we can understand what the onExit and onEnter functions for the mediation scenario are doing. When an intermediary scenario enters the stage, it is precisely when the scenario is switched out and the scenario is switched into the stage. When the intermediary scenario begins, the scenario is switched into the stage and the scenario is switched out. At this time, both the mediation scenario and the scene were taken off the stage, leaving the scene to be switched. Next let's take a look at the other two virtual function copy code void TransitionScene: draw (Renderer * renderer, const kmMat4 & transform, bool transformUpdated) {Scene: draw (renderer, transform, transformUpdated); if (_ isInSceneOnTop) {_ outScene-> visit (renderer, transform, transformUpdated); _ inScene-> visit (renderer, transform, transformUpdated );} else {_ inScene-> visit (renderer, transform, transformUpdated); _ outScene-> visit (renderer, tra Nsform, transformUpdated) ;}} there is no difficulty in copying the code draw method, that is, based on the _ isInSceneOnTop record cut-in two scene hierarchies for separate rendering. Copy the code void TransitionScene: cleanup () {Scene: cleanup (); if (_ isSendCleanupToScene) _ outScene-> cleanup ();} the clearup method of the replication Code also calls other clearup methods and then clears the switch-out scenario based on whether the _ isSendCleanupToScene mark has been cleared in the cut-out scenario. Next let's take a look at TransitionScene's other methods to copy the code void TransitionScene: finish () {// clean up _ inScene-> setVisible (true ); _ inScene-> setPosition (Point (0, 0); _ inScene-> setScale (1.0f); _ inScene-> setRotation (0.0f); _ inScene-> setAdditionalTransform (nullptr ); _ outScene-> setVisible (false); _ outScene-> setPosition (Point (0, 0); _ outScene-> setScale (1.0f); _ outScene-> setRotation (0.0f ); _ outScene-> setAdditionalTransform (nullp Tr); // [self schedule: @ selector (setNewScene :) interval: 0]; this-> schedule (schedule_selector (TransitionScene: setNewScene), 0 );} copy the code to finish the method. You can see that the function process in the method called when the scenario switching is complete is also very simple. Set the switch-in scenario to display status, and the switch-out scenario is not displayed, in addition, the rotation, scaling, and position of the scenario are restored to the initial state. It is worth noting that the callback function is added to the timer TransitionScene: setNewScene. The callback interval is 0, that is, it will be called at the next frame. Next, let's take a look at what this setNewScene function does. Copy code void TransitionScene: setNewScene (float dt) {CC_UNUSED_PARAM (dt); this-> unschedule (schedule_selector (TransitionScene: setNewScene); // Before replacing, save the "send cleanup to scene" Director * director = Director: getInstance (); _ isSendCleanupToScene = director-> isSendCleanupToScene (); director-> replaceScene (_ inScene ); // issue #267 _ outScene-> setVisible (true);} copy the Code. This function has a parameter but is not used. It may be reserved. In this function, the Director class is used to clear the scene tag and assigned the Variable _ isSendCleanupToScene. Note this line of code director-> replaceScene (_ inScene); we know that Director manages the scenario and can only have one runningScene, this line of code actually gives the stage to the scenario (_ inScene) void TransitionScene: hideOutShowIn () {_ inScene-> setVisible (true) through ctor ); _ outScene-> setVisible (false);} The hideOutShowIn function hides the scene to show the cut-in scenario. There is nothing to say more. After analysis, we have analyzed all the methods in the TransitionScene class. We may have some questions but only analyzed the callbacks for some scenarios to cut into the stage and leave the stage, the process of switching those dynamic scenarios is not seen. How do intermediary scenarios enter the stage? How can I use an intermediary scenario for scenario switching? The finish function is not called, so it seems that the name is actually saved. With questions, we continue to look for answers in the source code. Let's see CCTransition. h In addition to TransitionScene, this header file also defines a number of TransitionScene class subclasses. Next we will select a class to analyze and copy the code/** @ brief TransitionRotoZoom: Rotate and zoom out the outgoing scene, and then rotate and zoom in the incoming */class CC_DLL TransitionRotoZoom: public TransitionScene {public: static TransitionRotoZoom * create (float t, Scene * scene ); //// Overrides // virtual void onEnter () override; protected: TransitionRotoZ Oom (); virtual ~ TransitionRotoZoom (); private: CC_DISALLOW_COPY_AND_ASSIGN (TransitionRotoZoom) ;}; copy the code and read the comments of this class. switch out the scene, zoom out, and move in. The TransitionRotoZoom class inherits the TransitionScene class and does not add any attributes and methods. Instead, the onEnter method is overloaded. What changes are there in onEnter? Follow-up code: copy the code void TransitionRotoZoom: onEnter () {TransitionScene: onEnter (); _ inScene-> setScale (0.001f); _ outScene-> setScale (1.0f ); _ inScene-> setAnchorPoint (Point (0.5f, 0.5f); _ outScene-> setAnchorPoint (Point (0.5f, 0.5f); ActionInterval * rotozoom = (ActionInterval *) (Sequence :: create (Spawn: create (ScaleBy: create (_ duration/2, 0.001f), RotateBy: create (_ duration/2,360*2), nullptr), DelayTime:: Create (_ duration/2), nullptr); _ outScene-> runAction (rotozoom); _ inScene-> runAction (Sequence: create (rotozoom-> reverse (), callFunc: create (CC_CALLBACK_0 (TransitionScene: finish, this), nullptr);} copy the code to see the onEnter implementation. It means so much. animation is mentioned in it, latency ....... Start analysis.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.