Added interface for a 'hit effect', which is now a base for

explosion. This will allow to easily add different effects
later.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9607 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2011-08-23 21:57:46 +00:00
parent 6665249821
commit 5ecf3d4c08
9 changed files with 107 additions and 57 deletions

View File

@ -203,6 +203,7 @@ add_executable(supertuxkart
src/graphics/explosion.hpp src/graphics/explosion.hpp
src/graphics/hardware_skinning.cpp src/graphics/hardware_skinning.cpp
src/graphics/hardware_skinning.hpp src/graphics/hardware_skinning.hpp
src/graphics/hit_effect.hpp
src/graphics/irr_driver.cpp src/graphics/irr_driver.cpp
src/graphics/irr_driver.hpp src/graphics/irr_driver.hpp
src/graphics/lod_node.cpp src/graphics/lod_node.cpp

View File

@ -67,6 +67,7 @@ supertuxkart_SOURCES = \
graphics/explosion.hpp \ graphics/explosion.hpp \
graphics/hardware_skinning.cpp \ graphics/hardware_skinning.cpp \
graphics/hardware_skinning.hpp \ graphics/hardware_skinning.hpp \
graphics/hit_effect.hpp \
graphics/irr_driver.cpp \ graphics/irr_driver.cpp \
graphics/irr_driver.hpp \ graphics/irr_driver.hpp \
graphics/lod_node.cpp \ graphics/lod_node.cpp \

View File

@ -35,6 +35,7 @@ const float burst_time = 0.1f;
/** Creates an explosion effect. */ /** Creates an explosion effect. */
Explosion::Explosion(const Vec3& coord, const char* explosion_sound, Explosion::Explosion(const Vec3& coord, const char* explosion_sound,
bool player_kart_hit) bool player_kart_hit)
: HitEffect(coord, explosion_sound, player_kart_hit)
{ {
// short emision time, explosion, not constant flame // short emision time, explosion, not constant flame
m_remaining_time = burst_time; m_remaining_time = burst_time;
@ -101,8 +102,9 @@ Explosion::~Explosion()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/** Updates the explosion, called one per time step. /** Updates the explosion, called one per time step.
* \param dt Time step size. * \param dt Time step size.
* \return true If the explosion is finished.
*/ */
void Explosion::update(float dt) bool Explosion::update(float dt)
{ {
m_remaining_time -= dt; m_remaining_time -= dt;
@ -126,7 +128,7 @@ void Explosion::update(float dt)
// Do nothing more if the animation is still playing // Do nothing more if the animation is still playing
if (m_remaining_time>0) return; if (m_remaining_time>0) return false;
// Otherwise check that the sfx has finished, otherwise the // Otherwise check that the sfx has finished, otherwise the
// sfx will get aborted 'in the middle' when this explosion // sfx will get aborted 'in the middle' when this explosion
@ -147,7 +149,8 @@ void Explosion::update(float dt)
// Sound and animation finished --> remove node // Sound and animation finished --> remove node
irr_driver->removeNode(m_node); irr_driver->removeNode(m_node);
m_node = NULL; m_node = NULL;
projectile_manager->FinishedExplosion(); return true; // finished
return;
} }
return false; // not finished
} // update } // update

View File

@ -20,6 +20,7 @@
#ifndef HEADER_EXPLOSION_HPP #ifndef HEADER_EXPLOSION_HPP
#define HEADER_EXPLOSION_HPP #define HEADER_EXPLOSION_HPP
#include "graphics/hit_effect.hpp"
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
namespace irr namespace irr
@ -36,7 +37,7 @@ const float explosion_time = 1.5f;
/** /**
* \ingroup graphics * \ingroup graphics
*/ */
class Explosion : public NoCopy class Explosion : public HitEffect
{ {
private: private:
SFXBase* m_explode_sound; SFXBase* m_explode_sound;
@ -47,8 +48,7 @@ private:
public: public:
Explosion(const Vec3& coord, const char* explosion_sound, bool player_hit); Explosion(const Vec3& coord, const char* explosion_sound, bool player_hit);
~Explosion(); ~Explosion();
void update (float delta_t); bool update (float delta_t);
int inUse ();
bool hasEnded () { return m_remaining_time <= -explosion_time; } bool hasEnded () { return m_remaining_time <= -explosion_time; }
} ; } ;

View File

@ -0,0 +1,48 @@
// $Id$
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2011 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_HIT_EFFECT_HPP
#define HEADER_HIT_EFFECT_HPP
#include "utils/no_copy.hpp"
class Vec3;
/**
* \ingroup graphics
* A small interface for effects to be used when a kart is hit. That
* includes a sound effect only, or a graphical effect (like an
* explosion).
*/
class HitEffect: public NoCopy
{
public:
/** Constructor for a hit effect. */
HitEffect(const Vec3& coord, const char* explosion_sound,
bool player_hit) {};
virtual ~HitEffect() {};
/** Updates a hit effect. Called once per frame.
* \param dt Time step size.
* \return True if the hit effect is finished and can be removed. */
virtual bool update (float dt) = 0;
}; // HitEffect
#endif
/* EOF */

View File

@ -1784,6 +1784,10 @@
RelativePath="..\..\graphics\hardware_skinning.hpp" RelativePath="..\..\graphics\hardware_skinning.hpp"
> >
</File> </File>
<File
RelativePath="..\..\graphics\hit_effect.hpp"
>
</File>
<File <File
RelativePath="..\..\graphics\irr_driver.hpp" RelativePath="..\..\graphics\irr_driver.hpp"
> >

View File

@ -179,7 +179,7 @@ void Attachment::hitBanana(Item *item, int new_attachment)
case ATTACH_BOMB: case ATTACH_BOMB:
{ {
add_a_new_item = false; add_a_new_item = false;
projectile_manager->newExplosion(m_kart->getXYZ(), "explosion", projectile_manager->newHitEffect(m_kart->getXYZ(), "explosion",
m_kart->getController()->isPlayerController()); m_kart->getController()->isPlayerController());
m_kart->handleExplosion(m_kart->getXYZ(), /*direct_hit*/ true); m_kart->handleExplosion(m_kart->getXYZ(), /*direct_hit*/ true);
clear(); clear();
@ -313,7 +313,7 @@ void Attachment::update(float dt)
} }
if(m_time_left<=0.0) if(m_time_left<=0.0)
{ {
projectile_manager->newExplosion(m_kart->getXYZ(), "explosion", projectile_manager->newHitEffect(m_kart->getXYZ(), "explosion",
m_kart->getController()->isPlayerController()); m_kart->getController()->isPlayerController());
m_kart->handleExplosion(m_kart->getXYZ(), m_kart->handleExplosion(m_kart->getXYZ(),
/*direct_hit*/ true); /*direct_hit*/ true);

View File

@ -20,6 +20,7 @@
#include "items/projectile_manager.hpp" #include "items/projectile_manager.hpp"
#include "graphics/explosion.hpp" #include "graphics/explosion.hpp"
#include "graphics/hit_effect.hpp"
#include "items/bowling.hpp" #include "items/bowling.hpp"
#include "items/cake.hpp" #include "items/cake.hpp"
#include "items/plunger.hpp" #include "items/plunger.hpp"
@ -29,8 +30,6 @@
#include "network/network_manager.hpp" #include "network/network_manager.hpp"
#include "network/race_state.hpp" #include "network/race_state.hpp"
//static ssgSelector *find_selector ( ssgBranch *b );
ProjectileManager *projectile_manager=0; ProjectileManager *projectile_manager=0;
void ProjectileManager::loadData() void ProjectileManager::loadData()
@ -55,13 +54,13 @@ void ProjectileManager::cleanup()
} }
m_active_projectiles.clear(); m_active_projectiles.clear();
for(Explosions::iterator i = m_active_explosions.begin(); for(HitEffects::iterator i = m_active_hit_effects.begin();
i != m_active_explosions.end(); ++i) i != m_active_hit_effects.end(); ++i)
{ {
delete *i; delete *i;
} }
m_active_explosions.clear(); m_active_hit_effects.clear();
} // cleanup } // cleanup
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -86,7 +85,8 @@ void ProjectileManager::update(float dt)
if(! (*p)->hasHit()) { p++; continue; } if(! (*p)->hasHit()) { p++; continue; }
if((*p)->needsExplosion()) if((*p)->needsExplosion())
{ {
newExplosion((*p)->getXYZ(), (*p)->getExplosionSound(), false ); newHitEffect((*p)->getXYZ(), (*p)->getExplosionSound(),
/*player_kart_hit*/ false );
} }
Flyable *f=*p; Flyable *f=*p;
Projectiles::iterator pNext=m_active_projectiles.erase(p); // returns the next element Projectiles::iterator pNext=m_active_projectiles.erase(p); // returns the next element
@ -95,27 +95,19 @@ void ProjectileManager::update(float dt)
} // while p!=m_active_projectiles.end() } // while p!=m_active_projectiles.end()
} }
m_explosion_ended=false; HitEffects::iterator he = m_active_hit_effects.begin();
for(Explosions::iterator i = m_active_explosions.begin(); while(he!=m_active_hit_effects.end())
i != m_active_explosions.end(); ++i)
{ {
(*i)->update(dt); // Update this hit effect. If it can be removed, remove it.
} if((*he)->update(dt))
if(m_explosion_ended)
{
Explosions::iterator e;
e = m_active_explosions.begin();
while(e!=m_active_explosions.end())
{ {
if(!(*e)->hasEnded()) { e++; continue;} delete *he;
HitEffects::iterator next = m_active_hit_effects.erase(he);
delete *e; he = next;
} // if hit effect finished
Explosions::iterator eNext = m_active_explosions.erase(e); else // hit effect not finished, go to next one.
e = eNext; he++;
} // while e!=m_active_explosions.end() } // while hit effect != end
} // if m_explosion_ended
m_something_was_hit=false;
} // update } // update
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -143,9 +135,9 @@ void ProjectileManager::updateServer(float dt)
} // updateServer } // updateServer
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/** Updates all rockets and explosions on the client. /** Updates all rockets and hit effects on the client.
* updateClient takes the information in race_state and updates all rockets * updateClient takes the information in race_state and updates all rockets
* (i.e. position, explosion etc) */ * (i.e. position, hit effects etc) */
void ProjectileManager::updateClient(float dt) void ProjectileManager::updateClient(float dt)
{ {
m_something_was_hit = false; m_something_was_hit = false;
@ -186,16 +178,20 @@ Flyable *ProjectileManager::newProjectile(Kart *kart,
} // newProjectile } // newProjectile
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
/** See if there is an old, unused explosion object available. If so, /** Creates a new hit effect.
* reuse this object, otherwise create a new one. */ * \param coord The coordinates where the hit effect (i.e. sound, graphics)
Explosion* ProjectileManager::newExplosion(const Vec3& coord, * should be placed).
const char* explosion_sound, * \param sfx The name of the sound effect to be played.
* \param player_kart_hit True of a player kart was hit.
*/
HitEffect* ProjectileManager::newHitEffect(const Vec3& coord,
const char *sfx,
bool player_kart_hit) bool player_kart_hit)
{ {
Explosion *e = new Explosion(coord, explosion_sound, player_kart_hit); HitEffect *he = new Explosion(coord, sfx, player_kart_hit);
m_active_explosions.push_back(e); m_active_hit_effects.push_back(he);
return e; return he;
} // newExplosion } // newHitEffect
// ============================================================================= // =============================================================================
/** A general function which is only needed here, but /** A general function which is only needed here, but

View File

@ -33,7 +33,7 @@ namespace irr
class Vec3; class Vec3;
class Kart; class Kart;
class Explosion; class HitEffect;
class Flyable; class Flyable;
/** /**
@ -43,19 +43,19 @@ class ProjectileManager : public NoCopy
{ {
private: private:
typedef std::vector<Flyable*> Projectiles; typedef std::vector<Flyable*> Projectiles;
typedef std::vector<Explosion*> Explosions; typedef std::vector<HitEffect*> HitEffects;
// The list of all active projectiles, i.e. projectiles /** The list of all active projectiles, i.e. projectiles which are
// which are currently moving on the track * currently moving on the track. */
Projectiles m_active_projectiles; Projectiles m_active_projectiles;
// All active explosions, i.e. explosions which are currently /** All active hit effects, i.e. hit effects which are currently
// being shown * being shown or have a sfx playing. */
Explosions m_active_explosions; HitEffects m_active_hit_effects;
scene::IMesh *m_explosion_model; scene::IMesh *m_explosion_model;
bool m_something_was_hit; bool m_something_was_hit;
bool m_explosion_ended;
void updateClient(float dt); void updateClient(float dt);
void updateServer(float dt); void updateServer(float dt);
public: public:
@ -63,19 +63,16 @@ public:
~ProjectileManager() {} ~ProjectileManager() {}
/** Notifies the projectile manager that something needs to be removed. */ /** Notifies the projectile manager that something needs to be removed. */
void notifyRemove () {m_something_was_hit=true; } void notifyRemove () {m_something_was_hit=true; }
void FinishedExplosion() {m_explosion_ended =true; } scene::IMesh *getExplosionModel()
scene::IMesh* getExplosionModel()
{ {
return m_explosion_model; return m_explosion_model;
} }
unsigned int getNumProjectiles() const {return m_active_explosions.size();}
int getProjectileId (const std::string ident);
void loadData (); void loadData ();
void cleanup (); void cleanup ();
void update (float dt); void update (float dt);
Flyable* newProjectile (Kart *kart, Flyable* newProjectile (Kart *kart,
PowerupManager::PowerupType type); PowerupManager::PowerupType type);
Explosion* newExplosion (const Vec3& coord, HitEffect* newHitEffect (const Vec3& coord,
const char* explosion_sound="explosion", const char* explosion_sound="explosion",
bool is_player_kart_hit = false); bool is_player_kart_hit = false);
void Deactivate (Flyable *p) {} void Deactivate (Flyable *p) {}