mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-01-22 09:01:57 -05:00
Optimised calculatio of jump height.
This commit is contained in:
parent
46b93ff004
commit
345331c7ca
1 changed files with 19 additions and 26 deletions
|
@ -78,7 +78,7 @@ namespace ClassicalSharp {
|
||||||
PlayerRenderer renderer;
|
PlayerRenderer renderer;
|
||||||
|
|
||||||
public float JumpHeight {
|
public float JumpHeight {
|
||||||
get { return jumpVelocity == 0 ? 0 : GetMaxHeight( jumpVelocity ); }
|
get { return jumpVelocity == 0 ? 0 : (float)GetMaxHeight( jumpVelocity ); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CalculateJumpVelocity( float jumpHeight ) {
|
public void CalculateJumpVelocity( float jumpHeight ) {
|
||||||
|
@ -86,40 +86,33 @@ namespace ClassicalSharp {
|
||||||
jumpVelocity = 0;
|
jumpVelocity = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// NOTE: There is probably still a better way of doing this.
|
|
||||||
float jumpV = 0.01f;
|
float jumpV = 0.01f;
|
||||||
// Find the most appropriate starting velocity, this can ~half the time
|
|
||||||
// required in some circumstances. (8 -> 3 ms for max jump height of 1024 )
|
|
||||||
if( jumpHeight >= 256 ) jumpV = 10.0f;
|
if( jumpHeight >= 256 ) jumpV = 10.0f;
|
||||||
if( jumpHeight >= 512 ) jumpV = 16.5f;
|
if( jumpHeight >= 512 ) jumpV = 16.5f;
|
||||||
if( jumpHeight >= 768 ) jumpV = 22.5f;
|
if( jumpHeight >= 768 ) jumpV = 22.5f;
|
||||||
float diff = float.PositiveInfinity;
|
|
||||||
|
|
||||||
while( true ) {
|
while( GetMaxHeight( jumpV ) <= jumpHeight ) {
|
||||||
float height = GetMaxHeight( jumpV );
|
|
||||||
float newDiff = Math.Abs( height - jumpHeight );
|
|
||||||
if( newDiff > diff ) {
|
|
||||||
// 0.01 isn't subtracted because it's better to slightly
|
|
||||||
// overestimate jump height than underestimate it.
|
|
||||||
jumpVelocity = jumpV;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
diff = newDiff;
|
|
||||||
jumpV += 0.01f;
|
jumpV += 0.01f;
|
||||||
}
|
}
|
||||||
|
jumpVelocity = jumpV;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float GetMaxHeight( float velY ) {
|
static double GetMaxHeight( float u ) {
|
||||||
float posY = 0f;
|
// equation below comes from solving diff(x(t, u))= 0
|
||||||
float maxY = 0f;
|
// We only work in discrete timesteps, so test both rounded up and down.
|
||||||
|
double t = 49.49831645 * Math.Log( 0.247483075 * u + 0.9899323 );
|
||||||
while( posY > -0.1f ) {
|
return Math.Max( YPosAt( (int)t, u ), YPosAt( (int)t + 1, u ) );
|
||||||
posY += velY;
|
}
|
||||||
velY *= 0.98f;
|
|
||||||
velY -= 0.08f;
|
static double YPosAt( int t, float u ) {
|
||||||
if( posY > maxY ) maxY = posY;
|
// v(t, u) = (4 + u) * (0.98^t) - 4, where u = initial velocity
|
||||||
}
|
// x(t, u) = Σv(t, u) from 0 to t (since we work in discrete timesteps)
|
||||||
return maxY;
|
// plugging into Wolfram Alpha gives 1 equation as
|
||||||
|
// e^(-0.0202027 t) * (-49u - 196) - 4t + 50u + 196
|
||||||
|
// which is the same as (0.98^t) * (-49u - 196) - 4t + 50u + 196
|
||||||
|
double a = Math.Exp( -0.0202027 * t ); //~0.98^t
|
||||||
|
return a * ( -49 * u - 196 ) - 4 * t + 50 * u + 196;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleInput( out float xMoving, out float zMoving ) {
|
void HandleInput( out float xMoving, out float zMoving ) {
|
||||||
|
|
Loading…
Reference in a new issue