How to draw points above Sprite?

Firstly, I try to draw points on the layer when TouchMoved. And below is the code.

void GameLayer::onEnter() {
    LayerColor::onEnter();
    auto listener = EventListenerTouchOneByOne::create();
    listener->setSwallowTouches(true);
    listener->onTouchBegan = [=](cocos2d::Touch *touch, cocos2d::Event* event) {
        data.clear();
        this->data.push_back(touch->getLocation()); //data is a std::vector
        return true;
    };
    listener->onTouchMoved = CC_CALLBACK_2(GameLayer::onTouchMoved, this);
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
}

void GameLayer::onTouchMoved(Touch *touch, Event *event) {
    this->data.push_back(touch->getLocation());
}

void GameLayer::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) {
    DrawPrimitives::setPointSize(3.0f);
    for (int i = 0; i < data.size(); ++i) {
        DrawPrimitives::drawPoint(data.at(i));
    }
}

It works on the iPhone simulation, though I’m not sure whether there’s performance problem when running on a real iPhone.

And then I need a background.

auto *bg = Sprite::create("bg.png");
bg->setPosition(480, 320);
this->addChild(bg);

Unfortunately, the points don’t show anymore. So my question is that how can I draw the points above the background?

Thanks a lot.

Are you applying any soft of z order to your add child calls?

this->addChild(something, 0);
this->addChild(something2, 1);
this->addChild(something3, 2);

this would “layer” these, o being the back most, 2 being front most.

But if you want to add them above a sprite, it seems you could use the sprite.

Can you position them at the value of sprite->getContentSize().height + somePadding

I’ve tried to set the zindex but failed again.

Now the drawn points are replaced by Sprite, it works. Thank you.

v3.0 introduced the render queue. Now Node::draw method just puts the command to draw the Node into the queue which is fetched in the end of the frame.
In turn DrawPrimitves’s methods draw immediately. Thus when you call DrawPrimitives::drawSomething in Node::draw all your Nodes are drawn above the primiteves.
To draw primitives correctly, use CustomCommand. Check “cocos2d-x\tests\cpp-tests\Classes\DrawPrimitivesTest”

Thanks. But I find there’s still no examples about draw primitives above another sprite. Can you give me some guidance about that?

Wrap

    DrawPrimitives::setPointSize(3.0f);
    for (int i = 0; i < data.size(); ++i) {
        DrawPrimitives::drawPoint(data.at(i));
    }

into CustomCommand.

Should I put these codes into another layer?

Since when I add below code, it covered all the other sprites but only left a red line on the screen.

void GameLayer::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool transformUpdated) {
    _customCommand.init(_globalZOrder);
    _customCommand.func = CC_CALLBACK_0(GameLayer::onDraw, this, transform, transformUpdated);
    renderer->addCommand(&_customCommand);
}

void GameLayer::onDraw(const kmMat4 &transform, bool transformUpdated) {
    kmGLPushMatrix();
    kmGLLoadMatrix(&transform);
    
    printf("drawing\n");
    
    //draw
    DrawPrimitives::setDrawColor4B(255, 0, 0, 255);
    DrawPrimitives::drawLine(Point(0, 0), Point(200, 200));
    
    kmGLPopMatrix();
}
1 Like

Add Node::draw(renderer, transform, transformUpdated); at the beginning of the GameLayer::draw body.

like this? Still nothing.

void GameLayer::draw(cocos2d::Renderer *renderer, const kmMat4 &transform, bool transformUpdated) {
    Node::draw(renderer, transform, transformUpdated);
    _customCommand.init(_globalZOrder);
    _customCommand.func = CC_CALLBACK_0(GameLayer::onDraw, this, transform, transformUpdated);
    renderer->addCommand(&_customCommand);
}

void GameLayer::onDraw(const kmMat4 &transform, bool transformUpdated) {
    kmGLPushMatrix();
    kmGLLoadMatrix(&transform);
    
    printf("drawing\n");
    
    //draw
    DrawPrimitives::setDrawColor4B(255, 0, 0, 255);
    DrawPrimitives::drawLine(Point(0, 0), Point(200, 200));
    
    kmGLPopMatrix();
}

Try setting z-order value higher than the sprites’ ones here _customCommand.init(_globalZOrder);. _globalZOrder means the current z-order, thus the primmitives will be drawn in the same time with the GameLayer itself.

I set both the _customcommand and the sprite a big zorder value (9999) and it works. Thanks !