marktilbrook
marktilbrook

Reputation: 83

How to create 2D side to side movement in c++?

I am trying to move an AI spaceship side to side. I would imagine using sin would solve this but I am struggling. So far this is what I have. This just moves the spaceship right forever as it is called in an update function which is called every frame. I just want the spaceship to move right a certain amount then do the same to the left, and repeat forever. Thanks

m_velocity = Vector2D(200,0);
Vector2D friction = FRICTION * m_velocity;
m_velocity = m_velocity + friction * frametime;
m_position = m_position + m_velocity * frametime;

Upvotes: 0

Views: 732

Answers (2)

Spektre
Spektre

Reputation: 51835

if your m_velocity 2D vector is the direction your object is moving (turned) and you want side steps then you can simply turn the vector by 90 degrees. In 2D its very simple:

side1.x=+m_velocity.y;
side1.y=-m_velocity.x;
side2.x=-m_velocity.y;
side2.y=+m_velocity.x;

now you got 2 vectors pointing to the left and right (which depends on your coordinate system) so just scale it to match your side speed.

Another option is to get the angle from your speed and use sin,cos:

ang = atan2(m_velocity.y,m_velocity.x) +/- (M_PI*0.5);
side.x=side_speed*cos(ang);
side.y=side_speed*sin(ang);

However this is less accurate and much slower. Which side it is depends on the +/- Also I assumed your angles are in radians. If in degrees instead change (M_PI*0.5) to 90.0

However you are using Newton d'Alembert integration without acceleration. Its more realistic to apply the the control stuff (thrusters) to Acceleration instead of speed ... and have the turn angle ang already stored or in form of transform matrix or basis vectors for rendering anyway.

For more info see:

[Edit1] so you want zig zag like movement without forward motion

try this:

m_velocity = Vector2D(200*sin(2.0*M_PI*f*t),0);

where f is frequency of movement in [Hz] and t is elapsed time in [sec]

To make it more prone to rounding errors use

m_velocity = Vector2D(200*sin(fmod(2.0*M_PI*f*t,2.0*M_PI)),0);

However even this will not be OK after t saturates to the point it can not be incremented ...

When put together with time:

static float ang=0.0;
m_velocity = Vector2D(200*sin(ang),0);
ang=fmod(ang+(2.0*M_PI*f*dt),2.0*M_PI);

where dt is time interval in [sec] of your timer or whatever event you use to invoke this code

Upvotes: 0

QuantumDeveloper
QuantumDeveloper

Reputation: 777

As you said, you can do this using sine.

The values of sine go from -1 to 1.

So if you want to move your spaceship between position x₁ and x₂, you have to scale and translate it:

x = (x₁+x₂)/2 + (x₂-x₁)/2 *sin(ωt)

Where the first term moves the middle of the sine to the middlepoint between the two values.

The second term scales the amplitude of the sine, so it exactly reaches x₁ and x₂.

ω is the angular frequency which is a measurement of how fast/slow the thing moves.

t is the current time(accumulated since the start).

Upvotes: 1

Related Questions