You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
5.2 KiB

  1. /*******************************************************************************************
  2. *
  3. * raylib example - particles blending
  4. *
  5. * Example originally created with raylib 1.7, last time updated with raylib 3.5
  6. *
  7. * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
  8. * BSD-like license that allows static linking with closed source software
  9. *
  10. * Copyright (c) 2017-2024 Ramon Santamaria (@raysan5)
  11. *
  12. ********************************************************************************************/
  13. #include "raylib.h"
  14. #define MAX_PARTICLES 200
  15. // Particle structure with basic data
  16. typedef struct {
  17. Vector2 position;
  18. Color color;
  19. float alpha;
  20. float size;
  21. float rotation;
  22. bool active; // NOTE: Use it to activate/deactive particle
  23. } Particle;
  24. //------------------------------------------------------------------------------------
  25. // Program main entry point
  26. //------------------------------------------------------------------------------------
  27. int main(void)
  28. {
  29. // Initialization
  30. //--------------------------------------------------------------------------------------
  31. const int screenWidth = 800;
  32. const int screenHeight = 450;
  33. InitWindow(screenWidth, screenHeight, "raylib [textures] example - particles blending");
  34. // Particles pool, reuse them!
  35. Particle mouseTail[MAX_PARTICLES] = { 0 };
  36. // Initialize particles
  37. for (int i = 0; i < MAX_PARTICLES; i++)
  38. {
  39. mouseTail[i].position = (Vector2){ 0, 0 };
  40. mouseTail[i].color = (Color){ GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 };
  41. mouseTail[i].alpha = 1.0f;
  42. mouseTail[i].size = (float)GetRandomValue(1, 30)/20.0f;
  43. mouseTail[i].rotation = (float)GetRandomValue(0, 360);
  44. mouseTail[i].active = false;
  45. }
  46. float gravity = 3.0f;
  47. Texture2D smoke = LoadTexture("resources/spark_flame.png");
  48. int blending = BLEND_ALPHA;
  49. SetTargetFPS(60);
  50. //--------------------------------------------------------------------------------------
  51. // Main game loop
  52. while (!WindowShouldClose()) // Detect window close button or ESC key
  53. {
  54. // Update
  55. //----------------------------------------------------------------------------------
  56. // Activate one particle every frame and Update active particles
  57. // NOTE: Particles initial position should be mouse position when activated
  58. // NOTE: Particles fall down with gravity and rotation... and disappear after 2 seconds (alpha = 0)
  59. // NOTE: When a particle disappears, active = false and it can be reused.
  60. for (int i = 0; i < MAX_PARTICLES; i++)
  61. {
  62. if (!mouseTail[i].active)
  63. {
  64. mouseTail[i].active = true;
  65. mouseTail[i].alpha = 1.0f;
  66. mouseTail[i].position = GetMousePosition();
  67. i = MAX_PARTICLES;
  68. }
  69. }
  70. for (int i = 0; i < MAX_PARTICLES; i++)
  71. {
  72. if (mouseTail[i].active)
  73. {
  74. mouseTail[i].position.y += gravity/2;
  75. mouseTail[i].alpha -= 0.005f;
  76. if (mouseTail[i].alpha <= 0.0f) mouseTail[i].active = false;
  77. mouseTail[i].rotation += 2.0f;
  78. }
  79. }
  80. if (IsKeyPressed(KEY_SPACE))
  81. {
  82. if (blending == BLEND_ALPHA) blending = BLEND_ADDITIVE;
  83. else blending = BLEND_ALPHA;
  84. }
  85. //----------------------------------------------------------------------------------
  86. // Draw
  87. //----------------------------------------------------------------------------------
  88. BeginDrawing();
  89. ClearBackground(DARKGRAY);
  90. BeginBlendMode(blending);
  91. // Draw active particles
  92. for (int i = 0; i < MAX_PARTICLES; i++)
  93. {
  94. if (mouseTail[i].active) DrawTexturePro(smoke, (Rectangle){ 0.0f, 0.0f, (float)smoke.width, (float)smoke.height },
  95. (Rectangle){ mouseTail[i].position.x, mouseTail[i].position.y, smoke.width*mouseTail[i].size, smoke.height*mouseTail[i].size },
  96. (Vector2){ (float)(smoke.width*mouseTail[i].size/2.0f), (float)(smoke.height*mouseTail[i].size/2.0f) }, mouseTail[i].rotation,
  97. Fade(mouseTail[i].color, mouseTail[i].alpha));
  98. }
  99. EndBlendMode();
  100. DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, BLACK);
  101. if (blending == BLEND_ALPHA) DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, BLACK);
  102. else DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, RAYWHITE);
  103. EndDrawing();
  104. //----------------------------------------------------------------------------------
  105. }
  106. // De-Initialization
  107. //--------------------------------------------------------------------------------------
  108. UnloadTexture(smoke);
  109. CloseWindow(); // Close window and OpenGL context
  110. //--------------------------------------------------------------------------------------
  111. return 0;
  112. }