00001 #ifndef H_PICKUP 00002 #define H_PICKUP 00003 00004 class PickupEffect 00005 { 00006 public: 00007 virtual ~PickupEffect() {} 00008 virtual void apply(JungleBoy* boy) = 0; 00009 }; 00010 00011 class PickupEffectCreator 00012 { 00013 public: 00014 virtual ~PickupEffectCreator() {} 00015 virtual PickupEffect* create() const = 0; 00016 }; 00017 00018 class PickupEffectFactory : public Singleton 00019 { 00020 public: 00022 static PickupEffectFactory* instance(bool destroy=false) 00023 { 00024 static PickupEffectFactory* ptr=0; 00025 if (!ptr && !destroy) ptr=new PickupEffectFactory; 00026 else 00027 if (ptr && destroy) { delete ptr; ptr=0; } 00028 return ptr; 00029 } 00030 virtual void shutdown() { instance(true); } 00031 00032 void register_creator(const xstring& name, PickupEffectCreator* c) 00033 { 00034 m_Creators[name]=c; 00035 } 00036 00037 PickupEffect* create(const xstring& name) 00038 { 00039 crt_map::iterator it=m_Creators.find(name); 00040 if (it==m_Creators.end()) return 0; 00041 return it->second->create(); 00042 } 00043 00044 private: 00045 PickupEffectFactory() {} 00046 ~PickupEffectFactory() {} 00047 PickupEffectFactory(const PickupEffectFactory&) {} 00048 00049 typedef std::map<xstring,PickupEffectCreator*> crt_map; 00050 crt_map m_Creators; 00051 }; 00052 00053 #define REGISTER_EFFECT(x) class x##_Creator : public PickupEffectCreator { public: \ 00054 x##_Creator() { PickupEffectFactory::instance()->register_creator(#x,this); }\ 00055 PickupEffect* create() const { return new x; } } g_##x##_Creator 00056 00057 00058 class Pickup : public AnimatedSprite 00059 { 00060 PickupEffect* m_Effect; 00061 int m_Type; 00062 public: 00063 Pickup() 00064 : AnimatedSprite("rsc/pickup.xml") 00065 { 00066 add_animation_object(this); 00067 int n=get_sequences_count(); 00068 m_Type=irand(n); 00069 set_active_sequence(m_Type); 00070 m_Effect=PickupEffectFactory::instance()->create(get_sequence_name(m_Type)); 00071 } 00072 00073 ~Pickup() 00074 { 00075 delete m_Effect; 00076 } 00077 00078 virtual void handle_collision(RigidBody2D* o) 00079 { 00080 if (o->get("Boy")=="YES") 00081 { 00082 JungleBoy* jb=static_cast<JungleBoy*>(o); 00083 jb->take_pickup(m_Effect,get_current_image()); 00084 m_Effect=0; 00085 } 00086 } 00087 00088 virtual bool advance(int dt) 00089 { 00090 if (!AnimatedSprite::advance(dt)) return false; 00091 return (m_Effect!=0); 00092 } 00093 }; 00094 00095 #endif // H_PICKUP 00096