Added (for testing) new explosion handling, which uses a fixed random animation

to toss karts around after an explosion.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5223 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2010-04-20 23:50:38 +00:00
parent ec83ef6cad
commit f1fd38cbf3
11 changed files with 239 additions and 7 deletions

View File

@ -222,6 +222,11 @@
the force a plunger/rubber band applies to the kart(s).
duration is the duration a rubber band acts. -->
<rubber-band max-length="50" force="1500" duration="1"/>
<!-- Kart-specific explosion parameters. Height: how high this
this kart is being pushed in the sky by an explosion.
Time: how long it takes before the kart can drive again. -->
<explosion time="2" height="2" />
</general-kart-defaults>
</config>

View File

@ -158,6 +158,8 @@ supertuxkart_SOURCES = \
karts/controller/default_ai_controller.hpp \
karts/controller/end_controller.cpp \
karts/controller/end_controller.hpp \
karts/explosion_animation.cpp \
karts/explosion_animation.hpp \
karts/controller/kart_control.hpp \
karts/controller/new_ai_controller.cpp \
karts/controller/new_ai_controller.hpp \

View File

@ -464,6 +464,10 @@
<Filter
Name="karts"
>
<File
RelativePath="..\..\karts\explosion_animation.cpp"
>
</File>
<File
RelativePath="..\..\karts\kart.cpp"
>
@ -1286,6 +1290,10 @@
<Filter
Name="karts"
>
<File
RelativePath="..\..\karts\explosion_animation.hpp"
>
</File>
<File
RelativePath="..\..\karts\kart.hpp"
>

View File

@ -105,6 +105,7 @@ void InputManager::handleStaticAction(int key, int value)
{
Kart* kart = world->getLocalPlayerKart(0);
kart->setPowerup(POWERUP_BUBBLEGUM, 10000);
kart->handleExplosion(kart->getXYZ(), true);
}
break;
case KEY_F2:

View File

@ -0,0 +1,101 @@
// $Id$
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "karts/explosion_animation.hpp"
#include "karts/kart.hpp"
#include "modes/world.hpp"
#include "tracks/track.hpp"
#include "utils/constants.hpp"
Vec3 m_add_rotation;
Vec3 m_curr_rotation;
/** The constructor stores a pointer to the kart this object is animating,
* and initialised the timer.
* \param kart Pointer to the kart which is animated.
*/
ExplosionAnimation::ExplosionAnimation(Kart *kart)
{
m_timer = -1;
m_kart = kart;
}; // ExplosionAnimation
// ----------------------------------------------------------------------------
/** Starts an explosion animation.
* \param pos The coordinates of the explosion.
* \param direct_hig True if the kart was hit directly --> maximal impact.
*/
void ExplosionAnimation::handleExplosion(const Vec3 &pos, bool direct_hit)
{
// Avoid doing another explosion while a kart is thrown around in the air.
if(m_timer>=0) return;
m_timer = 0;
m_xyz = m_kart->getXYZ();
float t = m_kart->getKartProperties()->getExplosionTime();
// Half of the overall time is spent in raising, so only use
// half of the explosion time here.
// Velocity after t seconds is:
// v(t) = m_up_velocity + t*gravity
// Since v(explosion_time*0.5) = 0, the following forumla computes
// the right initial velocity for a kart to land back after
// the specified time.
m_up_velocity = 0.5f * t * World::getWorld()->getTrack()->getGravity();
World::getWorld()->getPhysics()->removeKart(m_kart);
m_curr_rotation.setHPR(m_kart->getRotation());
const int max_rotation = direct_hit ? 2 : 1;
// To get rotations in botb directions for each axis we determine a random
// number between -(max_rotation-1) and +(max_rotation-1)
float f=2.0f*M_PI/t;
m_add_rotation.setHeading( (rand()%(2*max_rotation+1)-max_rotation)*f );
m_add_rotation.setPitch( (rand()%(2*max_rotation+1)-max_rotation)*f );
m_add_rotation.setRoll( (rand()%(2*max_rotation+1)-max_rotation)*f );
} // handleExplosion
// ----------------------------------------------------------------------------
/** Updates the explosion animation.
* \param dt Time step size.
* \return True if the explosion is still shown, false if it has finished.
*/
bool ExplosionAnimation::update(float dt)
{
assert(m_timer>=0);
m_timer += dt;
if(m_timer>m_kart->getKartProperties()->getExplosionTime())
{
m_timer=-1;
World::getWorld()->getPhysics()->addKart(m_kart);
m_kart->getBody()->setLinearVelocity(btVector3(0,0,0));
m_kart->getBody()->setAngularVelocity(btVector3(0,0,0));
return false;
}
m_up_velocity -= dt*World::getWorld()->getTrack()->getGravity();
m_xyz.setY(m_xyz.getY()+m_up_velocity*dt);
m_kart->setXYZ(m_xyz);
m_curr_rotation += dt*m_add_rotation;
btQuaternion q(m_curr_rotation.getHeading(), m_curr_rotation.getPitch(),
m_curr_rotation.getRoll());
m_kart->setRotation(q);
return true;
} // update

