00001 #ifndef H_SDLPP_ANIMATION
00002 #define H_SDLPP_ANIMATION
00003
00004 #include <sdlpp_physics.h>
00005
00006 namespace SDLPP {
00007
00009
00010
00011
00012
00013
00014
00016
00017 class Sprite
00018 {
00019 class Frame
00020 {
00021 Bitmap image;
00022 int duration;
00023 CollisionModel2D col_model;
00024 public:
00025 Bitmap get_bitmap() { return image; }
00026 void set_bitmap(Bitmap bmp) { image=bmp; }
00027 int get_duration() const { return duration; }
00028 void set_duration(int d) { duration=d; }
00029 CollisionModel2D& get_col_model()
00030 {
00031 if (col_model.empty()) col_model.build(image);
00032 return col_model;
00033 }
00034 };
00035 typedef std::vector<Frame> frame_vec;
00036 struct Sequence
00037 {
00038 Sequence(const xstring& nm="", double base_v=0)
00039 : total_duration(0),
00040 name(nm),
00041 base_velocity(base_v)
00042 {}
00043 frame_vec frames;
00044 int total_duration;
00045 xstring name;
00046 double base_velocity;
00047 };
00048 typedef std::vector<Sequence> sequence_vec;
00049 typedef std::map<xstring,xstring> flags_map;
00050
00051 sequence_vec m_Sequences;
00052 flags_map m_Flags;
00053 public:
00054 Sprite();
00055 virtual ~Sprite();
00056 Sprite(const Sprite& rhs);
00057 Sprite& operator= (const Sprite& rhs);
00058
00059 int get_sequences_count() const;
00060 xstring get_sequence_name(int seq) const;
00061
00062 int add_animation_sequence(const xstring& name, double base_velocity);
00063 int add_animation_frame(int seq, Bitmap bmp, int duration);
00064 void clear();
00065
00066 void set_flag(const xstring& flag, const xstring& value);
00067 const xstring& get_flag(const xstring& flag) const;
00068
00069 int advance_sequence(int seq, int& last_t, int dt, const dVec2& velocity);
00070 Bitmap get_bitmap(int seq, int frame);
00071 CollisionModel2D& get_col_model(int seq, int frame);
00072 };
00073
00074 class SpriteLoader : public Loader<Sprite>
00075 {
00076 public:
00077 virtual void load(Sprite& s, const xstring& name, ResourceFile* rf);
00078 };
00079
00080 class SpriteCache : public Cache<Sprite>
00081 {
00082 public:
00083 static SpriteCache* instance()
00084 {
00085 static std::auto_ptr<SpriteCache> ptr(new SpriteCache);
00086 return ptr.get();
00087 }
00088
00089 static SpriteLoader& get_loader()
00090 {
00091 static SpriteLoader sl;
00092 return sl;
00093 }
00094
00095 private:
00096 friend class std::auto_ptr<SpriteCache>;
00097 SpriteCache() : Cache<Sprite>(get_loader()) {}
00098 ~SpriteCache() {}
00099 SpriteCache(const SpriteCache&) : Cache<Sprite>(get_loader()) {}
00100 };
00101
00102 inline Sprite& sprite(const xstring& name, ResourceFile* rf=0)
00103 {
00104 return SpriteCache::instance()->get(name,rf);
00105 }
00106
00107 class AnimatedSprite : public RigidBody2D
00108 {
00109 Sprite& m_Sprite;
00110 int m_ActiveSequence;
00111 int m_DT;
00112 int m_CurrentFrame;
00113 Bitmap m_CurrentImage;
00114 bool m_Volatile;
00115 PropertyBag m_Properties;
00116
00117 void init();
00118 public:
00119 AnimatedSprite(Sprite& spr);
00120 AnimatedSprite(const xstring& spr_xml, ResourceFile* rf=0);
00121
00122 int get_sequences_count() const;
00123 xstring get_sequence_name(int seq) const;
00124
00125 void set_active_sequence(int seq);
00126 int get_active_sequence() const { return m_ActiveSequence; }
00127 int get_current_frame() const { return m_CurrentFrame; }
00128
00129 Bitmap get_current_image() { return m_CurrentImage; }
00130
00131
00132 virtual bool advance(int dt);
00133 virtual void render(GameView& gv);
00134 virtual bool is_volatile() const { return m_Volatile; }
00135 virtual bool is_static_sprite() const { return false; }
00136
00137 virtual iRect2 get_rect() const;
00138 virtual CollisionModel2D& get_col_model()
00139 {
00140 int frame=(m_CurrentFrame<0?0:m_CurrentFrame);
00141 return m_Sprite.get_col_model(m_ActiveSequence,frame);
00142 }
00143 virtual xstring get_flag(const xstring& flag) { return m_Sprite.get_flag(flag); }
00144
00145 void set(const xstring& name, const xstring& value) { m_Properties.set(name,value); }
00146 const xstring& get(const xstring& name) const { return m_Properties.get(name); }
00147
00148 };
00149
00150 class TileLayer : public Array2D<Sprite>, public GameObject
00151 {
00152 typedef Array2D<Sprite> base;
00153 public:
00154 TileLayer() {}
00155 TileLayer(int width, int height) : base(width,height) {}
00156 void render(GameView& view);
00157 bool advance(int dt);
00158 };
00159
00160
00161 class AnimationManager : public GameObject, public Singleton
00162 {
00163 public:
00164 static AnimationManager* instance()
00165 {
00166 static std::auto_ptr<AnimationManager> ptr(new AnimationManager);
00167 return ptr.get();
00168 }
00169
00170 virtual void shutdown()
00171 {
00172 clear();
00173 }
00174
00175 void start_animation_scene()
00176 {
00177 m_Scene=true;
00178 }
00179
00180 void add_animation_object(RigidBody2D* obj)
00181 {
00182 if (!m_Scene) THROW("Animation Scene not started.");
00183 m_Objects.push_back(obj);
00184 if (obj->is_collidable()) m_CollidableObjects.push_back(obj);
00185 }
00186
00187 virtual bool advance(int dt);
00188 virtual void render(GameView& view)
00189 {
00190 obj_list::iterator b=m_Objects.begin(),e=m_Objects.end();
00191 for(;b!=e;++b)
00192 {
00193 GameObject* obj=*b;
00194 obj->render(view);
00195 }
00196 }
00197
00198 void clear();
00199 private:
00200 void check_for_collisions(int dt);
00201
00202 friend class std::auto_ptr<AnimationManager>;
00203 AnimationManager() : m_Scene(false) {}
00204 ~AnimationManager() {}
00205 AnimationManager(const AnimationManager&) {}
00206
00207 typedef std::list<RigidBody2D*> obj_list;
00208 typedef obj_list::iterator iterator;
00209 obj_list m_Objects;
00210 obj_list m_CollidableObjects;
00211 bool m_Scene;
00212 };
00213
00214 class AnimationScene
00215 {
00216 public:
00217 AnimationScene() { AnimationManager::instance()->start_animation_scene(); }
00218 ~AnimationScene() { AnimationManager::instance()->clear(); }
00219 };
00220
00221 #define ANIMATION_SCENE AnimationScene l_##__LINE__
00222
00223 inline void add_animation_object(RigidBody2D* obj)
00224 {
00225 AnimationManager::instance()->add_animation_object(obj);
00226 }
00227
00228 inline void advance(int dt)
00229 {
00230 AnimationManager::instance()->advance(dt);
00231 }
00232
00233 inline void render(GameView& view)
00234 {
00235 AnimationManager::instance()->render(view);
00236 }
00237
00238
00239 }
00240
00241
00242 #endif // H_SDLPP_ANIMATION
00243
00244