Alphabet Tracing

Hi Developers :slight_smile:

I want to create an educational app where kids can learn to write alphabets.
I want user to trace with finger over the alphabet. when user drag finger. it fills up the empty image with a color. color shouldn’t go beyond the fill area.
i am thinking of using DrawNode, but i need different width fill. also draw shouldn’t fill outside the alphabet.
Any suggestion which technique is best and how to do it. i am doing this in cocos2d-x 3.16 c++.

17 PM

Flood fill and render texture.

1 Like

Using DrawSegment + ClippingNode with 0 alpha texture seems work.

1 Like

@slackmoehrle can you elaborate a little more on that? any code help would be much of a help :slight_smile:

@sevent7 I was also thinking of something like that. but cant figure out how to do it. Do you have any helping material like tutorial or something?

@slackmoehrle @sevent7
fellas! any further help?

Try this:

stencil = Sprite::create("stencilAlphabetB.png");
stencil->setPosition(AlphabetB->getPosition());

clip = ClippingNode::create(stencil);
clip->setAlphaThreshold(0.0f);
this->addChild(clip);

drawer = DrawNode::create();
clip->addChild(drawer);

in your touch moved draw:
drawer->drawDot(location, 20, Color4F::RED);

*stencilAlphabetB.png is a solid color alphabet image

1 Like

if it doesn’t work maybe it need to add child stencil
this->addChild(stencil); and set its opacity to 0.

1 Like

Thanks alot :slight_smile:
it worked perfectly

@sevent7 @slackmoehrle
i have another thing in which i need guidence.
i want to remove the drawer with animation effect like progress effect or in the reverse fashion i am writing.
see the images added below. Thats my ultimate goal to achieve.
ezgif-5-205a6677c3 ezgif-5-aca839ae83
See how it is being removed from the letter. when user pick up the finger in the middle i goes back with animation. and when user reset the completely written letter. both draw nodes go back with animation.

Well you know the boundaries of the letter. Fill it. Then reverse what you did. Store the points so you know what to undo.

i followed @sevent7 instructions. I have used drawDot() method to draw. But i can only use removeFromParent on drawer which completely removes the drawNode. Is there anyother way to do it? what you suggest? A sample code snippet would be a great help.

Well, off hand from the code you already used, I guess I would create a DrawNode for each and store it in a std::vector, add all to drawer node you already have. Then you can iterate through backwards and either remove or change the visibility of each. It isn’t the best way in my opinion, but given what you already have it would work.

1 Like

Got it !
i’ll try to do that. Meanwhile, as you said

What is the best approach to it. i can change my work to the best approach as it is in early stages. it would be very helpful to know if there are good approaches to do it for this project and for future work.

If it were me, I would check out flood fill algorithms. But, as always there are a lot of ways to solve problems. You need to do what you understand how to do. You can always re-factor later.

1 Like

Is it for tutorial? I think using drawnode will be a hard work for that case.
Can it be done with progress timer?

its not tutorial. User will follow lines and will drag finger accordingly and will write the letter.
How can i use progress timer here? need some explanations here.
Thanks

i have another road block.
if user starts moving his finger backwards right on the point where he has already drawn then it should erase what is drawn.
What should i do?
i was saving all drawDot in an array but when i try to get its content size and position i get 0.00. It is inherited from a Node so it should have some content size and position. But all i get is 0.00

Please Help @slackmoehrle @sevent7

I guess post updated code.

DrawNode* drawer = DrawNode::create();
        drawer->drawSegment(initPoint,point,23,Color4F::ORANGE);
        drawNodeArray.push_back(drawer);
        clip->addChild(drawer);
        this->addChild(clip);
        
        log("Draw ContentSize : %f, %f", drawer->getContentSize().width, drawer->getContentSize().height);

        log("Draw Position : %f, %f", drawer->getPositionX(), drawer->getPositionY());

It logs this output :

Draw ContentSize : 0.000000, 0.000000
Draw Position : 0.000000, 0.000000

clip is a ClippingNode