View File

@ -0,0 +1,66 @@
// $Id$
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2010 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_EXPLOSION_ANIMATION_HPP
#define HEADER_EXPLOSION_ANIMATION_HPP
#include "utils/vec3.hpp"
class Kart;
/** This class is a 'mixin' for kart, and handles the animated explosion.
* I.e. it will throw the kart a certain amount in the air, rotate it
* randomly, and after the specified time period let it land at the
* same spot where it was hit, therefore avoiding any problems of
* karts being pushed on wrong parts of the track, and making explosion
* more 'fair' (it can't happen that one explosion give you actually
* a benefit by pushing you forwards.
* The object is a base class for kart, but will only be used if an
* explosion happens.
*/
class ExplosionAnimation
{
private:
/** The coordinates where the kart was hit originally. */
Vec3 m_xyz;
/** The rotation of the kart at the time of the explosion. */
Vec3 m_hpr;
/** The upwards velocity. */
float m_up_velocity;
/** Timer for the explosion. */
float m_timer;
/** Duration for this explosion. This can potentially be set
* with different values for different karts, or depending
* on difficulty (so that on easy you can drive again earlier. */
float m_duration;
/** A pointer to the class to which this object belongs. */
Kart *m_kart;
public:
ExplosionAnimation(Kart *kart);
~ExplosionAnimation() {};
void handleExplosion(const Vec3& pos, bool direct_hit);
bool update(float dt);
}; // ExplosionAnimation
#endif

View File

@ -64,7 +64,7 @@
Kart::Kart (const std::string& ident, int position,
const btTransform& init_transform)
: TerrainInfo(1),
Moveable(), m_powerup(this)
Moveable(), ExplosionAnimation(this), m_powerup(this)
#if defined(WIN32) && !defined(__CYGWIN__)
# pragma warning(1:4355)
@ -600,12 +600,15 @@ float Kart::getActualWheelForce()
} // getActualWheelForce
//-----------------------------------------------------------------------------
/** The kart is on ground if all 4 wheels touch the ground.
/** The kart is on ground if all 4 wheels touch the ground, and if no special
* animation (rescue or explosion) is happening).
*/
bool Kart::isOnGround() const
{
return (m_vehicle->getNumWheelsOnGround() == m_vehicle->getNumWheels());
return (m_vehicle->getNumWheelsOnGround() == m_vehicle->getNumWheels()
&& m_kart_mode!=KM_RESCUE && m_kart_mode!=KM_EXPLOSION);
} // isOnGround
//-----------------------------------------------------------------------------
/** The kart is near the ground, but not necesarily on it (small jumps). This
* is used to determine when to switch off the upright constraint, so that
@ -618,6 +621,7 @@ bool Kart::isNearGround() const
else
return ((getXYZ().getZ() - getHoT()) < stk_config->m_near_ground);
} // isNearGround
//-----------------------------------------------------------------------------
/** Called when an explosion happens.
* \param pos Position of the explosion.
@ -629,8 +633,13 @@ void Kart::handleExplosion(const Vec3& pos, bool direct_hit)
int sign_bits = rand(); // To select plus or minus randomnly, assuming 15 bit at least
if(direct_hit)
{
printf("he: ");
ExplosionAnimation::handleExplosion(pos, direct_hit);
m_kart_mode = KM_EXPLOSION;
// Play associated kart sound
playCustomSFX(SFXManager::CUSTOM_EXPLODE);
return;
float sign_a = (sign_bits & (0x1 << 8)) ? 1.0f : -1.0f;
float sign_b = (sign_bits & (0x1 << 9)) ? 1.0f : -1.0f;
float sign_c = (sign_bits & (0x1 << 10)) ? 1.0f : -1.0f;
@ -755,6 +764,12 @@ void Kart::update(float dt)
0));
setRotation(getRotation()*q_roll*q_pitch);
} // if rescue mode
else if ( m_kart_mode==KM_EXPLOSION)
{
if(!ExplosionAnimation::update(dt))
m_kart_mode = KM_RACE;
}
m_attachment->update(dt);
//smoke drawing control point
@ -764,6 +779,9 @@ void Kart::update(float dt)
m_water_splash_system->update(dt);
m_nitro->update(dt);
m_slip_stream->update(dt);
// update star effect (call will do nothing if stars are not activated)
m_stars_effect->update(dt);
} // UserConfigParams::m_graphical_effects
updatePhysics(dt);
@ -1319,8 +1337,6 @@ void Kart::updatePhysics(float dt)
);
#endif
// update star effect (call will do nothing if stars are not activated)
m_stars_effect->update(dt);
} // updatePhysics
//-----------------------------------------------------------------------------

View File

@ -26,6 +26,7 @@
#include "graphics/camera.hpp"
#include "items/attachment.hpp"
#include "items/powerup.hpp"
#include "karts/explosion_animation.hpp"
#include "karts/moveable.hpp"
#include "karts/kart_properties.hpp"
#include "karts/controller/controller.hpp"
@ -55,7 +56,7 @@ class Stars;
* is an object that is moved on the track, and has position and rotations)
* and TerrainInfo, which manages the terrain the kart is on.
*/
class Kart : public TerrainInfo, public Moveable
class Kart : public TerrainInfo, public Moveable, public ExplosionAnimation
{
private:
/** Reset position. */

View File

@ -72,7 +72,8 @@ KartProperties::KartProperties(const std::string &filename) : m_icon_material(0)
m_slipstream_length = m_slipstream_collect_time =
m_slipstream_use_time = m_slipstream_add_power =
m_slipstream_min_speed = m_camera_distance =
m_rescue_time = m_rescue_height = UNDEFINED;
m_rescue_time = m_rescue_height = m_explosion_time =
m_explosion_height = UNDEFINED;
m_gravity_center_shift = Vec3(UNDEFINED);
m_has_skidmarks = true;
m_version = 0;
@ -214,6 +215,12 @@ void KartProperties::getAllData(const XMLNode * root)
rescue_node->get("height", &m_rescue_height );
}
if(const XMLNode *explosion_node = root->getNode("explosion"))
{
explosion_node->get("time", &m_explosion_time );
explosion_node->get("height", &m_explosion_height);
}
if(const XMLNode *skid_node = root->getNode("skid"))
{
skid_node->get("increase", &m_skid_increase );
@ -469,6 +476,8 @@ void KartProperties::checkAllSet(const std::string &filename)
CHECK_NEG(m_rescue_height, "rescue height" );
CHECK_NEG(m_rescue_time, "rescue time" );
CHECK_NEG(m_rescue_vert_offset, "rescue vert-offset" );
CHECK_NEG(m_explosion_time, "explosion time" );
CHECK_NEG(m_explosion_height, "explosion height" );
} // checkAllSet

