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