A heading of 0 radians is to the right (positive X).
PI/2 radians (90 degrees) is up (positive Y).
PI radians (180 degrees) is left (negative X).
3*PI/2 radians (270 degrees) is down (negative Y).
The friction constant, k is available in the universal constants
as ssc_friction.
From F = ma, we can calculate that the acceleration due
to friction is equal to:
ar = -kv
The velocity of an object at any time t can be calculated given
its initial velocity v0:
v( t ) = v0
* e-kt
The convenience values ssc_frictionPerSecond
and ssc_frictionPerFrame
have been provided, such that:
v( constant( ssc_secondsPerFrame)
) = v0 * ( 1 - constant( ssc_frictionPerFrame
) )
v( 1.0 ) = v0
* ( 1 - constant( ssc_frictionPerSecond
) )
The distance travelled by an object between time t0 and t1
can be calculated by integrating the previous function:
d(t) = v0
* ( e-k*t0 ) / k - v0 * ( e-k*t1 ) / k
The game engine moves objects at constant velocity during each frame.
It applies friction by using the following formula to compute the velocity
of the object for the end of the frame:
vx,vy specify the object's
velocity at the start of the frame.
vx' = vx * (1.0 - constant(
ssc_frictionPerFrame
) )
vy' = vy * (1.0 - constant(
ssc_frictionPerFrame
) )
The object is moved at the average of these two values.
To compute the average velocity for the frame:
vx,vy specify the object's
velocity at the start of the frame.
vx',vy' specify the object's
velocity at the end of the frame.
avx = ( vx' + vx ) / 2
avy = ( vy' + vy ) / 2
To calculate the object's initial co-ordinates for next frame:
x,y specify the object's
initial co-ordinates for this frame
x' = x + avx * constant(
ssc_secondsPerFrame
)
y' = y + avy * constant(
ssc_secondsPerFrame
)
Objects bounce off the walls with perfect reflection. Remember to take into account the radius of the object if you're trying to compute how an object is going to reflect!
Collisions between moving objects are modelled by reducing them to a
one dimensional elastic collision.
The two colliding objects are considered to be moving along the line
running between both centres at the moment of impact. The velocity components
running along this line are extracted and used for the momentum transfer.
Because collisions between moving objects are elastic both momentum and
kinetic energy are conserved.
m1, m2 = masses
u1, u2 = pre-collision velocity component
v1, v2 = post-collision velocity componentMomentum before = Momentum after
(1) m1*u1 + m2*u2 = m1*v1 + m2*v2
K.E. before = K.E. afterIf you wish to solve for the post-collision velocities, v1 and v2, re-arrange (1) to:
(2) 1/2*m1*u1*u1 + 1/2*m2*u2*u2 = 1/2 *m1*v1*v1 + 1/2*m2*v2*v2
(4) v2 = ( m1*u1 + m2*u2 - m1*v1 ) / m2;The equation for v2 can then be situated into (2), and solved using the quadratic formula.
Collisions with a bullet also trigger an explosion.
The explosion happens just after the collision and momentum transfer
with the bullet.
Any object that is within ssc_bulletExplosionRadius
metres at the instant of the explosion is affected.
Each object receives ssc_bulletExplosionEnergy
Joules, in the form of Kinetic Energy directed away from the centre of
the explosion.
KE = 0.5 * mass * v * v = constant( ssc_bulletExplosionEnergy )
ev = sqrt( 2 * constant( ssc_bulletExplosionEnergy ) / mass )
alpha = heading from explosion to object
vx' = vx + ev * cos( alpha )
vy' = vy + ev * sin( alpha )
The first AI command acted upon is Firing. The ship will fire during
the exact moment presented to the AI for evaluation.
You can calculate the initial position and velocity of a new bullet
with:
bulletX = shipX + constant(
ssc_starshipRadius
) * cos( shipHeading )
bulletY = shipY + constant(
ssc_starshipRadius
) * sin( shipHeading )
bulletVY = shipVX + constant(
ssc_bulletLaunchSpeed
) * cos( shipHeading );
bulletVY = shipVY + constant(
ssc_bulletLaunchSpeed
) * sin( shipHeading );
Bullets last for ssc_bulletLifespan,
which means that their range is limited by their launch velocity relative
to the target!
Bullets, like their targets, are subject to friction.
If you are turning your starship, you can calculate what your heading
will be next frame with:
heading' = heading +/- constant(
ssc_starshipTurnRadiansPerFrame
)
The engine then returns back to step
1, moving the objects under friction.