Improved bouncing of ball when it is still far away from the kart.

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9314 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2011-07-21 06:58:28 +00:00
parent bf90805448
commit 4477862356
5 changed files with 37 additions and 9 deletions

View File

@ -17,7 +17,7 @@
<item name="swatter" icon="swatter-icon.png" /> <item name="swatter" icon="swatter-icon.png" />
<item name="rubber-ball" icon="rubber_ball-icon.png" <item name="rubber-ball" icon="rubber_ball-icon.png"
model="rubber_ball.b3d" speed="10.0" model="rubber_ball.b3d" speed="10.0"
min-height="0.2" max-height="1.0" /> interval="1" max-height="4.0" />
<item name="parachute" icon="parachute-icon.png" <item name="parachute" icon="parachute-icon.png"
model="parachute.b3d" /> model="parachute.b3d" />
<item name="plunger" icon="plunger-icon.png" <item name="plunger" icon="plunger-icon.png"

View File

@ -108,6 +108,7 @@ scene::IMesh* Flyable::m_st_model [PowerupManager::POWERUP_MAX];
float Flyable::m_st_min_height [PowerupManager::POWERUP_MAX]; float Flyable::m_st_min_height [PowerupManager::POWERUP_MAX];
float Flyable::m_st_max_height [PowerupManager::POWERUP_MAX]; float Flyable::m_st_max_height [PowerupManager::POWERUP_MAX];
float Flyable::m_st_force_updown[PowerupManager::POWERUP_MAX]; float Flyable::m_st_force_updown[PowerupManager::POWERUP_MAX];
float Flyable::m_st_interval [PowerupManager::POWERUP_MAX];
Vec3 Flyable::m_st_extend [PowerupManager::POWERUP_MAX]; Vec3 Flyable::m_st_extend [PowerupManager::POWERUP_MAX];
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -121,6 +122,7 @@ Flyable::Flyable(Kart *kart, PowerupManager::PowerupType type, float mass)
m_min_height = m_st_min_height[type]; m_min_height = m_st_min_height[type];
m_average_height = (m_min_height+m_max_height)/2.0f; m_average_height = (m_min_height+m_max_height)/2.0f;
m_force_updown = m_st_force_updown[type]; m_force_updown = m_st_force_updown[type];
m_interval = m_st_interval[type];
m_owner = kart; m_owner = kart;
m_type = type; m_type = type;
m_has_hit_something = false; m_has_hit_something = false;
@ -214,10 +216,12 @@ void Flyable::init(const XMLNode &node, scene::IMesh *model,
m_st_max_height[type] = 1.0f; m_st_max_height[type] = 1.0f;
m_st_min_height[type] = 3.0f; m_st_min_height[type] = 3.0f;
m_st_force_updown[type] = 15.0f; m_st_force_updown[type] = 15.0f;
m_st_interval[type] = 1.0f;
node.get("speed", &(m_st_speed[type]) ); node.get("speed", &(m_st_speed[type]) );
node.get("min-height", &(m_st_min_height[type]) ); node.get("min-height", &(m_st_min_height[type]) );
node.get("max-height", &(m_st_max_height[type]) ); node.get("max-height", &(m_st_max_height[type]) );
node.get("force-updown", &(m_st_force_updown[type])); node.get("force-updown", &(m_st_force_updown[type]));
node.get("interval", &(m_st_interval[type]) );
// Store the size of the model // Store the size of the model
Vec3 min, max; Vec3 min, max;

View File

@ -79,6 +79,9 @@ protected:
/** Force pushing the Flyable up. */ /** Force pushing the Flyable up. */
float m_force_updown; float m_force_updown;
/** Interval (used for rubber ball). */
float m_interval;
/** Speed of this Flyable. */ /** Speed of this Flyable. */
float m_speed; float m_speed;
@ -108,6 +111,9 @@ protected:
/** Force pushing up/down. */ /** Force pushing up/down. */
static float m_st_force_updown[PowerupManager::POWERUP_MAX]; static float m_st_force_updown[PowerupManager::POWERUP_MAX];
/** Interval, used for the rubber ball. */
static float m_st_interval[PowerupManager::POWERUP_MAX];
/** Size of the model. */ /** Size of the model. */
static Vec3 m_st_extend[PowerupManager::POWERUP_MAX]; static Vec3 m_st_extend[PowerupManager::POWERUP_MAX];

View File

@ -69,6 +69,8 @@ RubberBall::RubberBall(Kart *kart) : Flyable(kart, PowerupManager::POWERUP_RUBBE
m_aiming_at_target = false; m_aiming_at_target = false;
m_wrapped_around = false; m_wrapped_around = false;
m_previous_height = 0.0f; m_previous_height = 0.0f;
m_timer = 0.0f;
m_height = 0.0f;
} // RubberBall } // RubberBall
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -113,6 +115,9 @@ void RubberBall::init(const XMLNode &node, scene::IMesh *bowling)
void RubberBall::update(float dt) void RubberBall::update(float dt)
{ {
Flyable::update(dt); Flyable::update(dt);
m_timer += dt;
if(m_timer>m_interval)
m_timer -= m_interval;
// Update the target in case that the first kart was overtaken (or has // Update the target in case that the first kart was overtaken (or has
// finished the race). // finished the race).
@ -133,7 +138,6 @@ void RubberBall::update(float dt)
// FIXME: use interpolation here for smooth curves // FIXME: use interpolation here for smooth curves
Vec3 next_xyz = getXYZ() + delta * (m_speed * dt / delta.length()); Vec3 next_xyz = getXYZ() + delta * (m_speed * dt / delta.length());
// Determine new distance along track // Determine new distance along track
Vec3 ball_distance_vec; Vec3 ball_distance_vec;
m_quad_graph->findRoadSector(next_xyz, &m_current_graph_node); m_quad_graph->findRoadSector(next_xyz, &m_current_graph_node);
@ -161,22 +165,32 @@ void RubberBall::update(float dt)
float target_distance = float target_distance =
world->getDistanceDownTrackForKart(m_target->getWorldKartId()); world->getDistanceDownTrackForKart(m_target->getWorldKartId());
float x = target_distance - m_distance_along_track; float x = target_distance - m_distance_along_track;
if(x<0) if(x<0)
x+=track_length; x+=track_length;
// A formula to determine height depending on distance to target float height;
float height = 0.5f*sqrt(x)*fabsf(sinf(10.0f*log(0.005f*(x+5.0f)))); if(x>50)
// Stephen_irc:: float height = 0.5*x^0.333*fabsf(sinf(15*log(sqrt(x+5)))); {
const float weight = 0.7f; // Consider f(x) = x*(x-m_intervall), which is a parabolic function
float average_height = weight*m_previous_height + (1-weight)*height; // with f(0) = 0, f(m_intervall)=0. We then scale this function to
m_previous_height = height; // fulfill: f(m_intervall/2) = m_max_height, or:
// f(m_interval/2) = -m_interval^2/4 = m_max_height
// --> scale with m_max_height / -m_interval^2/4
float f = m_max_height / (-0.25f*m_interval*m_interval);
height = m_timer * (m_timer-m_interval) * f;
}
else
{
height = 0.5f*sqrt(x)*fabsf(sinf(10.0f*log(0.005f*(x+5.0f))));
}
#if 0 #if 0
printf("ball z %f dt %f x %f h %f, ah %f\n", printf("ball z %f dt %f x %f h %f, ah %f\n",
next_xyz.getZ(),dt, next_xyz.getZ(),dt,
x, height1, average_height); x, height1, average_height);
#endif #endif
next_xyz.setY(getHoT() + average_height); next_xyz.setY(getHoT() + height);
setXYZ(next_xyz); setXYZ(next_xyz);
} // update } // update

View File

@ -52,6 +52,10 @@ private:
* height newly determined height. */ * height newly determined height. */
float m_previous_height; float m_previous_height;
float m_height;
float m_timer;
/** True if the ball just crossed the start line, i.e. its /** True if the ball just crossed the start line, i.e. its
* distance changed from close to length of track in the * distance changed from close to length of track in the
* previous time step to a bit over zero now. */ * previous time step to a bit over zero now. */