4
\$\begingroup\$

i'm trying to draw a continues spline on every onTouchMoved call, the functionality is supposed to be similar to the line drawing used in the iOS game - flight control.

i'm using it in the following manner:

constructor init:

conPointsArray = new PointArray();
conPointsArray->initWithCapacity(DEF_ARRAY_SIZE);
lineDrawer = DrawNode::create();

the onTouchMoved callback usage:

void line::onTouchMoved(cocos2d::Touch *Touch, cocos2d::Event *Event)
{
conPointsArray->addControlPoint(Touch->getLocation());
lineDrawer->drawCardinalSpline((conPointsArray), 0.5f, 100, Color4F::BLUE);
CCLOG("on touch moved x: %f y %f", Touch->getLocation().x, Touch->getLocation().y);
}

But the app is always crashing in a certain openGL function.

I assumed the reason for it is because the array is constantly changing and openGL is having trouble with it (and the fact i'm always sending the same array which is a bad idea, but just to see how things work), so i moved the drawing call to onTouchEnded, And indeed, The line was drawn, but only (as expected) after the onTouch action has ended.

What is the solution/best practice for this issue?

Cheers.

\$\endgroup\$
8
  • \$\begingroup\$ I don't know the answer but I prefer CCRenderTexture for drawing. \$\endgroup\$
    – Emadpres
    Commented Jan 7, 2015 at 15:02
  • \$\begingroup\$ @Emadpres, i believe it is deprecated, isn't it? \$\endgroup\$
    – Itzik984
    Commented Jan 7, 2015 at 15:07
  • \$\begingroup\$ if you are using v3.x RenderTexture is available. \$\endgroup\$
    – Emadpres
    Commented Jan 7, 2015 at 16:01
  • \$\begingroup\$ @Emadpres, Thanks, Just saw it. Didn't notice any spline methods that could help with drawing the lines, any ideas? \$\endgroup\$
    – Itzik984
    Commented Jan 7, 2015 at 16:06
  • \$\begingroup\$ I don't know if I am in the same track with you, but I was creating an drawing app for kids and RenderTexture is best solution fo such applications. you can use visit() method of Sprite and draw(=visit) a point ( probably a circle sprite) on your canvas(=RenderTexture) while touch is moving(=onTouchMoved) \$\endgroup\$
    – Emadpres
    Commented Jan 7, 2015 at 18:48

2 Answers 2

1
\$\begingroup\$

I created an drawing app for kids and I think the RenderTexture is the best solution for such applications.

You can use visit() method of Sprite and draw(=visit) a point ( probably a circle sprite) on your canvas(=RenderTexture) while touch is moving(=onTouchMoved).

Don't forget to call RenderTexture->begin()/end() when using visit function.

This if for cocos2dx v2 but not so different with v3:

void PaintingScene::ccTouchesMoved(CCSet* touches, CCEvent* event)
{
    CCTouch *touch = (CCTouch*)touches->anyObject();
    brush->setPosition(touch->getLocation());
    RT_currentSession->begin(); //RT_currentSession : CCRenderTexture
    brush->setVisible(true);
    brush->visit(); 
    brush->setVisible(false);
    RT_currentSession->end();
}
\$\endgroup\$
1
  • \$\begingroup\$ It Works great, Thank you. There is one little issue i'm trying to solve, and its how to get a full line in case we have quick movements (saw some examples online, non of them work but using an array of brushes and drawing them, which kills the CPU), it's in the example i gave in the comments above. How did u solve it? \$\endgroup\$
    – Itzik984
    Commented Jan 7, 2015 at 23:21
0
\$\begingroup\$

Re:

"It Works great, Thank you. There is one little issue i'm trying to solve, and its how to get a full line in case we have quick movements (saw some examples online, non of them work but using an array of brushes and drawing them, which kills the CPU), it's in the example i gave in the comments above. How did u solve it?"

I use a different language and software, so the code below is more psuedocode, than code. You will need to properly type the position parameter of doIt, etc. The idea should be "gettable"; if not, let me know. initialPoint is set to true in the TouchDown callback (or possibly TouchUp).

Consider:

void doIt(position)
{
  brush->setPosition(position);
  brush->setVisible(true);
  brush->visit(); 
  brush->setVisible(false);
}
void PaintingScene::ccTouchesMoved(CCSet* touches, CCEvent* event)
{
   RT_currentSession->begin(); //RT_currentSession : CCRenderTexture
   touchLocation = touch->getLocation();
   if (initialPoint)
   {
     previousTouchLocation = touchLocation;
     initialPoint = false;
   }
   dragDistance = distance(touchLocation - previousTouchLocation);
   for (i = 0; i <= dragDistance; i++)
   {
     //doIt(previousTouchLocation + ((touchLocation - previousTouchLocation) * (float)i / dragDistance)));
     //doIt(lerp(previousTouchLocation, touchLocation, (float)i / dragDistance));
     doIt(lerp(previousTouchLocation, touchLocation, i, dragDistance));
     //Linearly interpolate between previousTouchLocation and touchLocation
     //turning on each pixel along the way
   }
   RT_currentSession->end();
   previousTouchLocation = touchLocation;
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .