Sprite.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #include <sstream>
  2. #include "Sprite.h"
  3. #include "res/ResAnim.h"
  4. #include "core/Renderer.h"
  5. #include "RenderState.h"
  6. #include "utils/stringUtils.h"
  7. #include "RootActor.h"
  8. #include "Serialize.h"
  9. namespace oxygine
  10. {
  11. Sprite::Sprite()
  12. {
  13. }
  14. Sprite::~Sprite()
  15. {
  16. if (_flags & flag_manageResAnim)
  17. {
  18. ResAnim *rs = _frame.getResAnim();
  19. if (rs)
  20. rs->getAtlas()->unload();
  21. }
  22. }
  23. void Sprite::copyFrom(const Sprite &src, cloneOptions opt)
  24. {
  25. VStyleActor::copyFrom(src, opt);
  26. _frame = src._frame;
  27. _vstyle= src._vstyle;
  28. if (getManageResAnim())
  29. {
  30. ResAnim *rs = _frame.getResAnim();
  31. if (rs)
  32. rs->getAtlas()->load();
  33. }
  34. }
  35. void Sprite::setManageResAnim(bool manage)
  36. {
  37. _flags &= ~flag_manageResAnim;
  38. if (manage)
  39. _flags |= flag_manageResAnim;
  40. }
  41. std::string Sprite::dump(const dumpOptions &options) const
  42. {
  43. stringstream stream;
  44. stream << "{Sprite}\n";
  45. stream << _vstyle.dump() << " ";
  46. string tname = "null";
  47. if (_frame.getDiffuse().base)
  48. tname = _frame.getDiffuse().base->getName();
  49. stream << "texture='" << tname << "' ";
  50. if (_flags & flag_manageResAnim)
  51. stream << "manageResAnim=true";
  52. stream << Actor::dump(options);
  53. return stream.str();
  54. }
  55. void Sprite::setAnimFrame(const AnimationFrame &f)
  56. {
  57. changeAnimFrame(f);
  58. }
  59. void Sprite::setResAnim(const ResAnim *resanim)
  60. {
  61. if (resanim)
  62. {
  63. if (resanim->getTotalFrames())
  64. setAnimFrame(resanim);
  65. else
  66. {
  67. AnimationFrame fr;
  68. fr.init(0, Diffuse(), RectF(0,0,0,0), RectF(0,0,0,0), getSize());
  69. setAnimFrame(fr);
  70. }
  71. }
  72. else
  73. setAnimFrame(AnimationFrame());
  74. }
  75. void Sprite::setAnimFrame(const ResAnim *resanim, int col, int row)
  76. {
  77. //OX_ASSERT(resanim);
  78. if (!resanim)
  79. {
  80. changeAnimFrame(AnimationFrame());
  81. return;
  82. }
  83. const AnimationFrame &frame = resanim->getFrame(col, row);
  84. changeAnimFrame(frame);
  85. }
  86. void Sprite::changeAnimFrame(const AnimationFrame &frame)
  87. {
  88. if (_flags & flag_manageResAnim)
  89. {
  90. ResAnim *rs = _frame.getResAnim();
  91. if (rs)
  92. rs->getAtlas()->unload();
  93. rs = frame.getResAnim();
  94. if (rs)
  95. rs->getAtlas()->load();
  96. }
  97. _frame = frame;
  98. setSize(_frame.getFrameSize());
  99. animFrameChanged(_frame);
  100. }
  101. void Sprite::animFrameChanged(const AnimationFrame &f)
  102. {
  103. }
  104. RectF Sprite::getDestRect() const
  105. {
  106. if (_frame.getDiffuse().base)
  107. return calcDestRectF(_frame.getDestRect(), _frame.getFrameSize());
  108. return Actor::getDestRect();
  109. }
  110. void Sprite::doRender(const RenderState &rs)
  111. {
  112. _vstyle._apply(rs);
  113. const Diffuse &df = _frame.getDiffuse();
  114. if (df.base)
  115. {
  116. rs.renderer->setDiffuse(df);
  117. RectF destRect = getDestRect();
  118. rs.renderer->draw(_frame.getSrcRect(), destRect);
  119. }
  120. }
  121. void Sprite::serialize(serializedata* data)
  122. {
  123. VStyleActor::serialize(data);
  124. pugi::xml_node node = data->node;
  125. node.remove_attribute("size");
  126. const ResAnim *rs = getResAnim();
  127. if (rs)
  128. {
  129. Resource *r = rs->getParent();
  130. const char* hint = "";
  131. if (r)
  132. {
  133. r = r->getParent();
  134. if (r)
  135. hint = r->getName().c_str();
  136. }
  137. if (rs->getName().find(':') == string::npos)
  138. {
  139. char name[255];
  140. safe_sprintf(name, "%s:%s", hint, rs->getName().c_str());
  141. node.append_attribute("resanim").set_value(name);
  142. }
  143. else
  144. {
  145. node.append_attribute("resanim").set_value(rs->getName().c_str());
  146. }
  147. }
  148. node.set_name("Sprite");
  149. }
  150. void Sprite::deserialize(const deserializedata* data)
  151. {
  152. VStyleActor::deserialize(data);
  153. pugi::xml_node node = data->node;
  154. const char *res = node.attribute("resanim").as_string(0);
  155. if (res)
  156. {
  157. ResAnim *rs = safeCast<ResAnim*>(data->factory->getResAnim(res));
  158. setResAnim(rs);
  159. }
  160. }
  161. TweenAnim::TweenAnim(const ResAnim *resAnim, int row):_resAnim(resAnim), _row(row), _colStart(0), _colEnd(0)
  162. {
  163. if (_resAnim)
  164. _colEnd = _resAnim->getColumns();
  165. }
  166. void TweenAnim::init(Sprite &actor)
  167. {
  168. }
  169. void TweenAnim::setResAnim(const ResAnim *resAnim)
  170. {
  171. _resAnim = resAnim;
  172. if (_resAnim)
  173. _colEnd = _resAnim->getColumns();
  174. }
  175. void TweenAnim::setColumns(int start, int end)
  176. {
  177. _colStart = start; _colEnd = end;
  178. }
  179. void TweenAnim::update(Sprite &actor, float p, const UpdateState &us)
  180. {
  181. OX_ASSERT(_resAnim);
  182. int col = interpolate<int>(_colStart, _colEnd, p);
  183. if (_colStart > _colEnd)
  184. {
  185. if (col <= _colEnd)
  186. col = _colEnd + 1;
  187. OX_ASSERT(col <= _colStart && col > _colEnd);
  188. }
  189. else
  190. {
  191. if (col >= _colEnd)
  192. col = _colEnd - 1;
  193. OX_ASSERT(col >= _colStart && col < _colEnd);
  194. }
  195. actor.setAnimFrame(_resAnim->getFrame(col, _row));
  196. }
  197. }