198 lines
6.2 KiB
C#
198 lines
6.2 KiB
C#
/*******************************************************************************************
|
|
*
|
|
* raylib [textures] example - particles blending
|
|
*
|
|
* Example complexity rating: [★☆☆☆] 1/4
|
|
*
|
|
* Example originally created with raylib 1.7, last time updated with raylib 3.5
|
|
*
|
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
|
* BSD-like license that allows static linking with closed source software
|
|
*
|
|
* Copyright (c) 2017-2025 Ramon Santamaria (@raysan5)
|
|
*
|
|
********************************************************************************************/
|
|
|
|
namespace Examples.Textures;
|
|
|
|
public partial class ParticlesBlending : IExample
|
|
{
|
|
private const int screenWidth = 800;
|
|
private const int screenHeight = 450;
|
|
|
|
public const int MaxParticles = 200;
|
|
|
|
public string Name => "Textures / Particles Blending";
|
|
|
|
public string Title => "raylib [textures] example - particles blending";
|
|
|
|
// Particle structure with basic data
|
|
private struct Particle
|
|
{
|
|
public Vector2 Position;
|
|
public Color Color;
|
|
public float Alpha;
|
|
public float Size;
|
|
public float Rotation;
|
|
// NOTE: Use it to activate/deactive particle
|
|
public bool Active;
|
|
}
|
|
|
|
private Particle[] mouseTail;
|
|
private float gravity;
|
|
private Texture2D smoke;
|
|
private BlendMode blending;
|
|
|
|
public void Init()
|
|
{
|
|
// Particles pool, reuse them!
|
|
mouseTail = new Particle[MaxParticles];
|
|
|
|
// Initialize particles
|
|
for (var i = 0; i < mouseTail.Length; i++)
|
|
{
|
|
mouseTail[i].Position = new Vector2(0, 0);
|
|
mouseTail[i].Color = new Color(
|
|
GetRandomValue(0, 255),
|
|
GetRandomValue(0, 255),
|
|
GetRandomValue(0, 255),
|
|
255
|
|
);
|
|
mouseTail[i].Alpha = 1.0f;
|
|
mouseTail[i].Size = (float)GetRandomValue(1, 30) / 20.0f;
|
|
mouseTail[i].Rotation = GetRandomValue(0, 360);
|
|
mouseTail[i].Active = false;
|
|
}
|
|
|
|
gravity = 3.0f;
|
|
smoke = LoadTexture("resources/spark_flame.png");
|
|
blending = BlendMode.Alpha;
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
// Update
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Activate one particle every frame and Update active particles
|
|
// NOTE: Particles initial position should be mouse position when activated
|
|
// NOTE: Particles fall down with gravity and rotation... and disappear after 2 seconds (alpha = 0)
|
|
// NOTE: When a particle disappears, active = false and it can be reused
|
|
for (var i = 0; i < mouseTail.Length; i++)
|
|
{
|
|
if (!mouseTail[i].Active)
|
|
{
|
|
mouseTail[i].Active = true;
|
|
mouseTail[i].Alpha = 1.0f;
|
|
mouseTail[i].Position = GetMousePosition();
|
|
i = mouseTail.Length;
|
|
}
|
|
}
|
|
|
|
for (var i = 0; i < mouseTail.Length; i++)
|
|
{
|
|
if (mouseTail[i].Active)
|
|
{
|
|
mouseTail[i].Position.Y += gravity / 2;
|
|
mouseTail[i].Alpha -= 0.005f;
|
|
|
|
if (mouseTail[i].Alpha <= 0.0f)
|
|
{
|
|
mouseTail[i].Active = false;
|
|
}
|
|
|
|
mouseTail[i].Rotation += 2.0f;
|
|
}
|
|
}
|
|
|
|
if (IsKeyPressed(KeyboardKey.Space))
|
|
{
|
|
if (blending == BlendMode.Alpha)
|
|
{
|
|
blending = BlendMode.Additive;
|
|
}
|
|
else
|
|
{
|
|
blending = BlendMode.Alpha;
|
|
}
|
|
}
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// Draw
|
|
//----------------------------------------------------------------------------------
|
|
BeginDrawing();
|
|
ClearBackground(Color.DarkGray);
|
|
|
|
BeginBlendMode(blending);
|
|
|
|
// Draw active particles
|
|
for (var i = 0; i < mouseTail.Length; i++)
|
|
{
|
|
if (mouseTail[i].Active)
|
|
{
|
|
Rectangle source = new(0, 0, smoke.Width, smoke.Height);
|
|
Rectangle dest = new(
|
|
mouseTail[i].Position.X,
|
|
mouseTail[i].Position.Y,
|
|
smoke.Width * mouseTail[i].Size,
|
|
smoke.Height * mouseTail[i].Size
|
|
);
|
|
Vector2 position = new(
|
|
smoke.Width * mouseTail[i].Size / 2,
|
|
smoke.Height * mouseTail[i].Size / 2
|
|
);
|
|
var color = Fade(mouseTail[i].Color, mouseTail[i].Alpha);
|
|
DrawTexturePro(smoke, source, dest, position, mouseTail[i].Rotation, color);
|
|
}
|
|
}
|
|
|
|
EndBlendMode();
|
|
|
|
DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, Color.Black);
|
|
|
|
if (blending == BlendMode.Alpha)
|
|
{
|
|
DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, Color.Black);
|
|
}
|
|
else
|
|
{
|
|
DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, Color.RayWhite);
|
|
}
|
|
|
|
EndDrawing();
|
|
//----------------------------------------------------------------------------------
|
|
}
|
|
|
|
public void Unload()
|
|
{
|
|
UnloadTexture(smoke);
|
|
}
|
|
|
|
public static int Main()
|
|
{
|
|
// Initialization
|
|
//--------------------------------------------------------------------------------------
|
|
InitWindow(screenWidth, screenHeight, "raylib [textures] example - particles blending");
|
|
|
|
SetTargetFPS(60);
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
var game = new ParticlesBlending();
|
|
game.Init();
|
|
|
|
// Main game loop
|
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
|
{
|
|
game.Update();
|
|
}
|
|
|
|
game.Unload();
|
|
|
|
// De-Initialization
|
|
//--------------------------------------------------------------------------------------
|
|
CloseWindow(); // Close window and OpenGL context
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
return 0;
|
|
}
|
|
}
|