RectangleLoopContainerModifier.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Copyright (c) Craftwork Games. All rights reserved.
  2. // Licensed under the MIT license.
  3. // See LICENSE file in the project root for full license information.
  4. using MonoGame.Extended.Particles.Data;
  5. namespace MonoGame.Extended.Particles.Modifiers.Containers;
  6. /// <summary>
  7. /// A modifier that constrains particles within a rectangular boundary by wrapping them around to the opposite side.
  8. /// </summary>
  9. /// <remarks>
  10. /// The <see cref="RectangleLoopContainerModifier"/> creates a looping effect by teleporting particles that exit the
  11. /// boundary to the opposite side, similar to classic arcade games where objects wrap around the screen edges. The
  12. /// rectangle is centered at each particle's trigger position (where it was emitted), creating local containment areas.
  13. /// </remarks>
  14. public class RectangleLoopContainerModifier : Modifier
  15. {
  16. /// <summary>
  17. /// Gets or sets the width of the rectangular container, in units.
  18. /// </summary>
  19. public int Width;
  20. /// <summary>
  21. /// Gets or sets the height of the rectangular container, in units.
  22. /// </summary>
  23. public int Height;
  24. /// <summary>
  25. /// Updates all particles by wrapping them around to the opposite side when they cross the rectangular boundary.
  26. /// </summary>
  27. /// <inheritdoc/>
  28. protected internal override unsafe void Update(float elapsedSeconds, ParticleIterator iterator, int particleCount)
  29. {
  30. if (!Enabled) { return; }
  31. for (int i = 0; i < particleCount && iterator.HasNext; i++)
  32. {
  33. Particle* particle = iterator.Next();
  34. var left = particle->TriggeredPos[0] + Width * -0.5f;
  35. var right = particle->TriggeredPos[0] + Width * 0.5f;
  36. var top = particle->TriggeredPos[1] + Height * -0.5f;
  37. var bottom = particle->TriggeredPos[1] + Height * 0.5f;
  38. var xPos = particle->Position[0];
  39. var yPos = particle->Position[1];
  40. if ((int)particle->Position[0] < left)
  41. {
  42. xPos = particle->Position[0] + Width;
  43. }
  44. else
  45. {
  46. if ((int)particle->Position[0] > right)
  47. {
  48. xPos = particle->Position[0] - Width;
  49. }
  50. }
  51. if ((int)particle->Position[1] < top)
  52. {
  53. yPos = particle->Position[1] + Height;
  54. }
  55. else
  56. {
  57. if ((int)particle->Position[1] > bottom)
  58. {
  59. yPos = particle->Position[1] - Height;
  60. }
  61. }
  62. particle->Position[0] = xPos;
  63. particle->Position[1] = yPos;
  64. }
  65. }
  66. }