00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "sprite/sprite.hpp"
00018
00019 #include <assert.h>
00020 #include <math.h>
00021
00022 #include "supertux/timer.hpp"
00023
00024 Sprite::Sprite(SpriteData& newdata) :
00025 data(newdata),
00026 frame(0),
00027 frameidx(0),
00028 animation_loops(-1),
00029 last_ticks(),
00030 angle(0.0f),
00031 color(1.0f, 1.0f, 1.0f, 1.0f),
00032 blend(),
00033 action(data.get_action("normal"))
00034 {
00035 if(!action)
00036 action = data.actions.begin()->second;
00037 last_ticks = game_time;
00038 }
00039
00040 Sprite::Sprite(const Sprite& other) :
00041 data(other.data),
00042 frame(other.frame),
00043 frameidx(other.frameidx),
00044 animation_loops(other.animation_loops),
00045 last_ticks(game_time),
00046 angle(0.0f),
00047 color(1.0f, 1.0f, 1.0f, 1.0f),
00048 blend(),
00049 action(other.action)
00050 {
00051 }
00052
00053 Sprite::~Sprite()
00054 {
00055 }
00056
00057 SpritePtr
00058 Sprite::clone() const
00059 {
00060 return SpritePtr(new Sprite(*this));
00061 }
00062
00063 void
00064 Sprite::set_action(const std::string& name, int loops)
00065 {
00066 if(action && action->name == name)
00067 return;
00068
00069 const SpriteData::Action* newaction = data.get_action(name);
00070 if(!newaction) {
00071 log_debug << "Action '" << name << "' not found." << std::endl;
00072 return;
00073 }
00074
00075 action = newaction;
00076 animation_loops = loops;
00077 frame = 0;
00078 frameidx = 0;
00079 }
00080
00081 void
00082 Sprite::set_action_continued(const std::string& name)
00083 {
00084 if(action && action->name == name)
00085 return;
00086
00087 const SpriteData::Action* newaction = data.get_action(name);
00088 if(!newaction) {
00089 log_debug << "Action '" << name << "' not found." << std::endl;
00090 return;
00091 }
00092
00093 action = newaction;
00094 update();
00095 }
00096
00097 bool
00098 Sprite::animation_done()
00099 {
00100 return animation_loops == 0;
00101 }
00102
00103 void
00104 Sprite::update()
00105 {
00106 float frame_inc = action->fps * (game_time - last_ticks);
00107 last_ticks = game_time;
00108
00109 frame += frame_inc;
00110
00111 while(frame >= 1.0f) {
00112 frame -= 1.0f;
00113 frameidx++;
00114 }
00115
00116 while(frameidx >= get_frames()) {
00117 frameidx -= get_frames();
00118 animation_loops--;
00119 if(animation_done()) {
00120 break;
00121 }
00122 }
00123
00124 if(animation_done()) {
00125 frame = 0;
00126 frameidx = get_frames()-1;
00127 }
00128
00129 assert(frameidx < get_frames());
00130 }
00131
00132 void
00133 Sprite::draw(DrawingContext& context, const Vector& pos, int layer,
00134 DrawingEffect effect)
00135 {
00136 assert(action != 0);
00137 update();
00138
00139 context.set_drawing_effect(effect);
00140 context.draw_surface(action->surfaces[frameidx],
00141 pos - Vector(action->x_offset, action->y_offset),
00142 angle,
00143 color,
00144 blend,
00145 layer + action->z_order);
00146 }
00147
00148 void
00149 Sprite::draw_part(DrawingContext& context, const Vector& source,
00150 const Vector& size, const Vector& pos, int layer)
00151 {
00152 assert(action != 0);
00153 update();
00154
00155 context.draw_surface_part(action->surfaces[frameidx], source, size,
00156 pos - Vector(action->x_offset, action->y_offset),
00157 layer + action->z_order);
00158 }
00159
00160 int
00161 Sprite::get_width() const
00162 {
00163 assert(frameidx < get_frames());
00164 return (int) action->surfaces[get_frame()]->get_width();
00165 }
00166
00167 int
00168 Sprite::get_height() const
00169 {
00170 assert(frameidx < get_frames());
00171 return (int) action->surfaces[get_frame()]->get_height();
00172 }
00173
00174 float
00175 Sprite::get_current_hitbox_x_offset() const
00176 {
00177 return action->x_offset;
00178 }
00179
00180 float
00181 Sprite::get_current_hitbox_y_offset() const
00182 {
00183 return action->y_offset;
00184 }
00185
00186 float
00187 Sprite::get_current_hitbox_width() const
00188 {
00189 return action->hitbox_w;
00190 }
00191
00192 float
00193 Sprite::get_current_hitbox_height() const
00194 {
00195 return action->hitbox_h;
00196 }
00197
00198 Rectf
00199 Sprite::get_current_hitbox() const
00200 {
00201 return Rectf(action->x_offset, action->y_offset, action->x_offset + action->hitbox_w, action->y_offset + action->hitbox_h);
00202 }
00203
00204 void
00205 Sprite::set_angle(float a)
00206 {
00207 angle = a;
00208 }
00209
00210 float
00211 Sprite::get_angle() const
00212 {
00213 return angle;
00214 }
00215
00216 void
00217 Sprite::set_color(const Color& c)
00218 {
00219 color = c;
00220 }
00221
00222 Color
00223 Sprite::get_color() const
00224 {
00225 return color;
00226 }
00227
00228 void
00229 Sprite::set_blend(const Blend& b)
00230 {
00231 blend = b;
00232 }
00233
00234 Blend
00235 Sprite::get_blend() const
00236 {
00237 return blend;
00238 }
00239
00240