trampoline.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // SuperTux - Trampoline
  2. // Copyright (C) 2006 Wolfgang Becker <uafr@gmx.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/trampoline.hpp"
  17. #include "audio/sound_manager.hpp"
  18. #include "badguy/walking_badguy.hpp"
  19. #include "control/controller.hpp"
  20. #include "object/player.hpp"
  21. #include "object/coin.hpp"
  22. #include "util/reader_mapping.hpp"
  23. /* Trampoline will accelerate Tux to to VY_INITIAL, if
  24. * he jumps on it to VY_MIN. */
  25. namespace {
  26. const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav";
  27. const float VY_MIN = -900; //negative, upwards
  28. const float VY_INITIAL = -500;
  29. } // namespace
  30. Trampoline::Trampoline(const ReaderMapping& mapping) :
  31. Rock(mapping, "images/objects/trampoline/trampoline.sprite")
  32. {
  33. // Older levels use the "portable" property to determine the type.
  34. bool portable = true;
  35. mapping.get("portable", portable);
  36. if (!portable)
  37. {
  38. m_type = STATIONARY;
  39. on_type_change(TypeChange::INITIAL);
  40. }
  41. else
  42. {
  43. parse_type(mapping);
  44. }
  45. SoundManager::current()->preload(TRAMPOLINE_SOUND);
  46. }
  47. Trampoline::Trampoline(const Vector& pos, int type) :
  48. Rock(pos, "images/objects/trampoline/trampoline.sprite")
  49. {
  50. m_type = type;
  51. on_type_change(TypeChange::INITIAL);
  52. SoundManager::current()->preload(TRAMPOLINE_SOUND);
  53. }
  54. GameObjectTypes
  55. Trampoline::get_types() const
  56. {
  57. return {
  58. { "portable", _("Portable") },
  59. { "stationary", _("Stationary") }
  60. };
  61. }
  62. std::string
  63. Trampoline::get_default_sprite_name() const
  64. {
  65. switch (m_type)
  66. {
  67. case STATIONARY:
  68. return "images/objects/trampoline/trampoline_fix.sprite";
  69. default:
  70. return m_default_sprite_name;
  71. }
  72. }
  73. void
  74. Trampoline::update(float dt_sec)
  75. {
  76. if (m_sprite->animation_done()) {
  77. set_action("normal");
  78. }
  79. Rock::update(dt_sec);
  80. }
  81. HitResponse
  82. Trampoline::collision(GameObject& other, const CollisionHit& hit)
  83. {
  84. auto heavy_coin = dynamic_cast<HeavyCoin*> (&other);
  85. if (heavy_coin) {
  86. return ABORT_MOVE;
  87. }
  88. //Tramponine has to be on ground to work.
  89. if (on_ground) {
  90. auto player = dynamic_cast<Player*> (&other);
  91. //Trampoline works for player
  92. if (player) {
  93. player->override_velocity();
  94. if (player->m_does_buttjump)
  95. player->m_does_buttjump = false;
  96. float vy = player->get_physic().get_velocity_y();
  97. //player is falling down on trampoline
  98. if (hit.top && vy >= 0) {
  99. if (!(player->get_status().bonus[player->get_id()] == AIR_BONUS))
  100. {
  101. if (player->get_controller().hold(Control::JUMP))
  102. vy = VY_MIN;
  103. else if (player->get_controller().hold(Control::DOWN))
  104. vy = VY_MIN + 100;
  105. else
  106. vy = VY_INITIAL;
  107. }
  108. else
  109. {
  110. if (player->get_controller().hold(Control::JUMP))
  111. vy = VY_MIN - 80;
  112. else if (player->get_controller().hold(Control::DOWN))
  113. vy = VY_MIN - 70;
  114. else
  115. vy = VY_INITIAL - 40;
  116. }
  117. player->get_physic().set_velocity_y(vy);
  118. SoundManager::current()->play(TRAMPOLINE_SOUND, get_pos());
  119. set_action("swinging", 1);
  120. return FORCE_MOVE;
  121. }
  122. }
  123. auto walking_badguy = dynamic_cast<WalkingBadguy*> (&other);
  124. //Trampoline also works for WalkingBadguy
  125. if (walking_badguy) {
  126. float vy = walking_badguy->get_velocity_y();
  127. //walking_badguy is falling down on trampoline
  128. if (hit.top && vy >= 0) {
  129. vy = VY_INITIAL;
  130. walking_badguy->set_velocity_y(vy);
  131. SoundManager::current()->play(TRAMPOLINE_SOUND, get_pos());
  132. set_action("swinging", 1);
  133. return FORCE_MOVE;
  134. }
  135. }
  136. }
  137. return Rock::collision(other, hit);
  138. }
  139. void
  140. Trampoline::grab(MovingObject& object, const Vector& pos, Direction dir)
  141. {
  142. m_sprite->set_animation_loops(0);
  143. Rock::grab(object, pos, dir);
  144. }
  145. bool
  146. Trampoline::is_portable() const
  147. {
  148. return Rock::is_portable() && m_type == PORTABLE;
  149. }
  150. /* EOF */