Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm making a game where player moves around a spaceship pressing W,S,A,D. What I would like to achieve is that I would like to make the ship stop slightly when a key is released before it went to full stop. How can I achieve that?

Here's the moving code :

 kbs = Keyboard.GetState();

            if (kbs.IsKeyDown(Keys.W))
            {
                this.pos.Y -= speed;
                this.animation = "up";

                if (kbs.IsKeyDown(Keys.D))
                {
                    if (!isDirectional)
                    {
                        frameIndex = 0;
                        isDirectional = true;
                    }
                    this.pos.X += speed;
                    this.animation = "upright";
                }
                else if (kbs.IsKeyDown(Keys.A))
                {
                    if (!isDirectional)
                    {
                        frameIndex = 0;
                        isDirectional = true;
                    }
                    this.pos.X -= speed;
                    this.animation = "upleft";
                }

                if (!this.isAnimating) this.isAnimating = true;
                else this.isAnimating = false;

                CheckStop();
            }
            else if (kbs.IsKeyDown(Keys.S))
            {
                this.pos.Y += speed;
                this.animation = "down";

                if (kbs.IsKeyDown(Keys.D))
                {
                    if (!isDirectional)
                    {
                        frameIndex = 0;
                        isDirectional = true;
                    }
                    this.pos.X += speed;
                    this.animation = "downright";
                }
                else if (kbs.IsKeyDown(Keys.A))
                {
                    if (!isDirectional)
                    {
                        frameIndex = 0;
                        isDirectional = true;
                    }
                    this.pos.X -= speed;
                    this.animation = "downleft";
                }

                if (!this.isAnimating) this.isAnimating = true;
                else this.isAnimating = false;
            }
            else if (kbs.IsKeyDown(Keys.A))
            {
                this.pos.X -= speed;
                this.animation = "left";
                if (!this.isAnimating) this.isAnimating = true;
                else this.isAnimating = false;
            }
            else if (kbs.IsKeyDown(Keys.D))
            {
                this.pos.X += speed;
                this.animation = "right";
                if (!this.isAnimating) this.isAnimating = true;
                else this.isAnimating = false;
            }
            else
            {
                this.isAnimating = false;
                this.isDirectional = false;
                frameIndex = 0;
            }

I have been trying to check for the ship to slowly stop with CheckStop() function, here it is (for the sake of trying, on the above code I only apply CheckStop() on the 'W' key):

private void CheckStop()
        {
            KeyboardState nkbs = Keyboard.GetState();

            if (!kbs.IsKeyDown(Keys.W) && nkbs.IsKeyDown(Keys.W))
            {
                speed -= fraction;
                if (speed <= 0) speed = 0;
                this.pos.Y -= speed;
            }
        }

Any help is appreciated, thanks.

share|improve this question
    
You can do something like this: Each frame do this this.position += velocity; and velocity -= new Vector2(0.1f); to minimum of (0,0). When key is down, start increasing velocity to max of (speed, speed). Btw you can probably remove the nested ifs for moving upleft, upright, downleft and downright with this approach (by checking what velocity components are and setting animation accordingly). –  Kikaimaru Jul 11 '13 at 9:21

2 Answers 2

up vote 1 down vote accepted

Something like this can be achieved by using velocity/acceleration as well as dampening.

A simplified example could be something like the following. velocity, position and max_velocity are supposed to be vectors, but they could be single values (for one dimension, like forward trust) as well - you'd just have to modify the movement code.

velocity *= 0.9; // Dampening the current velocity, the smaller this number, the faster you slow down.

if (kbs.IsKeyDown(Keys.W))
    velocity.x = max(-max_velocity.x, velocity.x - .1f); // Accelerate (by .1f)
else if (kbs.IsKeyDown(Keys.D))
    velocity.x = min(max_velocity.x, velocity.x + .1f);
// Do the same here for vertical acceleration.

// Once everything is done, actually move the ship (or whatever)
position += velocity;

For an Asteroids like game, you could essentially do the same. Just use the x coordinate as your angle and the y coordinate as your rotation (or similar).

share|improve this answer
    
achieved what i want with this, thanks –  user2002495 Jul 12 '13 at 2:51

I find in situations like asteroid-y type games to model position(P), velocity(V), and acceleration(A), and then when updating the positions, the following procedures are carried out:

V += A
P += V

Likely in your code it would look like:

V.x += A.x;
V.y += A.y;
P.x += V.x;
P.y += V.y;

In such a model, there are two types of acceleration.... your acceleration due to thrust and your acceleration due to "drag".

Acceleration due to thrust is easy... if your engines are "on", then you provide thrust at whatever rate you decide in whatever direction your ship is pointing, probably like so:

AThrust.x = Math.cos(direction) * Force;
AThrust.y = Math.sin(direction) * Force;

(since you are using WASD, your directions are very simple... 0, pi/2, pi, -pi/2, and you may not need trig at all);

Acceleration due to drag is based on the velocity and a constant, like so:

A(drag) = -V * k

Or rather

ADrag.x = -V.x * k;
ADrag.y = -V.y * k;

(k might be 0.1 as suggested above, but you will ultimately have to work out what it is)

Each time you update your position, you then are doing the following:

ADrag.x = -V.x * k;
ADrag.y = -V.y * k;
V.x += ADrag.x + AThrust.x;
V.y += ADrag.y + Athrust.y;
P.x += V.x;
P.y += V.y;

And this will work out fine if your time units are frames and not seconds or milliseconds or whatever other actual time unit.

Otherwise, you need the delta time between the last update and this one:

t = currentFrameTime-lastFrameTime;
ADrag.x = -V.x * k;
ADrag.y = -V.y * k;
V.x += (ADrag.x + AThrust.x) * t;
V.y += (ADrag.y + Athrust.y) * t;
P.x += V.x * t;
P.y += V.y * t;
share|improve this answer
    
what is Athrust and Adrag class? It belongs to the ship? –  user2002495 Jul 12 '13 at 2:51
    
they are like the pos field... vectors associated with the object. –  PlayDeezGames Jul 12 '13 at 3:09

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.