space ship inertia

BlitzMax Forums/BlitzMax Beginners Area/space ship inertia

Cruis.In(Posted 2006) [#1]
how do I add friction or inertia type movement to the space ship object?

where the ship continues heading in the last direction you were thrusting in, even if your rotation has changed. and also to be heading in that direction at the same speed you stopped thrusting at, i.e no slowing down as time goes by, so i guess thats newtonian and not just friction, friction would slow you down after a while.

so

vx :+ Sin(angle)*speed
vy :+ Cos(angle)*speed

x  :+  vx
y  :-  vy



that gives the proper direction and stuff, but what to carry on the speed no matter the angle?

currently of course as soon as you change angle, it starts going in that directrion.


SculptureOfSoul(Posted 2006) [#2]
The key is to only update your vx and vy while you are applying the thruster.

Otherwise, just leave vx and vy alone (unless you do want to add in some sort of friction).


SculptureOfSoul(Posted 2006) [#3]
Oh, and get rid of that *speed. I'm pretty sure (w/o having tested it) that that is what is causing your problem. Vx and Vy represent your speed.


So now we'll let vx and vy represent your speed, and set the necessary caps on them. I'd personally keep vx and vy between 0 and 1.0 and then multiply them by a constant representing your MAXSPEED later.

Of course, you'll need to multiply your Sin(angle) by some constant value as well, to keep the values small so that vx and vy don't climb from 0.0 to 1.0 too fast.

Here's some quick and dirty code (not tested). Space bar represents the thruster here. Adjust the const's to taste - I have no idea if the values I put in actually work decently or not ;).
const THRUST_MULTIPLIER:float = 0.005
const MAX_HORIZONTAL_VELOCITY = 10
const MAX_VERTICAL_VELOCITY = 10

if Keydown( key_space )

vx:+ sin(angle) *  THRUST_MULTIPLIER
vy:+ cos(angle) * THRUST_MULTIPLIER

if vx > 1.0
 vx = 1.0
endif

if vx < -1.0
 vx = -1.0
endif

if vy > 1.0
 vy = 1.0
endif

if vy < -1.0
 vy = -1.0
endif


endif

x:+ (vx * MAX_HORIZONTAL_VELOCITY)
y:+ (vy * MAX_VERTICAL_VELOCITY)




Steve Elliott(Posted 2006) [#4]
Asteroids is the classic example of this type of movement - take a look at this tutorial:

http://www.blitzbasic.com/Community/posts.php?topic=48800


Yan(Posted 2006) [#5]
Had this to hand if it helps any...


[edit]
Ha...Probably not then. ;o)
[/edit]


Cruis.In(Posted 2006) [#6]
thanks guys. got it, i just had to put the vector code in the thrust input. where as before it was in an update physics method in the loop, now I put the cos sin of vx vy in the forward thrust and rear thrust and leave the x+vx stuff in the update physics method and it works, after testing for a few seconds, so who knows if i run into something else along the way. I want this type of movement for a different game than the one i am doing now.


rdodson41(Posted 2006) [#7]
@Sculpture - I like your way, but I found a nice way of keeping it below max speed, but you cant use your 0.0 to 1.0 idea. Here is the code for a Thrust() method:
Const MAX_SPEED:Float = 6.0
Const ACCELERATION:Float = 0.1

'# vx = x part of velocity
'# vy = y part of velocity
'# dir = direction facing

'# change vx and vy depending on what direction the ship is facing
vx :+ ACCELERATION * Cos(dir)
vy :+ ACCELERATION * Sin(dir)

'# this keeps the overall speed below max speed no matter what
If Sqr(vx * vx + vy * vy) > MAX_SPEED
    Local a:Float = ATan2(vy, vx)
    vx = MAX_SPEED * Cos(a)
    vy = MAX_SPEED * Sin(a)
EndIf



SculptureOfSoul(Posted 2006) [#8]
Hmm, I see what you're doing (i think). If the length of the velocity vector is > max speed you calculate the angle the ship is traveling at, and then set vx and vy according to that, thus preventing the player from ever actually exceeding MAX_SPEED in any direction (where my code would let you travel at MAX_SPEED if you were heading strictly horizontally or vertically, but greater than MAX_SPEED when moving diagonally).

Nice!

One of these days I might actually get around to working with physics/graphics with real code (I built an inertia engine in Click & Create, hehe, but other than C&C games I've never really programmed physics/graphics). Until then, I apologize for half-baked ideas off the top of my head ;).


rdodson41(Posted 2006) [#9]
Yeah, the first time I tried this I just checked if vx and vy were greater than MAX_SPEED but then yeah you could go greater than MAX_SPEED by going diagonally. I spent a long time trying to figure out how to fix that, and I finally found out about ATan and ATan2 and now it works great.


rdodson41(Posted 2006) [#10]
oops, double post.


Yan(Posted 2006) [#11]
You could also lose the trig...
local VelMag = Sqr((vx * vx) + (vy * vy)) 
If VelMag > MAX_SPEED
    vx = (vx / VelMag) * MAX_SPEED
    vy = (vy / VelMag) * MAX_SPEED
EndIf