Reza Ghobadinic

Node Creation

I will use the Node class in this post to demonstrate how to create one and how to use it in two simple examples.

Simple Example

Lets make a class that draws a simple shape on the screen and then move it around the screen to see how all these work!

#ifndef MyDrawNode_hpp
#define MyDrawNode_hpp

#include <stdio.h>
#include "cocos2d.h"

using namespace cocos2d;

class MyDrawNode:public Node
{
    bool isDrawn;
public:
    static Node* createNode();

    virtual bool init();
    virtual void draw(Renderer* renderer, const Mat4& transform, uint32_t flags);

    CREATE_FUNC(MyDrawNode); // Make the create function
};

#endif /* MyDrawNode_hpp */

As you can see, we have init and draw methods that are virtual and override the parent methods of the same names. In the init method we initialize the class. The draw method will be called on every frame to draw our shapes on the screen.

#include "MyDrawNode.hpp"


Node* MyDrawNode::createNode()
{
    return MyDrawNode::create(); // Create an instance of this class and return the pointer
}

bool MyDrawNode::init()
{
    if(!Node::init())
    {
        return false;
    }

    isDrawn = false;

    // Screen coordinates
    auto visibleSize = Director::getInstance()->getVisibleSize(); // Screen's visible size
    Vec2 origin = Director::getInstance()->getVisibleOrigin();    // Screen's visible origin
    
    // Calculating the center of the screen
    float cx = origin.x + visibleSize.width * 0.5;  // X for the center of the screen
    float cy = origin.y + visibleSize.height * 0.5; // Y for the center of the screen
    
    setPosition(cx, cy);

    return true;
}

void MyDrawNode::draw(Renderer* renderer, const Mat4& transform, uint32_t flags)
{
    if(!isDrawn)
    {
        auto draw = DrawNode::create(); // Create a drawNode object that draws simple shapes
        // Draw a rectangle
        draw->drawLine(Vec2(-100, -100), Vec2(-100, +100), Color4F(1.0, 1.0, 1.0, 1.0));
        draw->drawLine(Vec2(+100, -100), Vec2(+100, +100), Color4F(1.0, 1.0, 1.0, 1.0));
        draw->drawLine(Vec2(-100, -100), Vec2(+100, -100), Color4F(1.0, 1.0, 1.0, 1.0));
        draw->drawLine(Vec2(-100, +100), Vec2(+100, +100), Color4F(1.0, 1.0, 1.0, 1.0));
        addChild(draw);   // Parenting the drawn object to this node
        isDrawn = true;   // Should stop drawing on every frame
    }
}

The DrawNode class that I have used here is a Cocos2d-x class that draws basic shapes like, line, circle, point, etc…

If you don’t set the isDrawn to true, you will see that on every frame GL verts number increases on the screen which means on every frame four new lines are being added to the scene. This is not necessary and that is why we just want to draw these four lines once!

#include "MyDrawNode.hpp"
bool HelloWorld::init()
{
    if ( !Scene::init() )
    {
        return false;
    }

    auto mynode = MyDrawNode::create(); // Create an instance of MyDrawNode
    this->addChild(mynode);             // Add the instance to the parent

    return true;
}
static cocos2d::Size designResolutionSize = cocos2d::Size(1136, 640);

Download Source

Spirograph Example

Drawing a box is fine, but not very interesting. Now lets redo our MyDrawNode class to do something more fun than before.

#ifndef MyDrawNode_hpp
#define MyDrawNode_hpp

#include <stdio.h>
#include "cocos2d.h"

using namespace cocos2d;

class MyDrawNode:public Node
{
    Vec2 firstPoint;
    Vec2 secondPoint;
    
    float i;
    float radius1;
    float radius2;
    float multi;
    float delta;

public:
    static Node* createNode();
    
    virtual bool init();
    virtual void draw(Renderer* renderer, const Mat4& transform, uint32_t flags);
    
    CREATE_FUNC(MyDrawNode); // Make the create function
};

#endif /* MyDrawNode_hpp */
#include <iostream>
#include <cstdlib>

#include "MyDrawNode.hpp"

using namespace cocos2d;
using namespace std;

Node* MyDrawNode::createNode()
{
    return DrawNode::create(); // Create an instance of this class and return the pointer
}

bool MyDrawNode::init()
{
    if(!Node::init())
    {
        return false;
    }
    
    srand(time(NULL));
    
    i = 0;
    radius1 = rand() % 100 + 150; // Random between 150 to 250
    radius2 = rand() % 100 + 50; // Random between 50 to 150
    multi = 0.53;
    delta = 0.2;
    
    firstPoint = Vec2(0, 0);
    secondPoint = Vec2(0, 0);
    
    // Screen coordinates
    auto visibleSize = Director::getInstance()->getVisibleSize(); // Screen's visible size
    Vec2 origin = Director::getInstance()->getVisibleOrigin();    // Screen's visible origin
    
    // Calculating the center of the screen
    float cx = origin.x + visibleSize.width * 0.5;  // X for the center of the screen
    float cy = origin.y + visibleSize.height * 0.5; // Y for the center of the screen
    
    this->setPosition(cx, cy);
    
    return true;
}

void MyDrawNode::draw(Renderer* renderer, const Mat4& transform, uint32_t flags)
{
    secondPoint.x = radius1 * cos(i * multi) + radius2 * sin(i * 1.1); // Calculating X for the end point
    secondPoint.y = radius1 * sin(i * multi) + radius2 * cos(i * 1.1); // Calculating Y for the end point
    
    if (i < 800.0)
    {
        i += delta;
        
        if(firstPoint == Vec2(0,0))
            firstPoint = secondPoint;
        
        auto draw = DrawNode::create(); // Create a drawNode object that draws simple shapes
        draw->drawLine(firstPoint, secondPoint, Color4F(1.0, 1.0, 1.0, 1.0)); // Draw a line from the start point to the end point
        firstPoint = secondPoint;
        
        this->addChild(draw); // Parenting the drawn object to this node
    }
}
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Scene::init() )
    {
        return false;
    }

    auto mynode = MyDrawNode::create(); // Create an instance of MyDrawNode
    this->addChild(mynode);             // Add the instance to the parent

    return true;
}

Notice that the GL Verts count goes up as it draws the pattern. That is because on every frame we are adding a line that contains two new points.

Download Source

Next

Exit mobile version