泛型粒子系統的設計3 (轉)
二、 可制定行為的粒子
有了粒子結構,接下來的工作就是制定我們的粒子系統了。任何一個粒子系統都可以被分成3個部分:初始化器——用於初始化每一個剛剛產生的新粒子;器——用於在每一楨更新粒子的狀態;死亡——用於定義粒子死亡時所引發的事件。由於粒子結構的不同,而不同的粒子部分又需要做不同的初始化和更新,所以對於整個粒子的初始化器和更新器需要做類似粒子部分的組裝。:namespace prefix = o ns = "urn:schemas--com::office" />
有了以上的粒子結構,初始化器,更新器和死亡觸發器我們就可以開始組裝完整的粒子系統了:
// 粒子系統
template<
typename _ParticleType, // 粒子結構
size_t nLifeIndex, // 粒子壽命所在粒子結構中的
size_t _Num, // 粒子總數
class _InitializePolicy, // 粒子初始化器
class _ActionPolicy, // 粒子更新器
class _DeadPolicy = TNilDeadTrigger< _ParticleType > // 死亡觸發器
> class TParticleSystem
: boost::noncopyable
{
public:
// 粒子型別
typedef _ParticleType tParticle;
// 初始化器型別
typedef _InitializePolicy tInitializer;
// 更新器型別
typedef _ActionPolicy tActor;
// 死亡觸發器型別
typedef _DeadPolicy tDeadTrigger;
protected:
// 粒子總數
static const int s_ciNum = _Num;
// 粒子陣列
boost::array< tParticle, s_ciNum > m_aParticles;
// 初始化器
tInitializer m_Initializer;
// 更新器
tActor m_Actor;
// 死亡觸發器
tDeadTrigger m_DeadTrigger;
// 當前活動粒子數
size_t m_nCurrentCount;
public:
// 構造
TParticleSystem( void ) : m_nCurrentCount( 0 ) { }
// 解構函式
virtual ~TParticleSystem( void ) { }
// 重置
inline void Reset( void ) { m_nCurrentCount = 0; }
// 獲取初始化器
inline tInitializer& Initializer( void ) { return m_Initializer; }
inline const tInitializer& Initializer( void ) const { m_Initializer; }
// 獲取更新器
inline tActor& Actor( void ) { return m_Actor; }
inline const tActor& Actor( void ) const { m_Actor; }
// 獲取死亡觸發器
inline tDeadTrigger& DeadTrigger( void ) { return m_DeadTrigger; }
inline const tDeadTrigger& DeadTrigger( void ) const { m_DeadTrigger; }
// 獲取粒子陣列的指標
inline const tParticle* GetParticles( void ) const {
if( Particleunt() == 0 ) {
return NULL;
}
return boost::addressof( m_aParticles[0] );
}
// 獲取最大粒子數
inline size_t MaxParticles( void ) const {
return s_ciNum;
}
// 獲取當前活動粒子數
inline size_t ParticlesCount( void ) const {
return m_nCurrentCount;
}
// 發射指定數目的粒子
void Emit( size_t nAmount ) {
// 是否已經達到最大粒子數?
if( ( ParticlesCount() + nAmount ) > MaxParticles() ) {
nAmount = MaxParticles() - ParticlesCount();
}
if( nAmount > 0 ) {
// 發射粒子
size_t nCnt = m_nCurrentCount;
m_nCurrentCount += nAmount;
for( ; nCnt < m_nCurrentCount; ++nCnt ) {
Init< 0 >( m_aParticles[nCnt], m_Initializer );
}
}
}
// 更新
void Update( double dElapsedTime ) {
for( size_t nCnt = 0; nCnt < m_nCurrentCount; ) {
// 更新每一個活動的粒子
Update< 0 >( dElapsedTime, m_aParticles[nCnt], m_Actor );
// 殺掉所有壽命為0或負數的粒子
if( m_aParticles[nCnt].Part< nLifeIndex >().m_Value <= 0.0 ) {
// 移除死亡的粒子,移動最後一個粒子到當前位置
m_DeadTrigger.On( m_aParticles[nCnt] );
m_aParticles[nCnt] = m_aParticles[m_nCurrentCount - 1];
// 當前活動粒子數減一
--m_nCurrentCount;
} else {
// 處理下一個粒子
++nCnt;
}
}
}
private:
// 初始化動作
template< size_t nIndex >
void Init( tParticle& p, tInitializer& i ) {
i.Part< nIndex >().Action< nIndex >( p );
Init< nIndex + 1 >( p, i );
}
template<>
void Init< tParticle::s_ciNumOfParts >( tParticle&, tInitializer& ) {
}
// 執行更新動作
template< size_t nIndex >
void Update( const double& dElapsedTime, tParticle& p, tActor& a ) {
a.Part< nIndex >().Action< nIndex >( dElapsedTime, p );
Update< nIndex + 1 >( dElapsedTime, p, a );
}
template<>
void Update< tParticle::s_ciNumOfParts >( const double&, tParticle&, tActor& )
{
}
};
整個TParticleSystem模板類其實很簡單,這裡只對幾個關鍵點進行說明。TParticleSystem一共接受6個模板引數,第一個_ParticleType為此粒子系統所需要處理的粒子結構;第二個nLifeIndex為粒子壽命部分所在粒子結構中的索引(每一個粒子都必須有一個壽命部分,TParticleSystem將使用此處索引所指的粒子部分來判斷粒子是否死亡);第三個_Num是整個粒子系統所能容納的最大粒子數;第四個_InitializePolicy是用於初始化粒子的初始化器;第五個_ActionPolicy是用於更新粒子的更新器;第六個_DeadPolicy是用於處理粒子死亡的死亡觸發器。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10794571/viewspace-969588/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 泛型粒子系統的設計1 (轉)泛型
- 泛型粒子系統的設計2 (轉)泛型
- 泛型粒子系統的設計4 (轉)泛型
- 泛型粒子系統的設計5 (轉)泛型
- 泛型粒子系統的設計6 (轉)泛型
- 泛型粒子系統的設計7 (轉)泛型
- 泛型類及系統中常用的泛型類泛型
- .NET泛型程式設計簡介 (轉)泛型程式設計
- 泛型程式設計泛型程式設計
- 泛型最佳實踐:Go泛型設計者教你如何用泛型泛型Go
- java 泛型程式設計Java泛型程式設計
- [CUJ]泛型程式設計--轉移建構函式 (轉)泛型程式設計函式
- Go 泛型的這 3 個核心設計,你都知道嗎?Go泛型
- AE 3D粒子系統外掛3D
- Windows系統上泛域名解析的設定(轉)Windows
- 十、GO程式設計模式 : 泛型程式設計Go程式設計設計模式泛型
- 談談 "JS 和 設計泛型"JS泛型
- 泛型程式設計詳解(一)泛型程式設計
- 泛型程式設計與 OI——modint泛型程式設計
- C#學習 [型別系統] 泛型(16)C#型別泛型
- hugo.elias專題 之 粒子系統 (轉)Go
- c++ 泛型 程式設計 之 Functor 設計模式C++泛型程式設計設計模式
- Kotlin語言中的泛型設計哲學Kotlin泛型
- Go泛型草案設計簡明指南Go泛型
- c++ 泛型程式設計 之 TypeListsC++泛型程式設計
- 泛型轉DataTable方法泛型
- 物件導向程式設計和`GP`泛型程式設計物件程式設計泛型
- Dart語法篇之型別系統與泛型(七)Dart型別泛型
- 使用 Go 泛型的函數語言程式設計Go泛型函數程式設計
- 泛型--泛型萬用字元和泛型的上下限泛型字元
- GO語言泛型程式設計實踐Go泛型程式設計
- [MetalKit]41-Working-with-Particles-in-Metal-part3粒子系統3
- 泛型程式設計在非C++語言中的實現之探討 (轉)泛型程式設計C++
- 轉向Kotlin——泛型Kotlin泛型
- Swift 3必看:typealias支援泛型Swift泛型
- Java語法糖3:泛型Java泛型
- 軟體設計是怎樣煉成的(3)——軟體系統不是木桶型的
- Three.js開發指南(7):粒子和粒子系統JS