Im building a small space shooter game. I have how ever stubbed on a math problem when it come to the space physics.
Describing this with words is following: There is a max speed. So if you give full full speed you ship will move with this over the screen over and over again like in the old asteroids games. If then release the rocket boost you ship should be keep moving with that speed over the screen.
Then the tricky part where Im stuck right now.
If you rotate the ship ANY angle and gives boost again the ship should try to get to this direction and NEVER surpas the max speed when it comes to how fast it is moving. so my question is. anyone have a good idea formula for this issue? feels like it has been done before if you know what to look for. :)
Ill add this small image to illustrate what is tried to be done with some vector calculations.
Red ring: Max speed
Green line: current ship direction.
Black line: direction(s) and how fast the ship is moveing in x and y.
Black ring: origin of movement.
Can illustrate it but hard to find a good math solution for this. :)
EDIT
This is the code Im using right now in every frame. It gives movement to the ship but does not give the force of movement the user has to counter-react with its rocket boosters to get the ship to stop or slow down. With this it stops the instant you release the accelerating speed for the ship.
//Calculates ship movement rules
var shipVelocityVec = GetVectorPosByAngle(shipMoveSpeed, shipRotationAngle);
var shipUnitVec =$V([Math.cos(shipRotationAngle),Math.sin(shipRotationAngle),0]);
var rawAccel = shipAccelSpeed / shipMass;
var scale = (shipUnitVec.dot(shipVelocityVec))/(shipTopSpeed * shipTopSpeed);
var v1 = shipUnitVec.subtract(shipVelocityVec.multiply(scale));
var finalAccelVec = v1.multiply(rawAccel);
console.log(finalAccelVec);
//move ship according to rules
var shipPosVector = $V([shipxPos, shipyPos, 0]);
var movementVector = shipPosVector.add(finalAccelVec);
shipxPos = movementVector.elements[0];
shipyPos = movementVector.elements[1];
To give the acceleration speed the user has to keep the button pressed. the instance the user releases the button the acceleration is set to zero and have to boost over again to give maximum acceleration throttle.
Solution found! Posted it here how it was done.
Speed is a measure of distance per unit of time, and force measures acceleration times mass. To convert speed to force, you need to convert the speed to acceleration by dividing the change in speed by time. This gives you acceleration. Then, you must multiply by the mass to get force.
You seem to be confusing something - there is no issue capping the velocity to a maximum speed, even when the acceleration is at a different angle, if you are using vectors correctly.
Your setup should look something like this:
x
and y
components).That's it! There are no special cases to consider - that's the magic of vector algebra!
@BlueRaja's solution should work, although you will get an abrupt change in behavior when you hit the max speed.
If you want a solution with no "seams", I believe you can do what you're looking for by adding the right kind of adjustment to the acceleration, as follows:
ship_unit_vec = [cos(ship_angle), sin(ship_angle)]
raw_accel = (engine_thrust / ship_mass)
scale = dot_product(ship_unit_vec, ship_velocity_vec) / max_speed^2
final_accel_vec = raw_accel * (ship_unit_vec - scale * ship_velocity_vec)
Notes:
|ship_velocity_vec|<<max_speed
, the scale * ship_velocity_vec
component is negligable.|ship_velocity_vec|==max_speed
, the scale * ship_velocity_vec
component cancels all additional acceleration in the "wrong" direction, and aids acceleration in the "right" direction.More generally, if there are more sources of acceleration than just the ship thrusters, you can add them all together (say, as raw_accel_vec
), and perform the above operation all at once:
scale_forall = dot_product(raw_accel_vec, ship_velocity_vec) / max_speed^2
final_accel_vec = raw_accel_vec - scale_forall * ship_velocity_vec
Rather than just imposing an ad hoc maximum speed, you could use some actual physics and impose a drag force. This would be an extra force acting on the spaceship, directed opposite to the velocity vector. For the magnitude of the drag force, it's simplest to just take it proportional to the velocity vector.
The overall effect is that the drag force increases as the spaceship moves faster, making it harder to accelerate in the direction of motion when the ship moves faster. It also makes acceleration easier when it is opposed to the direction of motion.
One point where this diverges from your description is that the spaceship won't continue at maximum speed forever, it will slow down. It won't, however, come to a halt, since the drag force drops as the ship slows down. That matches my memory of asteroids better than the ship continuing forever at constant velocity, but it has been quite a while since I've played.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With