Cocos2d-x memory management, Object Construction, coordinates, Container Use

Source: Internet
Author: User

Cocos2d-x

Create a project

Cocos2d-x consists of several parts, some use static links, some are dynamic links, more direct source code distribution; coupled with the cross-platform properties of the project itself, need to write initialization code for different platforms; all in all, writing an empty project from scratch is quite tedious.

Therefore, the policy of the old version is to provide templates, scripts, and other things for development tools on different platforms to obtain the initial empty project each time. For example, it installs a cocos2d-x template for Visual Studio so that you can choose to create an empty cocos2d-x project for Visual C ++ directly in the new dialog box.

Of course, since version 2.1.4, the official version no longer provides templates for VS, and gradually uses a unified Python script on each platform to create cross-platform projects. (Tucao: although the template is not provided, but the original used to install the template of the install-templates-msvc.bat file is still, although a line of operation on the error said ......)

This creation script uses Python 2.xand has a Bug: use the current directory instead of the directory where the script file is located to find the template file (the develop version on GitHub has been fixed ). Therefore, to create a project, we need to first enter the tools/project-creator directory from the command line, and then use

Create_project.py-project <Project name>-Package <JavaPackage Name>-language <Language>

The corresponding project will be created under the projects directory. This prompt is displayed when you directly run create_project.py. (Version 3.0 will provide the cocos2d-x file in the create-multi-platform-projects.py root directory for indirect calls to tools/project-creator/create_project.py for you) so as an example, we can enter:

Create_project.py-projectWhatever-Package com.Timothyqiu.Whatever-Languagecpp

Ke: If you are confused about why the language is C ++ and you need to enter the "Java package name", you can see the directory structure of the generated project at a Glance:

Whatever-+-Classes

|-Resources

|-Proj. android

|-Proj. blackberry

|-Proj. ios

|-Proj. linux

|-Proj. mac

|-Proj. marmalade

'-Proj. win32

Very well structured: the platform-independent (self-written logic) Code is under the Classes directory; the Resources used by the program are under the Resources Directory; the code and engineering files related to other platforms (such as preset initialization) are in their respective directories.

Therefore, since the Android project is in place, the package name is obviously required during creation.

Rendering tree

If you are familiar with 3D, you may also be familiar with the concept of "rendering Tree": Adding nodes in the rendering tree can be rendered, the parent-child relationship of a node also affects its displacement, scaling, and rotation. The process of rendering an image is to traverse the entire rendering tree and draw nodes in sequence.

Nodes in the cocos2d-x, expressed as CCNode, provide scheduled callbacks and the ability to execute CCAction in addition to serving as nodes in the rendering tree. Of course, CCNode also encapsulates some basic attributes such as location, scaling, and rotation. Anchor Point is a very important attribute: what is the relationship between the node location and the position in the upper left corner and lower right corner of the node? Which point is used for scaling? Which node is the center of rotation? The answer to these questions is the anchor.

Properties of objects in the cocos2d-x are encapsulated using Getter/Setter in the form of setPropertyName (value), getPropertyName (), and isPropertyName. Common CCNode attributes are as follows:

·Location(Position) The default value is (0, 0), which is a CCPoint value.

·Rotate(Rotation) The default value is 0, and the clockwise angle is used.

·Zoom(Scale) The default value is 1.0f.

·Dimensions(ContentSize) The default value is (0, 0), which is a CCSize value.

·Visible(Visible) The default value is true. Invisible and non-existent are two different things.

·Anchor(AnchorPoint) is (0, 0) by default ). Each component is a floating point number. 0.0f indicates the upper left and 1.0f indicates the lower right (So 0.5f indicates the center point ). The value can also be out of the range of 0 and 1, indicating that the anchor is out of the node range.

In addition, there are three groups of tags, UserData, and UserObject, whose types are int, void *, and CCObject. They are all user-defined data for the node, and CCNode only saves it for your future acquisition, do not use it.

Some common subclasses of CCNode include:

· The CCScene scenario is generally used as the root node of the rendering tree.

· CCLayer layer, which is generally used as a Sprite container and can accept external input (such as touch events and accelerator)

· CCSprite genie, image Node

· CCMenu abstract menu. You can add the UI elements of CCMenuItem. It is derived from CCLayer.

For the purpose of saving the public from fire, the anchor points of the above sub-classes are set to (0.5, 0.5) by default ).

Most classes in p.s. cocos2d-x are prefixed with CC. But this is obviously the same as the namespace in cocos2d where they are located. Fortunately, these duplicate prefixes will be deleted in the future 3. X new versions.

