how to move a node or sprite without action?

how to move a node or sprite without action?
0.0 0


Hi there,
I want to move the sprite on fixed path with many control points,
1079,383 —> 1072,383 —> 1065,384 —-> ……

I can use the action moveto or moveby to do this, but i want to
try this without action, by using setPosition/setRotation in
update schedule function, of cause the sprite has velocity and
angel feature.

Is there any sample for this ? Thanks a lot.


If the sprite has velocity, what’s problem? Inherit CCSprite with some MegaCCSprite, declare: CCPoint pos, vel;
And in update cycle (schedule something):

float dt = CCDirector::getSharedDirector()->getDeltaTime();

vel.x = SPEED * dt;
= SPEED * dt;

pos.x = vel.x;
= vel.y;

SPEED is a constant, try to find it by hands.


@Max Frai

vel.x += SPEED * dt;
vel.y += SPEED * dt;

This is wrong. you have to calculate the speed component on y axis and speed component on x axis.

vel.x = SPEED * cos(angle) * dt;
vel.y = SPEED * sin(angle) * dt;


@Plato Manchi
Oh, yea, Monday’s morning :smiley:


Consider the case as shown in the image

“Starting Point” is the starting point and “Control Point” is next control point.
“angle” is the angle between x-axis and the line connecting start and control.
If sprite is at (x, y), in deltaTime sec the amount of distance traveled by sprite will be

float deltaDistanceTravelled = SPEED * dt;

the angel can be obtained by the formula

//consider that start, control are starting point and control point
float angel = atan2f( (control.y - start.y), (control.x - start.x) );

we have angle and deltaDistanceTravelled. so calculating deltaX and deltaY.

// cos( angel ) = adjacent side / hypotenuse;
// => adjacent side = hypotenuse * cos( angel )
float deltaX = deltaDistanceTravelled * cos( angel );
float deltaY = deltaDistanceTravelled * sin( angel );

the new position will be

float newX = currentX + deltaX;
float newY = currentY + deltaY;

Putting everything together into cocos2dx code using scheduler …
Control points can be saved using CCPointArray. (dont forget to retain, since you want the array to stay in memory.)

I did this in a basic helloworld project.

Inside init()

// creating and retaining a CCPointArray
this->mControlPoints = CCPointArray::create( 5 );

// adding some control points to the array
this->mControlPoints->addControlPoint( ccp(100, 100) );
this->mControlPoints->addControlPoint( ccp(40, 90) );
this->mControlPoints->addControlPoint( ccp(280, 160) );
this->mControlPoints->addControlPoint( ccp(380, 60) );

// initializing the totalDistanceToBeCovered to the
// distance between sprite's current position and the 1st control point
if( this->mControlPoints->count() > 0 )
        // calculating distanceSquare instead of distance,
        // because calculating sqrt(float) is costly operation on CPU (compared to multiplying)
    this->totalDistanceToBeCovered = distanceSquare(this->sprite->getPosition(), this->mControlPoints->getControlPointAtIndex(0));
    this->totalDistanceToBeCovered = 0.0f;

// this used to keep track of how much distance traveled by the sprite.
this->distanceCovered = 0.0f;

// totalDistanceToBeCovered and distanceCovered has to be initialized before
// scheduling the moveSprite function
this->schedule( schedule_selector(HelloWorld::moveSprite) );

and the moveSprite function is

void HelloWorld::moveSprite(float deltaTime){
    HelloWorld* thisScene = (HelloWorld*)this;

    // if there are no control points
    // then unschedule the function.
    if( thisScene->mControlPoints->count() == 0 ){
        thisScene->unschedule( schedule_selector(HelloWorld::moveSprite) );

    float speed = 100.0f; // pixels per second

    // getting the next control point to which
    // sprite should move
    CCPoint mNextDestination = thisScene->mControlPoints->getControlPointAtIndex( 0 );

    // current sprite position
    CCPoint mCurrentPosition = thisScene->sprite->getPosition();

    // calculating how much distance the sprite should travel
    // distance = velocity * time;
    float deltaDistanceTravelled = speed * deltaTime;

    // calculating the total distance covered by the sprite
    thisScene->distanceCovered += deltaDistanceTravelled;

    if( (thisScene->distanceCovered * thisScene->distanceCovered) < thisScene->totalDistanceToBeCovered ){
        // this means the sprite is still on its way towards the control point
        // see the image attached for reference on calculating deltaX and deltaY

        // calculating the angle btw next control point and the sprite
        // tan( angle ) = ( y2 - y1 ) / ( x2 - x1 );
        // angle = tanInverse( ( y2 - y1 ) / ( x2 - x1 ) );
        float angle = atan2f( (mNextDestination.y - mCurrentPosition.y), (mNextDestination.x - mCurrentPosition.x) );

        float deltaX = deltaDistanceTravelled * cos( angle );
        float deltaY = deltaDistanceTravelled * sin( angle );

        thisScene->sprite->setPosition( ccp(mCurrentPosition.x + deltaX, mCurrentPosition.y + deltaY) );
        // this means the sprite reached the control point
        thisScene->sprite->setPosition( mNextDestination );

        // removing the control point from the array of control points

        // since we just removed a point from array, making sure that array contains points
        if( thisScene->mControlPoints->count() > 0 ){
            // calculating the distance towards next control point
            thisScene->totalDistanceToBeCovered = distanceSquare(mNextDestination, thisScene->mControlPoints->getControlPointAtIndex(0));
            thisScene->distanceCovered = 0.0f;

I’m sure there will be another more better and faster way to do this. (atan2f is costly operation on CPU)
Please let me know if there is any.


Great answer. But anyway, I don’t see the reason to use trigonometry (including atan2f) if we can work with pure vector math which excludes this.


Sorry, but i have more confidence on trigonometry than on vectors. So i couldn’t think of way to do it using vectors.
I very much appreciate it if you can show how it can be done :slight_smile: