pneumatic_platform.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // SuperTux - PneumaticPlatform
  2. // Copyright (C) 2007 Christoph Sommer <christoph.sommer@2007.expires.deltadevelopment.de>
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. #include "object/pneumatic_platform.hpp"
  17. #include "object/player.hpp"
  18. #include "object/portable.hpp"
  19. #include "supertux/flip_level_transformer.hpp"
  20. #include "supertux/sector.hpp"
  21. #include "util/reader_mapping.hpp"
  22. PneumaticPlatformChild::PneumaticPlatformChild(const ReaderMapping& mapping, bool left, PneumaticPlatform& parent) :
  23. MovingSprite(mapping, "images/objects/platforms/small.sprite", LAYER_OBJECTS, COLGROUP_STATIC),
  24. m_parent(parent),
  25. m_left(left),
  26. m_contacts()
  27. {
  28. if (!m_left) {
  29. set_pos(get_pos() + Vector(get_bbox().get_width(), 0));
  30. }
  31. }
  32. PneumaticPlatformChild::~PneumaticPlatformChild()
  33. {
  34. }
  35. void
  36. PneumaticPlatformChild::update(float dt_sec)
  37. {
  38. const float offset_y = m_left ? m_parent.m_offset_y : -m_parent.m_offset_y;
  39. const Vector movement(0, (m_parent.m_start_y + offset_y) - get_pos().y);
  40. m_col.set_movement(movement);
  41. m_col.propagate_movement(movement);
  42. }
  43. HitResponse
  44. PneumaticPlatformChild::collision(GameObject& other, const CollisionHit& )
  45. {
  46. // somehow the hit parameter does not get filled in, so to determine (hit.top == true) we do this:
  47. auto mo = dynamic_cast<MovingObject*>(&other);
  48. if (!mo) return FORCE_MOVE;
  49. if ((mo->get_bbox().get_bottom()) > (m_col.m_bbox.get_top() + 2)) return FORCE_MOVE;
  50. auto pl = dynamic_cast<Player*>(mo);
  51. if (pl) {
  52. if (pl->is_big()) m_contacts.insert(nullptr);
  53. auto po = pl->get_grabbed_object();
  54. auto pomo = dynamic_cast<MovingObject*>(po);
  55. if (pomo) m_contacts.insert(pomo);
  56. }
  57. m_contacts.insert(&other);
  58. return FORCE_MOVE;
  59. }
  60. void PneumaticPlatformChild::editor_delete()
  61. {
  62. // removing a child removes the whole platform
  63. m_parent.editor_delete();
  64. }
  65. void
  66. PneumaticPlatformChild::on_flip(float height)
  67. {
  68. MovingSprite::on_flip(height);
  69. FlipLevelTransformer::transform_flip(m_flip);
  70. }
  71. PneumaticPlatform::PneumaticPlatform(const ReaderMapping& mapping) :
  72. GameObject(mapping),
  73. m_pos(0.0f, 0.0f),
  74. m_sprite_name(),
  75. m_start_y(),
  76. m_speed_y(0),
  77. m_offset_y(0),
  78. m_children()
  79. {
  80. mapping.get("x", m_pos.x);
  81. mapping.get("y", m_pos.y);
  82. mapping.get("sprite", m_sprite_name);
  83. m_children.push_back(&d_sector->add<PneumaticPlatformChild>(mapping, true, *this));
  84. m_children.push_back(&d_sector->add<PneumaticPlatformChild>(mapping, false, *this));
  85. m_start_y = m_children[0]->get_pos().y;
  86. }
  87. PneumaticPlatform::~PneumaticPlatform()
  88. {
  89. }
  90. void
  91. PneumaticPlatform::draw(DrawingContext& context)
  92. {
  93. }
  94. void
  95. PneumaticPlatform::update(float dt_sec)
  96. {
  97. const int contact_diff = static_cast<int>(m_children[0]->m_contacts.size()) - static_cast<int>(m_children[1]->m_contacts.size());
  98. for (const auto& child : m_children) {
  99. child->m_contacts.clear();
  100. }
  101. const float gravity = Sector::get().get_gravity();
  102. m_speed_y += (static_cast<float>(contact_diff) * dt_sec) * 12.8f;
  103. m_speed_y -= (m_offset_y * dt_sec * 0.05f);
  104. m_speed_y *= 1 - dt_sec;
  105. m_offset_y += m_speed_y * dt_sec * gravity;
  106. if (m_offset_y < -256) {
  107. m_offset_y = -256;
  108. m_speed_y = 0;
  109. }
  110. if (m_offset_y > 256) {
  111. m_offset_y = 256;
  112. m_speed_y = -0;
  113. }
  114. }
  115. void
  116. PneumaticPlatform::on_flip(float height)
  117. {
  118. m_pos.y = height - m_pos.y - m_children[0]->m_col.m_bbox.get_height();
  119. m_start_y = height - m_start_y - m_children[0]->m_col.m_bbox.get_height();
  120. }
  121. void
  122. PneumaticPlatform::editor_delete()
  123. {
  124. // remove children
  125. for (auto& child : m_children) {
  126. child->remove_me();
  127. }
  128. // remove self
  129. remove_me();
  130. }
  131. ObjectSettings
  132. PneumaticPlatform::get_settings()
  133. {
  134. ObjectSettings result = GameObject::get_settings();
  135. result.add_sprite(_("Sprite"), &m_sprite_name, "sprite", "images/objects/platforms/small.sprite");
  136. result.add_float(_("X"), &m_pos.x, "x", 0.0f, OPTION_HIDDEN);
  137. result.add_float(_("Y"), &m_pos.y, "y", 0.0f, OPTION_HIDDEN);
  138. return result;
  139. }
  140. void
  141. PneumaticPlatform::after_editor_set()
  142. {
  143. GameObject::after_editor_set();
  144. }
  145. /* EOF */