No rule is not a square

Cocos2d-x based on OpenGL, so the use of the right hand Coordinate System: from left to right, from bottom to the axis of the square direction.

The CCPoint type mentioned above can be used to represent coordinate points or vectors. The CCSize type is similar to that used to represent dimensions. In addition, CCRect is a combination of CCPoint and CCSize, indicates the upper left corner and size of the rectangle area.

Because CCPoint and CCSize are essentially two float combinations, their constructors also need two float. Static_cast is explicitly removed from each input of different types of variables. Too much hand left, the cocos2d-x gives three corresponding macros to help you write the transformation: CCPointMake (x, y), CCSizeMake (w, h) and CCRectMake (x, y, w, h ). Of course, CCPoint is so common that it also has a macro ccp (x, y) that saves the number of keys ).

As mentioned above, the rotation attribute is an angle value. The cocos2d-x provides the conversion of CC_DEGREES_TO_RADIANS (deg) and CC_RADIANS_TO_DEGREES (rad) Macros in radians and degrees.

Memory Management

The cocos2d-x uses the Objective-C style from the cocos2d-iphone, not only in the Code style, but also in the memory management style.

Objective-C memory management uses (manual) reference counting technology. In short, it means that an object has one reference by default, retain () can be used to add a reference, and release () can be used to reduce a reference. Once the reference is reduced to 0, the object is automatically released.

You must have come up with a lot of implementation methods. However, in the current version, all objects are only bare pointers (for example, CCDirecter * ctor Ctor is essentially a pointer rather than an object, it seems that the only way to implement reference counting on this premise is that all objects inherit from the same root class, and this root class is responsible for reference counting. Of course, all objects should be created on the stack.

By the way, the current cocos2d-x version does not use smart pointers, one is because the cocos2d-iphone is so, two is because the cocos2d-x project was not finalized when C ++ 11 was started, the third reason is that the support conditions on mobile platforms were different at that time. However, the time has passed, and now 2013 is halfway through, the official has decided to introduce the smart pointer of C ++ 11 in the new version 3.0.

Root object

The root class that the cocos2d-x uses to provide the reference count function is CCObject. It focuses on these four functions:

· CCObject: CCObject ()

· CCObject: retain ()

· CCObject: release ()

· CCObject: autorelease ()

The first three statements are to set the reference count of the current object to one, add one, And subtract one. So what is the last autorelease?

By using the explanation in Objective-C: release () is the reference count.NowMinus one, while autorelease () isIn the near futureMinus one (at least after the current function ).

In the implementation of the cocos2d-x, the "Auto Release pool" object named CCAutoReleasePool is used. It will call the release () method of all objects it holds when it is released. CCObject: autorelease () adds itself to the Auto Release pool.

The cocos2d-x creates a CCAutoReleasePool at the beginning of each frame and releases it at the end of the frame. Therefore, all CCObject that has been called autorelease () has the opportunity to automatically release after the end of the current frame. (The reason is "have a chance", because even if release () is called, it only has a chance to release it. Whether it is actually released depends on the reference count .)

Therefore, the general summary is:

· Autorelease () or release () should exist for each new or retain () request ()

· Autorelease () is costly, so use release () whenever possible ()

Create and destroy

There is no use exception in the cocos2d-x, so the creation of the object uses a Two-step Constructor (Two-phase Construction ). The so-called two-step constructor is only used to assign initial values to the variable without executing the logic-related code. All the function code used for initialization writes an initialization function. (The constructor does not return values, so it can only communicate with the outside world with exceptions .)

CCSprite * sprite =NewCCSprite (); // create an object

Sprite-> initWithFile ("background.png"); // initialize the object

The above two rows are an example of the Two-Step constructor. Between such writing is quite tedious, The cocos2d-x provides a corresponding factory method for every initXXX () createXXX ():

CCSprite * sprite = CCSprite ::Create("Background.png ");

The implementation is simple:

CCSprite * pobSprite =NewCCSprite ();

If(PobSprite & pobSprite-> initWithFile (pszFileName )){

PobSprite-> autorelease ();

ReturnPobSprite;

}

CC_SAFE_DELETE (pobSprite );

Return NULL;

Have you noticed the autorelease? This means that if you only create () and do not perform any other operations, the object will be released at the end of this frame; but if you create () then, sprite-> retain () is called, so this object will not be automatically released (if this-> addChild (sprite) is used, because addChild () will indirectly call retain ()).

Note that this method also causes the parent class to fail to be automatically initialized. You must manually call the initXXX () method of the parent class in the initXXX () method of the subclass. As a result (if handwritten), the initialization is generally similar:

BoolHelloWorldLayer: init ()

{

BoolSuccess =False;

Do{

CC_BREAK_IF (! CCLayer: init ());

// Actual init code here, break if failed

Success =True;

}While(0 );

// Clean up if nescesary

ReturnSuccess;

}

Container

Because of the cocos2d-x's "special" memory management approach, STL containers that do not know anything about retain (), release () may not be suitable for you, so there is CCArray, CCSet, CCDirectory. (Storing bare pointers directly in STL containers may cause various troubles due to wild pointers. Of course, if you want to use smart pointers, you can save the corresponding std: shared_ptr to ensure that the objects contained in the lifecycle of the container are valid; the cocos2d-x in the future version of the introduction of intelligent pointer instead of Objective-C style memory management, a single deposit std: weak_ptr can detect the wild pointer .)

The containers provided by the cocos2d-x store all the CCObject objects (actually pointers, but since the correct method of use is only a pointer, so it will not be emphasized after convenience ). When an object enters the container, the container automatically calls retain () to obtain its reference. When the object is removed from the container or the container is destroyed, the container automatically calls release () to discard the reference.

This ensures that all objects in these containers are valid objects. (Remember CCAutoReleasePool? It is implemented using CCArray .)

In addition to adding and deleting containers, traversal is also commonly used. Unlike the iterator provided by STL, CCArray and CCDirectory are traversed using the For Each macro. (CCSet and STL are the same .)

CCObject * element =Nullptr;

CCARRAY_FOREACH (arrayOfSprites, element ){

AutoSprite =Dynamic_cast (Element );

//...

}

Director

The CCDirector class is the director class. There is only one director in each scene. Therefore, it is a single-piece class. All single-piece classes in the cocos2d-x get the CCName * single-piece object in a way similar to CCName: sharedName. This (naming) habit comes from the cocos2d-iphone, and in 3.X it will become a more convenient way of CCName: getInstance.

The director's main functions are scenario scheduling and game process control.

· RunWithScene () starts to run and sets the initial scenario.

· ReplaceScene () Switch scenario, old scenarios are not retained

· Common scenarios of pushScene () and popScene () stack Management

· Pause () pause the current scenario (some scenarios will still be drawn, but the logic will not be executed)

· Resume the current scenario

· End () stops running

Details

In the empty project provided by the SDK, in addition to the aforementioned "Big Data", there are also some minor details.

Portal

In fact, each proj. * directory has its own platform initialization code, which is similar to main.

In the Classes directory, in the platform-independent code, the program entry is the AppDelegate class. Yes, this class (still) comes from the cocos2d-iphone, specifically iOS, personally understand, this is a class used to receive program UI status messages.

The program uses the only three methods as its name implies: applicationDidFinishLaunching () applicationDidEnterBackground () applicationWillEnterForeground () to perceive its own status and respond. For example, the engine is initialized when Did finish launching, the background music is paused when Did enter background, the temporary storage status is paused, and the background music is restored when Will enter foreground.

In the existing "Empty Project", the core of applicationDidFinishLaunching () is actually the two sentences:

CCScene * pScene = HelloWorld: scene ();

PDirector-> RunWithScene (pScene );

It builds a bridge between AppDelegate and HelloWorld under the Classes Directory: Create the scenario and hand it over to the Director. Then the director takes care of his work.

Selector

In HelloWorld. cpp, we can see the following statement:

CCMenuItemImage * pCloseItem = CCMenuItemImage ::Create(

"CloseNormal.png", "CloseSelected.png ",

This, menu_selector (HelloWorld: menuCloseCallback)

);

What is the magic of this menu_selector?

Okay, this (yes, it's also) is from the cocos2d-iphone, let's look at the actual code (2.1.4 C style conversion looks uncomfortable, here, the C ++ style type conversion is slightly modified ):

Typedef void (CCObject: * SEL_MenuHandler) (CCObject *);

# Definemenu_selector (_ SELECTOR) static_cast (& _ SELECTOR)

You see, there is no big deal. All selector functions are just "member function pointer + forced type conversion". It and its previous parameter (CCObject *) specify a callback. (In retrospect, do you still remember how to define, initialize, and use member function pointers in C ++ ?)

Of course, in the near future, version 3.x will use more flexible std: function and std: bind to replace this kind of "selector 」.

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.