View File

@ -112,6 +112,12 @@ private:
/** Distance the kart is raised before dropped. */
float m_rescue_height;
/** Time an animated explosion is shown. Longer = more delay for kart. */
float m_explosion_time;
/** Height of an explosion animation. */
float m_explosion_height;
/** Vertical offset after rescue. */
float m_rescue_vert_offset;
@ -247,8 +253,16 @@ public:
float getRescueTime () const {return m_rescue_time; }
/** Returns the height a kart is moved to during a rescue. */
float getRescueHeight () const {return m_rescue_height; }
/** Returns the time an explosion animation is shown. */
float getExplosionTime () const {return m_explosion_time; }
/** Returns the height of the explosion animation. */
float getExplosionHeight () const {return m_explosion_height; }
/** Returns how much a kart can roll/pitch before the upright constraint
* counteracts. */
float getUprightTolerance () const {return m_upright_tolerance; }
/** Returns the maximum value of the upright counteracting force. */
float getUprightMaxForce () const {return m_upright_max_force; }
/** Returns artificial acceleration to keep wheels on track. */
float getTrackConnectionAccel () const {return m_track_connection_accel; }
/** Returns the maximum length of a rubber band before it breaks. */
float getRubberBandMaxLength () const {return m_rubber_band_max_length; }

View File

@ -94,6 +94,10 @@ void Moveable::reset()
} // reset
//-----------------------------------------------------------------------------
/** Updates the current position and rotation from the corresponding physics
* body, and then calls updateGraphics to position the model correctly.
* \param float dt Time step size.
*/
void Moveable::update(float dt)
{
m_motion_state->getWorldTransform(m_transform);
@ -113,6 +117,11 @@ void Moveable::update(float dt)
} // update
//-----------------------------------------------------------------------------
/** Creates the bullet rigid body for this moveable.
* \param mass Mass of this object.
* \param trans Transform (=position and orientation) for this object).
* \param shape Bullet collision shape for this object.
*/
void Moveable::createBody(float mass, btTransform& trans,
btCollisionShape *shape) {
btVector3 inertia;