xvel = xvel + (thrust * AngleCos)
yvel = yvel + (thrust * AngleSin)
'mag is magnitude of the velocity
mag = Sqr((xvel * xvel) + (yvel * yvel))
'divide by mag and multiply by a small constant (friction) to
'get the amount to get the friction in x and y directions
xfric = (-xvel / mag) * friction
yfric = (-yvel / mag) * friction
xvel and yvel are added to the ship's x and y co-ordinate every frame and are then reduced by xfric and yfric.
This all works and looks nice. I realise there are some optimisations that can be made (I've now removed the square root function and adjusted the friction constant) but that can come later.
If my understanding is correct I'm effectively using vectors, recalculating the velocity vector when thrusting and normalising the vector and scaling it to get the "friction" vector. However, this kind of "feels" wrong. For example, the x and y friction causes the ship not only to slow but to accelerate in the opposite direction if I don't check for it passing zero.
Ideally I'd like to implement a system of forces and velocities, where the ship's position is represented by a location, direction angle and speed (polar co-ordinates?) That method just feels like the right way to do it. I could then simulate friction by reducing it's speed slightly each frame. However, I'm not sure how I'd calculate the ship's movement as the player thrusts. For the example, say the ship's direction of travel is 30 degrees and it's speed is 50 units. The player rotates the ship 5 degrees to the right and thrusts. Assuming thrusting accelerates the ship by 5 units, how do I calculate the the new direction and speed of travel, taking into account the existing direction and speed? I'm sure it's simple trig, but as I said, my maths is rusty.
Can anyone help with either the maths, pointing me to a good tutorial or just commenting on the pros and cons of these two approaches? I've been doing this all day long and I'm feeling pretty tired, so sorry for any mistakes and for such a long mail.
Moot
Edited by - Moot on January 16, 2001 2:32:05 PM
2D Geometry/Physics Help Needed
My maths knowledge is years old and very rusty. I've read through a few 2D geometry tutorials, but would appreciate if someone could let me know whether I'm taking the right approach.
I'm writing a game where spacecraft will move "Asteroids style". You can rotate the ship and thrust to move it forward in that direction. The ship will then continue to move in that direction, even if the ship is rotated, although it's speed will slowly decrease due to friction/resistance (yes, I know space is a vacuum etc... but I want it to work this way) The ship will only change direction if the player thrusts a second time, at which point a new velocity is calculated based on the current velocity and the direction of the ship/power of the thrust.
I've tackled the problem in the following way:
The ship has the following variables:
x: the x co-ordinate
y: the y co-ordinate
angle: the direction in which it is pointing
xvel: x velocity added to the x co-ordinate every frame
yvel: y velocity added to the y co-ordinate every frame
xfric: added to the x velocity to simulate friction
yfric: added to the y velocity to simulate friction
When the player presses the thrust key I calculate the x and y velocities as follows:
This is lifted from VB code, but should make sense to everyone. The game is in C++ but I do most testing of new algorithms in VB.
AngleCos and AngleSin are the cos and sin of the ship direction angle.
I would store the ship''s movement as a vector.
i.e.
(vb-code)
type vector
-double vertical
-double horizontal
end type
this gives you a line, now when the ship accelerates in another direction all you have to do is manipulate that line using vector math.
you have a acceleration constant & max velocity & the new direction in degrees) so here goes:
The hypotenuse of the new triangle is always going to be the acceleration constants (say 6 pixels/s/s).
So we can say that
vector accelerating_vector
accelerating_vector.vertical = Sin (direction) * Acceleration_Constant
accelerating_vector.horizontal = Cos (direction) * Acceleration_Constant
then you just add these to the original vector... and there you go... (I think... I''m a little rusty as well )
you could also try to implement a "thrust" feature where the acceleration can get faster/slower depending on how long you''ve been accelerating and a maximum velocity.
Oh yeah... with the friction thing... you could "hack" it by just saying that for every unit time the ship will slow by 2% or something. (it will never reach zero... and will probably play quite well I would think.)
Regards,
Nekosion
i.e.
(vb-code)
type vector
-double vertical
-double horizontal
end type
this gives you a line, now when the ship accelerates in another direction all you have to do is manipulate that line using vector math.
you have a acceleration constant & max velocity & the new direction in degrees) so here goes:
The hypotenuse of the new triangle is always going to be the acceleration constants (say 6 pixels/s/s).
So we can say that
vector accelerating_vector
accelerating_vector.vertical = Sin (direction) * Acceleration_Constant
accelerating_vector.horizontal = Cos (direction) * Acceleration_Constant
then you just add these to the original vector... and there you go... (I think... I''m a little rusty as well )
you could also try to implement a "thrust" feature where the acceleration can get faster/slower depending on how long you''ve been accelerating and a maximum velocity.
Oh yeah... with the friction thing... you could "hack" it by just saying that for every unit time the ship will slow by 2% or something. (it will never reach zero... and will probably play quite well I would think.)
Regards,
Nekosion
Regards,Nekosion
Thanks for the reply, Nekosion. I was pretty much doing what you said, but I didn''t like the idea of a "hack" for the friction. I wanted it to realistically model real physics.
Last night I did what I should have done in the first place. I dug out an old physics text book and read through the chapters on mechanics, vectors, etc.
I''ve now written a 2d vector class and use vectors to represent the ship''s velocity and thrust, as well as friction. Every frame I add the thrust vector to the velocity, if the player is thrusting, and add the friction vector, which is treated as a force acting in the opposite direction to the ship''s velocity. I calculate it by reversing the ship''s velocity vector and scaling the result by a certain amount, this amount representing the "drag coeffecient" of the spaceship.
It all works very nicely. The friction slows the spaceship and limits the top speed just as it should. Changing the "drag coefficient" and thrust (thrust coefficient?) leads to anything from a sluggish craft that seems to be flying through treacle to zippy little fighter.
I''m very pleased with the results because I can now build up a collection of craft with very different handling characteristics simply by changing a few variables.
Thanks for the help.
Moot
Last night I did what I should have done in the first place. I dug out an old physics text book and read through the chapters on mechanics, vectors, etc.
I''ve now written a 2d vector class and use vectors to represent the ship''s velocity and thrust, as well as friction. Every frame I add the thrust vector to the velocity, if the player is thrusting, and add the friction vector, which is treated as a force acting in the opposite direction to the ship''s velocity. I calculate it by reversing the ship''s velocity vector and scaling the result by a certain amount, this amount representing the "drag coeffecient" of the spaceship.
It all works very nicely. The friction slows the spaceship and limits the top speed just as it should. Changing the "drag coefficient" and thrust (thrust coefficient?) leads to anything from a sluggish craft that seems to be flying through treacle to zippy little fighter.
I''m very pleased with the results because I can now build up a collection of craft with very different handling characteristics simply by changing a few variables.
Thanks for the help.
Moot
float xv = acceleration * shipCOS[degrees]; float yv = acceleration * shipSIN[degrees]; xVelocity += xv; yVelocity += yv;// test for maximum velocity float vel = fastDistance(xVelocity, yVelocity); if (vel >= maxSpeed) { // re-compute velocity vector by normalizing then re-scaling xVelocity = (maxSpeed-1) * xVelocity / vel; yVelocity = (maxSpeed-1) * yVelocity / vel; } xPos += xVelocity; yPos += yVelocity;
xVelocity and yVelocity are the speed componets of the ship
fastDistance is an optimized distance function
xPos and yPos are the position of the ship
now it would be a good idea to make the movement independant of frame rate by calculating the elapsed time between each run throgh of this function and moving the ship based on that elapsed time
"Yo yo ma"
-Kramer
"Yo yo ma" -Kramer
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement