如何利用Composite模式实现多样化的粒子系统

来源:互联网 发布:php开发用什么框架 编辑:程序博客网 时间:2024/06/01 09:42

    首先,我的粒子是采取广告板的方式来表现的,因为这样才能给我实现多样化粒子系统的能力.

    具体做法是,将广告版看成是Leaf,而粒子系统看成Composite,那么利用Composite模式既可以让广告板单独使用,又可以用多个广告板组成复杂的粒子系统,这是灵活性1.

    另外,我们知道Composite模式是可以组成一个树型结构的,那么粒子系统需要树型结构吗,答案是肯定的,比如你模拟火,火的粒子系统是树根,而象由火产生的烟雾等,都可以看成火的儿子.所以灵活性之二就是可以自由的抽象出象这样的结构.

    下面我用控制台程序模拟了这一过程:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

class Spirit3DComponent{

public:
 Spirit3DComponent(){};
 Spirit3DComponent( string name ) : m_name( name ){};
 virtual void Add( Spirit3DComponent* comPtr ) = 0;
 virtual void Remove( Spirit3DComponent* comPtr ) = 0;
 virtual void Display() = 0;
 string GetName(){
  return m_name;
 }

protected:
 string m_name;

};

class ParticleSystem : public Spirit3DComponent{

 //输出名字
 class DisplayName{

 public:
  void operator()( Spirit3DComponent* p ){

   if( p ){
    p->Display();
   }

  }

 };

 //删除谓词
 class DeletePtr{

 public:
  void operator()( Spirit3DComponent* p ){

   if( p ){
    delete p;
   }

  }

 };

 //移出谓词
 class RemovePtr{

 public:
  RemovePtr( Spirit3DComponent* p ) : m_p( p ){}

  bool operator()( Spirit3DComponent* p ){

   if( p->GetName() == m_p->GetName() ){
    return true;
   }
   else{
    return false;
   }

  }

 protected:
  Spirit3DComponent* m_p;

 };

public:
    typedef vector< Spirit3DComponent* > compositevec;
 typedef compositevec::iterator IteratorCom;
 typedef compositevec::const_iterator ConstIteratorCom;

 ParticleSystem(){};

 ~ParticleSystem(){
        for_each( m_comVec.begin(), m_comVec.end(), DeletePtr() );
 }

 ParticleSystem( string name ) : Spirit3DComponent( name ){};

 virtual void Add( Spirit3DComponent* comPtr ){
 
        m_comVec.push_back( comPtr );

 }
 virtual void Remove( Spirit3DComponent* comPtr ){

  IteratorCom newEnd = remove_if( m_comVec.begin(), m_comVec.end(), RemovePtr( comPtr ) );
  for( IteratorCom i = newEnd; newEnd != m_comVec.end(); ++i ){

            m_comVec.erase( i++ );

  }

 }
 virtual void Display(){

  cout<<"例子系统属于:"<<m_name<<endl;
  cout<<"组成部分:"<<endl;
  if( m_comVec.empty() ){
   cout<<"无"<<endl;
  }
  else{
   for_each( m_comVec.begin(), m_comVec.end(), DisplayName() );
  }
  cout<<endl;

 }

protected:
    compositevec m_comVec;

};

class BillBoard : public Spirit3DComponent{

public:
 BillBoard(){};

 BillBoard( string name ) : Spirit3DComponent( name ){};

 virtual void Add( Spirit3DComponent* comPtr ){}
 virtual void Remove( Spirit3DComponent* comPtr ){}
 virtual void Display(){

  cout<<"粒子名:"<<m_name<<endl;
 
 }


};

int main(){

 Spirit3DComponent* cSmoke = new ParticleSystem( "烟" );
 cSmoke->Add( new BillBoard( "烟" ) );
 cSmoke->Add( new BillBoard( "烟" ) );
 cSmoke->Display();

 Spirit3DComponent* cFire = new ParticleSystem( "火" );
 cFire->Add( new BillBoard( "火" ) );
 cFire->Add( new BillBoard( "火" ) );
    cFire->Add( cSmoke );
 cFire->Display();
 
 


 return 0;
}