particlesystem.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // SuperTux
  2. // Copyright (C) 2006 Matthias Braun <matze@braunis.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/particlesystem.hpp"
  17. #include <math.h>
  18. #include "supertux/globals.hpp"
  19. #include "supertux/sector.hpp"
  20. #include "util/reader.hpp"
  21. #include "util/reader_mapping.hpp"
  22. #include "util/writer.hpp"
  23. #include "object/camera.hpp"
  24. #include "video/drawing_context.hpp"
  25. #include "video/surface.hpp"
  26. #include "video/surface_batch.hpp"
  27. #include "video/video_system.hpp"
  28. #include "video/viewport.hpp"
  29. ParticleSystem::ParticleSystem(const ReaderMapping& reader, float max_particle_size_) :
  30. GameObject(reader),
  31. ExposedObject<ParticleSystem, scripting::ParticleSystem>(this),
  32. max_particle_size(max_particle_size_),
  33. z_pos(LAYER_BACKGROUND1),
  34. particles(),
  35. virtual_width(static_cast<float>(SCREEN_WIDTH) + max_particle_size * 2.0f),
  36. virtual_height(static_cast<float>(SCREEN_HEIGHT) + max_particle_size * 2.0f),
  37. enabled(true)
  38. {
  39. reader.get("enabled", enabled, true);
  40. z_pos = reader_get_layer(reader, LAYER_BACKGROUND1);
  41. }
  42. ParticleSystem::ParticleSystem(float max_particle_size_) :
  43. GameObject(),
  44. ExposedObject<ParticleSystem, scripting::ParticleSystem>(this),
  45. max_particle_size(max_particle_size_),
  46. z_pos(LAYER_BACKGROUND1),
  47. particles(),
  48. virtual_width(static_cast<float>(SCREEN_WIDTH) + max_particle_size * 2.0f),
  49. virtual_height(static_cast<float>(SCREEN_HEIGHT) + max_particle_size * 2.0f),
  50. enabled(true)
  51. {
  52. }
  53. ObjectSettings
  54. ParticleSystem::get_settings()
  55. {
  56. ObjectSettings result = GameObject::get_settings();
  57. result.add_bool(_("Enabled"), &enabled, "enabled", true);
  58. result.add_int(_("Z-pos"), &z_pos, "z-pos", LAYER_BACKGROUND1);
  59. result.reorder({"enabled", "name"});
  60. result.add_remove();
  61. return result;
  62. }
  63. ParticleSystem::~ParticleSystem()
  64. {
  65. }
  66. void
  67. ParticleSystem::draw(DrawingContext& context)
  68. {
  69. if (!enabled)
  70. return;
  71. float scrollx = context.get_translation().x;
  72. float scrolly = context.get_translation().y;
  73. const auto& region = Sector::current()->get_active_region();
  74. context.push_transform();
  75. context.set_translation(Vector(max_particle_size,max_particle_size));
  76. std::unordered_map<SurfacePtr, SurfaceBatch> batches;
  77. for (const auto& particle : particles)
  78. {
  79. // remap x,y coordinates onto screencoordinates
  80. Vector pos(0.0f, 0.0f);
  81. // horizontal wrap when particle goes off screen to the left
  82. const int particle_width = particle->texture->get_width();
  83. pos.x = fmodf(particle->pos.x - scrollx, virtual_width);
  84. if ((pos.x + static_cast<float>(particle_width)) < 0) pos.x += virtual_width;
  85. pos.y = fmodf(particle->pos.y - scrolly, virtual_height);
  86. if (pos.y < 0) pos.y += virtual_height;
  87. if(!region.contains(pos + Sector::get().get_camera().get_translation()))
  88. continue;
  89. //if(pos.x > virtual_width) pos.x -= virtual_width;
  90. //if(pos.y > virtual_height) pos.y -= virtual_height;
  91. auto it = batches.find(particle->texture);
  92. if (it == batches.end()) {
  93. const auto& batch_it = batches.emplace(particle->texture, SurfaceBatch(particle->texture));
  94. batch_it.first->second.draw(pos, particle->angle);
  95. } else {
  96. it->second.draw(pos, particle->angle);
  97. }
  98. }
  99. for(auto& it : batches) {
  100. auto& surface = it.first;
  101. auto& batch = it.second;
  102. context.color().draw_surface_batch(surface,
  103. batch.move_srcrects(),
  104. batch.move_dstrects(),
  105. batch.move_angles(),
  106. batch.get_color(),
  107. z_pos);
  108. }
  109. context.pop_transform();
  110. }
  111. void
  112. ParticleSystem::set_enabled(bool enabled_)
  113. {
  114. enabled = enabled_;
  115. }
  116. bool
  117. ParticleSystem::get_enabled() const
  118. {
  119. return enabled;
  120. }
  121. /* EOF */