Skip to main content
Adding an example.
Source Link
Vaillancourt
  • 16.4k
  • 17
  • 56
  • 61

Based on Jon's comment, here is an addendum.

This is an implementation with the suggestion I have already made:

// Assuming the following: float mSideThrustersRadPerSec;// Used to compute how much a ship can turn per second Matrix mTransform; // Used to track the orientation of the ship Vector2 mFrontVector; // Used to determine where your ship model is pointing in its // local space float mRearThrustersKmPerSec; // How much are your thrusters able to push the ship Vector2 mPosition; // Position of the ship. if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Left ) ) mTransform = mTransform.rotate( sfUtil::radiansToDegrees( -mSideThrustersRadPerSec * Global::GetInstance().getFrameTime() ) ); if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Right ) ) mTransform = mTransform.rotate( sfUtil::radiansToDegrees( mSideThrustersRadPerSec * Global::GetInstance().getFrameTime() ) ); if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Up ) ) { sf::Vector2f offset = mFrontVector * ( mRearThrustersKmPerSec * Global::GetInstance().getFrameTime() ); sf::Vector2f orientedOffset = mTransform * offset; mPosition = mPosition + orientedOffset; } 

Here is the result:

enter image description here

And this is based on if your ship has a velocity and no external resistance.

// Assuming the following: float mSideThrustersRadPerSec; // Used to compute how much a ship can turn per second Matrix mTransform; // Used to track the orientation of the ship Vector2 mFrontVector; // Used to determine where your ship model is pointing in // its local space float mRearThrustersKmPerSec; // How much are your thrusters able to push the ship float mFrontThrustersKmPerSec; // How much are your thrusters able to slow the ship (and // eventually make it go reverse) Vector2 mPosition; // Position of the ship. Vector2 mVelocity; // Speed and direction of the ship float mSpeedMax; // Maximum speed of the ship if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Left ) ) mTransform = mTransform.rotate( sfUtil::radiansToDegrees( -mSideThrustersRadPerSec * Global::GetInstance().getFrameTime() ) ); if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Right ) ) mTransform = mTransform.rotate( sfUtil::radiansToDegrees( mSideThrustersRadPerSec * Global::GetInstance().getFrameTime() ) ); bool shouldApplyOffset = false; sf::Vector2f offset; if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Up ) && sf::Keyboard::isKeyPressed( sf::Keyboard::Down ) ) { offset = ( mFrontVector * ( mRearThrustersKmPerSec * Global::GetInstance().getFrameTime())) + ( -mFrontVector * ( mFrontThrustersKmPerSec * Global::GetInstance().getFrameTime())); shouldApplyOffset = true; } else if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Up ) ) { offset = mFrontVector * (mRearThrustersKmPerSec * Global::GetInstance().getFrameTime()); shouldApplyOffset = true; } else if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Down ) ) { offset = -mFrontVector * (mFrontThrustersKmPerSec * Global::GetInstance().getFrameTime()); shouldApplyOffset = true; } if ( shouldApplyOffset ) { sf::Vector2f orientedOffset = mTransform * offset; mVelocity += orientedOffset; float currentSpeed = sfUtil::lenght( mVelocity ); if ( currentSpeed > mSpeedMax ) { sf::Vector2f direction = mVelocity / currentSpeed; mVelocity = direction * mSpeedMax; } } mPosition = mPosition + mVelocity; 

With the result:

enter image description here

You can get the working VC2013 code here (it uses SFML).


Based on Jon's comment, here is an addendum.

This is an implementation with the suggestion I have already made:

// Assuming the following: float mSideThrustersRadPerSec;// Used to compute how much a ship can turn per second Matrix mTransform; // Used to track the orientation of the ship Vector2 mFrontVector; // Used to determine where your ship model is pointing in its // local space float mRearThrustersKmPerSec; // How much are your thrusters able to push the ship Vector2 mPosition; // Position of the ship. if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Left ) ) mTransform = mTransform.rotate( sfUtil::radiansToDegrees( -mSideThrustersRadPerSec * Global::GetInstance().getFrameTime() ) ); if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Right ) ) mTransform = mTransform.rotate( sfUtil::radiansToDegrees( mSideThrustersRadPerSec * Global::GetInstance().getFrameTime() ) ); if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Up ) ) { sf::Vector2f offset = mFrontVector * ( mRearThrustersKmPerSec * Global::GetInstance().getFrameTime() ); sf::Vector2f orientedOffset = mTransform * offset; mPosition = mPosition + orientedOffset; } 

Here is the result:

enter image description here

And this is based on if your ship has a velocity and no external resistance.

// Assuming the following: float mSideThrustersRadPerSec; // Used to compute how much a ship can turn per second Matrix mTransform; // Used to track the orientation of the ship Vector2 mFrontVector; // Used to determine where your ship model is pointing in // its local space float mRearThrustersKmPerSec; // How much are your thrusters able to push the ship float mFrontThrustersKmPerSec; // How much are your thrusters able to slow the ship (and // eventually make it go reverse) Vector2 mPosition; // Position of the ship. Vector2 mVelocity; // Speed and direction of the ship float mSpeedMax; // Maximum speed of the ship if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Left ) ) mTransform = mTransform.rotate( sfUtil::radiansToDegrees( -mSideThrustersRadPerSec * Global::GetInstance().getFrameTime() ) ); if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Right ) ) mTransform = mTransform.rotate( sfUtil::radiansToDegrees( mSideThrustersRadPerSec * Global::GetInstance().getFrameTime() ) ); bool shouldApplyOffset = false; sf::Vector2f offset; if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Up ) && sf::Keyboard::isKeyPressed( sf::Keyboard::Down ) ) { offset = ( mFrontVector * ( mRearThrustersKmPerSec * Global::GetInstance().getFrameTime())) + ( -mFrontVector * ( mFrontThrustersKmPerSec * Global::GetInstance().getFrameTime())); shouldApplyOffset = true; } else if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Up ) ) { offset = mFrontVector * (mRearThrustersKmPerSec * Global::GetInstance().getFrameTime()); shouldApplyOffset = true; } else if ( sf::Keyboard::isKeyPressed( sf::Keyboard::Down ) ) { offset = -mFrontVector * (mFrontThrustersKmPerSec * Global::GetInstance().getFrameTime()); shouldApplyOffset = true; } if ( shouldApplyOffset ) { sf::Vector2f orientedOffset = mTransform * offset; mVelocity += orientedOffset; float currentSpeed = sfUtil::lenght( mVelocity ); if ( currentSpeed > mSpeedMax ) { sf::Vector2f direction = mVelocity / currentSpeed; mVelocity = direction * mSpeedMax; } } mPosition = mPosition + mVelocity; 

With the result:

enter image description here

You can get the working VC2013 code here (it uses SFML).

Source Link
Vaillancourt
  • 16.4k
  • 17
  • 56
  • 61

You will need a forward vector which represent the forward direction of your ship, and the velocity of your ship.

// Stuff that you need (or already have) vec3 shipForwardVector; // This is according to your game infrastructure // and ship model; make it a unit vector. mat4 worldSpaceRotationMat; // assuming ship!.transform is only the rotation. float maxVeolicityPerSecond; // Your game settings float requestedVelocityRatio; // User request; from a keyboard, it's 0 or 1, // from a joystick, 0..1 // Computation vec3 rotatedForward = worldSpaceRotationMat * shipForwardVector; float requestedVelocity = maxVeolicityPerSecond * requestedVelocityRatio; // scale the movement according to the time that has passed vec3 displacementThisFrame = rotatedForward * (t * requestedVelocity) ship.position = ship.position + displacementThisFrame