2

I currently have an object that I want to gradually accelerate. The longer you hold down on a certain key, the faster it goes. I managed to get it to work fine for one key (when it moves right) however, it does not seem to work for the other directions.

The code I have right now is:

    if (mKeyboard->isKeyDown(OIS::KC_NUMPAD8)) 
    {
        mSpeed += mAcceleration*evt.timeSinceLastFrame;
        movement.z -= mSpeed*evt.timeSinceLastFrame;
        mAcceleration++;
    }
    if (mKeyboard->isKeyDown(OIS::KC_NUMPAD4)) 
    {
        mSpeed += mAcceleration*evt.timeSinceLastFrame;
        movement.x -= mSpeed*evt.timeSinceLastFrame;
        mAcceleration++;
    }
    if (mKeyboard->isKeyDown(OIS::KC_NUMPAD5)) 
    {
        mSpeed += mAcceleration*evt.timeSinceLastFrame;
        movement.z += mSpeed*evt.timeSinceLastFrame;
        mAcceleration++;
    }
    if (mKeyboard->isKeyDown(OIS::KC_NUMPAD6))
    {
        mSpeed += mAcceleration*evt.timeSinceLastFrame;
        movement.x += mSpeed*evt.timeSinceLastFrame;
        mAcceleration++;
    }

And the statement that works fine is the last one. The rest just move normally, without any acceleration.

I was wondering how I can get the object to gradually accelerate at the other directions as well.

P.S Just in case anyone is wondering as well, I cannot change the "if"s to "while". The program does not run at all when I change it.

P.P.S The object works (gradually accelerates in all directions) when I change the others to "else if" however, I can no longer move diagonally which is also my problem. I have tried doing something such as

else if (mKeyboard->isKeyDown(OIS::KC_I) && mKeyboard->isKeyDown(OIS::KC_J))
    {
        mSpeed += mAcceleration *evt.timeSinceLastFrame;
        movement.z -= mSpeed*evt.timeSinceLastFrame;
        movement.x -= mSpeed*evt.timeSinceLastFrame;
        mAcceleration++;
    }

but it still does not move diagonally.

Stuart Den
  • 51
  • 7

3 Answers3

0

Acceleration should be a constant number, unless you want you acceleration to accelerate. So in some graphics I've done with key inputs I have a variable called boost or force and I define it as a number. Then, for the if statement, I will have:

if (mKeyboard->isKeyDown(OIS::KC_<whatever>)) {
    object.boost();
} else { object.noBoost(); }

Where boost() is a function that sets a boolean to true within the object. In the update function, where the object is drawn I have:

if (isBoosting) {
    velocity += accel//where accel is a defined number
}

You don't have to add all of this stuff, but instead of having mAcceleration++, I would just remove that and define its acceleration somewhere else and have mSpeed += acceleration *... ;. I hope this helps!

Zeke Willams
  • 170
  • 11
  • I have tried removing mAcceleration++ because I thought the same thing before posting but when I ran the program, it ended up not accelerating at all. The object just moves normally. – Stuart Den Nov 19 '17 at 07:01
  • You removed `mAcceleration++`, but what did you add? – Zeke Willams Nov 19 '17 at 07:03
  • Oh, I didn't add anything. mAcceleration is defined in the whole class too (in the TutorialApplication header). – Stuart Den Nov 19 '17 at 07:05
  • Ah okay, well it could be that multiplying the acceleration number by the time since last frame could be causing the acceleration to be so small, that it's not even noticeable. I would still take out the mAcceleration++ out though, unless you want your acceleration to accelerate. – Zeke Willams Nov 19 '17 at 07:07
  • Sadly, I tried taking out the time since last frame but it made no changes :/ – Stuart Den Nov 19 '17 at 07:52
0

So apparently, I just needed to add another if statement

if (!mKeyboard->isKeyDown(OIS::KC_NUMPAD8) && !mKeyboard->isKeyDown(OIS::KC_NUMPAD4) && !mKeyboard->isKeyDown(OIS::KC_NUMPAD6) && !mKeyboard->isKeyDown(OIS::KC_NUMPAD2))
{
    mSpeed = mSetSpeed;
    mAcceleration = mSetAcceleration;
}

(I know it looks bad ahahaha) to reset the speed and acceleration back to normal (so it can gradually increase again) when it is no longer being pressed. Still curious as to why it won't work without mAcceleration++ though.

Another way of solving this is having

if(movement.length()==0) mSpeed = mSetSpeed;
else mSpeed += mAcceleration*evt.timeSinceLastFrame;
Stuart Den
  • 51
  • 7
0

I think your solution needs two changes:

  1. acceleration should be a constant.
  2. speed must be a vector.

I think modifying your code like the following should work (not testet):

if (mKeyboard->isKeyDown(OIS::KC_NUMPAD8)) 
{
    mSpeed.z -= mAcceleration*evt.timeSinceLastFrame;
}
if (mKeyboard->isKeyDown(OIS::KC_NUMPAD4)) 
{
    mSpeed.x -= mAcceleration*evt.timeSinceLastFrame;
}
if (mKeyboard->isKeyDown(OIS::KC_NUMPAD5)) 
{
    mSpeed.z += mAcceleration*evt.timeSinceLastFrame;
}
if (mKeyboard->isKeyDown(OIS::KC_NUMPAD6))
{
    mSpeed.x += mAcceleration*evt.timeSinceLastFrame;
}

movement += mSpeed*evt.timeSinceLastFrame;
Tobias Wollgam
  • 761
  • 2
  • 8
  • 25
  • I have had acceleration as a const since the very start! I am just a bit confused because "speed" has z/y axes. I tried it out but my object no longer moved. – Stuart Den Nov 23 '17 at 12:04
  • What does it mean "speed" has z/y axes? Your movement uses x and z. And is movement the final position or are there more calculations? – Tobias Wollgam Nov 23 '17 at 13:52