Public Group

# Moving sprite around point

This topic is 1436 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello guys,

I am trying to rotate a sprite around a specific point on the screen. I managed to do so and here is what I have so far:

My Enemy update function:

void Enemy::update()
{
moveInCircle(&position, 1, 100, 100, 100);

{


My function to move sprite around point:

void moveInCircle(Vector2D* enemyPos, float speed, int centerX, int centerY, int radius)
{
float speedScale = (0.001 * 2 * PI) / speed;
float angle = SDL_GetTicks() * speedScale;

}


However, I want to be able to rotate the sprite in a limited angle, instead of just moving ad infinitum and here is where I got stuck, how can I check how many degrees the sprite have moved? Maybe there is a better approach on the function 'moveInCircle' than the one I used?

lvenonl

##### Share on other sites

Maintain a separate variable for the enemy - e.g., float curAngle. Instead of calculating the angle, calculate a delta-angle.

Then:

float speedScale = (0.001 * 2 * PI) / speed;
float angle = SDL_GetTicks() * speedScale;

// determine if the incremented angle will still be within bounds
if( WithinBounds(enemy.curAngle + angle) ) // WithinBounds(float testAngle) function checks whether testAngle is within whatever radian limits you want
{
enemy.curAngle += angle; // update the current angle
// set the position based on the angle
SetY(...)
}

If you need to convert radians to degrees: degrees = (360 / 2*PI) * angle-in-radians.

Edited by Buckeye

##### Share on other sites

This is similar to what Buckeye said, but you can also do something like this. You can use variable to know when the update should actually move the sprite. When you want it to move, set the variable to the amount of radians you want it to rotate, and then on the moveInCircle function do:

void moveInCircle(Vector2D* enemyPos, float speed, int centerX, int centerY, int radius)
{
float speedScale = (0.001 * 2 * PI) / speed;
float angle = SDL_GetTicks() * speedScale;

}
}


I think something like that should work. Maybe you want to check that the angle you rotate is always less or equal the radians left to rotate, so the rotation stops exactly where you want it. For example, something like this after you compute the angle:

if (angle > radiansToRotate)


##### Share on other sites

Thanks for the answer guys! I appreciate it!

void moveInCircle(Vector2D* enemyPos, float speed, int centerX, int centerY, int radius, float* currentAngle, float limit)
{
float speedScale = (0.001 * 2 * PI) / speed;
float angle = SDL_GetTicks() * speedScale;

if(*currentAngle + angle < limit)
{
*currentAngle += angle;
}
}


And in my update function:

if(currentAngle < 360)
{
moveInCircle(&position, 4, 100, 100, 100, &currentAngle, 360);
}


But the enemy is not completing a full 360º rotation. I think I'm missing something pretty simple and stupid! LOL

##### Share on other sites

It stops close to 360? It probably is because you stop the rotation if the angle to rotate will exced the limit, but you never reach the limit. If currentAngle + angle is equal to limit you should also rotate, and if it's more than the limit you should rotate some amount anyway (limit - currentAngle instead of "angle").

##### Share on other sites

Actually it stops around 90 degrees away from the 'target'. One strange thing is that printing out the 'currentAngle' value I noticed that at first 'angle' adds around 0.5 to currentAngle, then it starts adding 1, and suddenly it adds 2 every time it passes through the function. I think it's something wrong with the way I'm calculating the 'angle' variable, I just don't know what.

##### Share on other sites
SDL_GetTicks returns the number of milliseconds since when SDL was initialized and because of that it's an ever increasing value you get.

You need the delta between the current and the last frame.

Something like this:

class CTimer{
public:
CTimer( void ) :
m_thisFrame( SDL_GetTicks() ),
m_lastFrame( m_thisFrame )
{
};

void Update( void )
{
m_lastFrame = m_thisFrame;
m_thisFrame = SDL_GetTicks();

m_dT = ( m_thisFrame - m_lastFrame ) / 1000.0f;
};

float getDeltaTime( void ) const
{
return( m_dT );
};

private:
unsigned long m_thisFrame;
unsigned long m_lastFrame;

float m_dT { 0.0f };
}

Now call the update-function every frame, and replace your use of "SDL_GetTicks" with "getDeltaTime".

Regards
Markus
Edited by Charon

##### Share on other sites

Now call the update-function every frame, and replace your use of "SDL_GetTicks" with "getDeltaTime".

Regards
Markus

Now I've got the sprite not moving at all

I did the same logic you did, except I didn't add a class CTimer, I just added these variables (as floats) to my Enemy update function:

fB = fA;
fA = SDL_GetTicks();
dT = (fA - fB) / 1000.0f;


And modified my moveInCircle function to take dT as an argument

void moveInCircle(Vector2D* enemyPos, float speed, int centerX, int centerY, int radius, float* currentAngle, float limit, float dT)
{
float speedScale = (0.001 * 2 * PI) / speed;
float angle = d_t * speedScale;

std::cout << *currentAngle << "\n";

if(*currentAngle + angle <= limit)
{
*currentAngle += angle;
}
}


What am I doing wrong?

Edited by lvenonl

##### Share on other sites

Does that even compile? You named the parameter "dT" but you're using the variable "d_t" to get the angle... maybe d_t is some global variable that's always 0?

##### Share on other sites

Does that even compile? You named the parameter "dT" but you're using the variable "d_t" to get the angle... maybe d_t is some global variable that's always 0?

Nope! I put that underscore there by mistake, on my code it is "dT" hahahaha

I double checked it, tried to do everything all over again, but I still get the sprite not rotating at all

1. 1
2. 2
3. 3
Rutin
18
4. 4
JoeJ
14
5. 5

• 14
• 10
• 23
• 9
• 32
• ### Forum Statistics

• Total Topics
632631
• Total Posts
3007528
• ### Who's Online (See full list)

There are no registered users currently online

×