Categories
Uncategorized

Learning systems cocos2d-x cocos (1)

Analysis of HelloWorld scene

Previously used cocos2d-x 3.14 time, HelloWorld scene is not a class, but a class layer, when the HelloWorld :: createScene () is so long

Scene* HelloWorld::createScene()
{
    auto scene = Scene::create();
    auto layer = HelloWorld::create();
    scene->addChild(layer);
    return scene;
}

And now 3.17 HelloWorld :: createScene () so long

Scene* HelloWorld::createScene()
{
    return HelloWorld::create();
}

HelloWorld difference is itself a scene, the scene and then no further generates a scenario HelloWorld added as child nodes

HelloWorld layout

HelloWorld场景中有一个cocos的logo,一个关闭按钮,一个HelloWorld的字样,这些小物体都是在HelloWorld::init()中生成的

Initialize the base class

Before we add things to the HelloWorld scene, you need to call the base class initialization function Scene class, and then get it visibleSize and spare origin

bool HelloWorld::init()
{

    if ( !Scene::init() )
    {
        return false;
    }
    auto visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
.................
}

Close generate button

bool HelloWorld::init()
{
.................
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));

    float x = origin.x + visibleSize.width - closeItem->getContentSize().width/2;
    float y = origin.y + closeItem->getContentSize().height/2;
    closeItem->setPosition(Vec2(x,y));

    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);
.................
}

Here is the code may look complicated, it is not true, we can find a lot of objects in cocos will create using this static factory method at the time of generation, HelloWorld this scene is no exception, create game objects will generate parameters needed to fill into returns a pointer to an object constructed

MenuItemImage creation

MenuItemImage create method passed in the default state of the close button of the picture, click on the close button at the picture and a status callback, the callback refers to a procedure for the button is pressed to make a response to this event, add a macro using CC_CALLBACK_1 void function pointer member functions (T :: *) (Ref *) type and calling the object’s member function pointers to a callback, do not understand it does not matter, we write like shining
    Value is then calculated x and y coordinates of the button which is the lower right corner, getContentSize () to get the size of the object, and using the coordinates of the button setting setPosition

Menu creation

Note that the buttons are not directly added to the scene, the need to rely on the menu button, which is the Menu object, so we create a menu that contains a closeItem, and set the coordinates (0,0), and finally to use addChild to add menu to the scene

Font generation

bool HelloWorld::init()
{
.................
    auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
    label->setPosition(Vec2(origin.x + visibleSize.width/2,
                                origin.y + visibleSize.height - label->getContentSize().height));
    this->addChild(label, 1);
.................
}

This is also well understood, createWithTTF Label returns a pointer to the object, the display character string, font and font size as a parameter, is added to the scene addChild used, 1-0 high level here, we try to text coordinates provided to the center of the scene

bool HelloWorld::init()
{
.................
    auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
    label->setPosition(Vec2(origin.x + visibleSize.width/2,
                                origin.y + visibleSize.height/2));
    this->addChild(label, 1);
.................
}

Text in the logo above, the higher the proof layers, rendering the more later, the first rendering is pressed after rendering objects below

Generation wizard

bool HelloWorld::init()
{
.................
    auto sprite = Sprite::create("HelloWorld.png");
    sprite->setPosition(Vec2(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));
    this->addChild(sprite, 0);
    return true;
.................
}

This is even easier, use a wizard to generate a picture, it is also added to the scene, and finally remember to return true, if the init function does not return true, then the program will collapse out of

Depth exploration HelloWorld scene

I always thought cocos2dx learning c ++ is a very good teaching, cocos2dx use a lot of object-oriented features, characteristics c ++, there are some design patterns of thinking, a great help for the comprehensive growth of a novice programmer

Where the game begins

First of all, entrance is runWithScene game scene director class, open AppDelegate.cpp, find AppDelegate :: applicationDidFinishLaunching () function, we can see code

bool AppDelegate::applicationDidFinishLaunching() {
    auto director = Director::getInstance();
..............
    auto scene = HelloWorld::createScene();

    director->runWithScene(scene);

    return true;
}

Director class is a singleton class, it can be obtained using the getInstance instance, Singleton is actually through the privatization of the constructor, the access to objects to achieve a static function, usually we use lazy loading to use these kind of singleton, pull away, that Director uses the singleton pattern
    Director by runWithScene run HelloWorld scene, and let the child node HelloWorld HelloWorld and work

Node class

Node class is the base class for most of the scene HelloWorld class we use, in fact Scene class it is also a Node, a good understanding of the game world objects are in fact mostly Node, Node and Node linked through parent-child relationships, the model object of the game is a tree, use addChild parent node child node is added to manage their own sub-node queue, when the game is running, the director will traverse these node let them work, for example HelloWorld scene, HelloWorld the scene is the root node, the wizard sprite, text label, menu, menu HelloWorld is a child node, the button closeItem is a child node of the menu menu

Ref Class

Ref class is for reference counting classes, responsible for the object reference count, Ref class is the base class Node class, which means that all are using the Node cocos2dx reference counting memory management system memory management, which is why we the object is not generated by new and delete, but with reason create generated objects. Here’s knowledge related to the GC. In simple terms, reference counting method theory is that when the object is referenced, the object’s reference count will be +1, dereference when he -1, when the count is 0 when the objects will be destroyed interested can find out smart pointers and RAII

create

This function we can say that it is a factory, the factory we need to do to generate the object before the first work done in the very beginning of the article reached such a code

Scene* HelloWorld::createScene()
{
    return HelloWorld::create();
}

Then this is the HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Scene
{
public:
    static cocos2d::Scene* createScene();

    virtual bool init();
    
    void menuCloseCallback(cocos2d::Ref* pSender);
    
    CREATE_FUNC(HelloWorld);
};

#endif

Oh, wonder, why not see create function, is it in the base class? Ah Um, static member functions are not inherited, so the problem is on CREATE_FUNC, yes! We look at the definition of CREATE_FUNC

#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \
    __TYPE__ *pRet = new(std::nothrow) __TYPE__(); \
    if (pRet && pRet->init()) \
    { \
        pRet->autorelease(); \
        return pRet; \
    } \
    else \
    { \
        delete pRet; \
        pRet = nullptr; \
        return nullptr; \
    } \
}

Can be seen, CREATE_FUNC is one that will allow you lazy do not have to manually write create function macros
    Of course, some classes require custom create, for example, create the Sprite

Sprite* Sprite::create()
{
    Sprite *sprite = new (std::nothrow) Sprite();
    if (sprite && sprite->init())
    {
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}

create it in What operation?
    1. Using the new generation objects
    2. Use init to initialize the object
    3. Ref autorelease this class reference counting system to manage memory
    Init we see this is not to think of what HelloWorld scene layout is implemented in the init, and init, that is to say, by calling create the HelloWorld create when he had the text, buttons, sprites and other objects to create and added to the scene, and these objects are also created by create, that is, when the scene calls init will create all the items, so we are not a deeper understanding of the flow of the game cocos2dx
    Ref autorelease method is the class, look at its definition

Ref* Ref::autorelease()
{
    PoolManager::getInstance()->getCurrentPool()->addObject(this);
    return this;
}

Saw the getInstance, explained PoolManager is a singleton class, this code’s meaning is clear, Ref added to the current memory pool management
    We often need to create customized in the subsequent development, as long as we create to meet the above three functions can be

to sum up

This section we learned a lot of knowledge of a variety of small things, design patterns, GC, object structure of the game design ideas, as well as c ++ by studying cocos2dx new project comes HelloWorld code macro lazy with it, the macro protection to avoid duplication compile it
    Ok? What macro protection?

Macro protection

Here way to talk about protecting the little knowledge macro, the macro protection to avoid using .h file from being compiled, for example here in order to HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
............
#endif

# This is the beginning of the symbol code preprocessor, compiler before the program will carry out pre-processing work, which a few lines of code mean, if this symbol is not defined __HELLOWORLD_SCENE_H__ definition __HELLOWORLD_SCENE_H__ and compile the contents of up to endif, when __HELLOWORLD_SCENE_H__ be defined once, the next time the preprocessor encounters this pre-command when he does not then the following code as a compiler target, of course, now there is a #pragma once vs command, ensure that the file is only compiled once, we can also achieve our objective

Leave a Reply