feat: backporting existing raylib-cs examples and new official raylib examples to WASM, adopting raylib's original code style
This commit is contained in:
parent
6aa91e3097
commit
f804ab7773
41 changed files with 38997 additions and 10578 deletions
275
Examples/Shapes/BallPhysics.cs
Normal file
275
Examples/Shapes/BallPhysics.cs
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - ball physics
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by David Buzatto (@davidbuzatto) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* 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) 2025 David Buzatto (@davidbuzatto)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
using static Raylib_cs.Raymath;
|
||||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public partial class BallPhysics : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
private const int MAX_BALLS = 5000; // Maximum quantity of balls
|
||||
|
||||
public string Name => "Shapes / Ball Physics";
|
||||
|
||||
public string Title => "raylib [shapes] example - ball physics";
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Ball data type
|
||||
private struct Ball
|
||||
{
|
||||
public Vector2 position;
|
||||
public Vector2 speed;
|
||||
public Vector2 prevPosition;
|
||||
public float radius;
|
||||
public float friction;
|
||||
public float elasticity;
|
||||
public Color color;
|
||||
public bool grabbed;
|
||||
}
|
||||
|
||||
private Ball[] balls;
|
||||
private int ballCount;
|
||||
private int grabbedBallIndex; // Index of the current ball that is grabbed (-1 if none)
|
||||
private Vector2 pressOffset; // Mouse press offset relative to the ball that grabbedd
|
||||
|
||||
private float gravity; // World gravity
|
||||
|
||||
private Vector2 windowPosition;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
balls = new Ball[MAX_BALLS];
|
||||
|
||||
// Init first ball in the array
|
||||
balls[0] = new Ball
|
||||
{
|
||||
position = new Vector2(GetScreenWidth()/2.0f, GetScreenHeight()/2.0f),
|
||||
speed = new Vector2(200, 200),
|
||||
prevPosition = new Vector2(0, 0),
|
||||
radius = 40,
|
||||
friction = 0.99f,
|
||||
elasticity = 0.9f,
|
||||
color = Color.Blue,
|
||||
grabbed = false
|
||||
};
|
||||
|
||||
ballCount = 1;
|
||||
grabbedBallIndex = -1; // A reference to the current ball that is grabbed
|
||||
pressOffset = new Vector2(0, 0); // Mouse press offset relative to the ball that grabbedd
|
||||
|
||||
gravity = 100; // World gravity
|
||||
|
||||
windowPosition = GetWindowPosition();
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
float delta = GetFrameTime();
|
||||
Vector2 mousePos = GetMousePosition();
|
||||
|
||||
// Checks if a ball was grabbed
|
||||
if (IsMouseButtonPressed(MouseButton.Left))
|
||||
{
|
||||
for (int i = ballCount - 1; i >= 0; i--)
|
||||
{
|
||||
pressOffset.X = mousePos.X - balls[i].position.X;
|
||||
pressOffset.Y = mousePos.Y - balls[i].position.Y;
|
||||
|
||||
// If the distance between the ball position and the mouse press position
|
||||
// is less than or equal to the ball radius, the event occurred inside the ball
|
||||
if (MathF.Sqrt(pressOffset.X*pressOffset.X + pressOffset.Y*pressOffset.Y) <= balls[i].radius)
|
||||
{
|
||||
balls[i].grabbed = true;
|
||||
grabbedBallIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Releases any ball the was grabbed
|
||||
if (IsMouseButtonReleased(MouseButton.Left))
|
||||
{
|
||||
if (grabbedBallIndex != -1)
|
||||
{
|
||||
balls[grabbedBallIndex].grabbed = false;
|
||||
grabbedBallIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a new ball
|
||||
if (IsMouseButtonPressed(MouseButton.Right) || (IsKeyDown(KeyboardKey.LeftControl) && IsMouseButtonDown(MouseButton.Right)))
|
||||
{
|
||||
if (ballCount < MAX_BALLS)
|
||||
{
|
||||
balls[ballCount++] = new Ball
|
||||
{
|
||||
position = mousePos,
|
||||
speed = new Vector2(GetRandomValue(-300, 300), GetRandomValue(-300, 300)),
|
||||
prevPosition = new Vector2(0, 0),
|
||||
radius = 20.0f + GetRandomValue(0, 30),
|
||||
friction = 0.99f,
|
||||
elasticity = 0.9f,
|
||||
color = new Color(GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255),
|
||||
grabbed = false
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Get window position change for shaking
|
||||
Vector2 windowPositionDelta = Vector2Subtract(windowPosition, GetWindowPosition());
|
||||
|
||||
if (Vector2Length(windowPositionDelta) > 5.0f)
|
||||
{
|
||||
for (int i = 0; i < ballCount; i++)
|
||||
{
|
||||
if (!balls[i].grabbed) balls[i].speed = Vector2Add(balls[i].speed, Vector2Scale(windowPositionDelta, 10.0f));
|
||||
}
|
||||
}
|
||||
|
||||
// Shake balls
|
||||
if (IsMouseButtonPressed(MouseButton.Middle))
|
||||
{
|
||||
for (int i = 0; i < ballCount; i++)
|
||||
{
|
||||
if (!balls[i].grabbed) balls[i].speed = new Vector2(GetRandomValue(-2000, 2000), GetRandomValue(-2000, 2000));
|
||||
}
|
||||
}
|
||||
|
||||
// Changes gravity
|
||||
gravity += GetMouseWheelMove()*5;
|
||||
|
||||
// Updates each ball state
|
||||
for (int i = 0; i < ballCount; i++)
|
||||
{
|
||||
// The ball is not grabbed
|
||||
if (!balls[i].grabbed)
|
||||
{
|
||||
// Ball repositioning using the velocity
|
||||
balls[i].position.X += balls[i].speed.X * delta;
|
||||
balls[i].position.Y += balls[i].speed.Y * delta;
|
||||
|
||||
// Does the ball hit the screen right boundary?
|
||||
if ((balls[i].position.X + balls[i].radius) >= screenWidth)
|
||||
{
|
||||
balls[i].position.X = screenWidth - balls[i].radius; // Ball repositioning
|
||||
balls[i].speed.X = -balls[i].speed.X*balls[i].elasticity; // Elasticity makes the ball lose 10% of its velocity on hit
|
||||
}
|
||||
// Does the ball hit the screen left boundary?
|
||||
else if ((balls[i].position.X - balls[i].radius) <= 0)
|
||||
{
|
||||
balls[i].position.X = balls[i].radius;
|
||||
balls[i].speed.X = -balls[i].speed.X*balls[i].elasticity;
|
||||
}
|
||||
|
||||
// The same for y axis
|
||||
if ((balls[i].position.Y + balls[i].radius) >= screenHeight)
|
||||
{
|
||||
balls[i].position.Y = screenHeight - balls[i].radius;
|
||||
balls[i].speed.Y = -balls[i].speed.Y*balls[i].elasticity;
|
||||
}
|
||||
else if ((balls[i].position.Y - balls[i].radius) <= 0)
|
||||
{
|
||||
balls[i].position.Y = balls[i].radius;
|
||||
balls[i].speed.Y = -balls[i].speed.Y*balls[i].elasticity;
|
||||
}
|
||||
|
||||
// Friction makes the ball lose 1% of its velocity each frame
|
||||
balls[i].speed.X = balls[i].speed.X*balls[i].friction;
|
||||
// Gravity affects only the y axis
|
||||
balls[i].speed.Y = balls[i].speed.Y*balls[i].friction + gravity;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ball repositioning using the mouse position
|
||||
balls[i].position.X = mousePos.X - pressOffset.X;
|
||||
balls[i].position.Y = mousePos.Y - pressOffset.Y;
|
||||
|
||||
// While the ball is grabbed, recalculates its velocity
|
||||
balls[i].speed.X = (balls[i].position.X - balls[i].prevPosition.X)/delta;
|
||||
balls[i].speed.Y = (balls[i].position.Y - balls[i].prevPosition.Y)/delta;
|
||||
balls[i].prevPosition = balls[i].position;
|
||||
}
|
||||
}
|
||||
|
||||
windowPosition = GetWindowPosition();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
for (int i = 0; i < ballCount; i++)
|
||||
{
|
||||
DrawCircleV(balls[i].position, balls[i].radius, balls[i].color);
|
||||
DrawCircleLinesV(balls[i].position, balls[i].radius, Color.Black);
|
||||
}
|
||||
|
||||
DrawText("grab a ball by pressing with the mouse and throw it by releasing", 10, 10, 10, Color.DarkGray);
|
||||
DrawText("right click to create new balls (keep left control pressed to create a lot)", 10, 30, 10, Color.DarkGray);
|
||||
DrawText("use mouse wheel to change gravity", 10, 50, 10, Color.DarkGray);
|
||||
DrawText("middle click to shake", 10, 70, 10, Color.DarkGray);
|
||||
DrawText($"BALL COUNT: {ballCount}", 10, GetScreenHeight() - 70, 20, Color.Black);
|
||||
DrawText($"GRAVITY: {gravity:F2}", 10, GetScreenHeight() - 40, 20, Color.Black);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new BallPhysics();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - Draw basic shapes 2d (rectangle, circle, line...)
|
||||
* raylib [shapes] example - basic shapes
|
||||
*
|
||||
* This example has been created using raylib 1.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 4.2
|
||||
*
|
||||
* 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) 2014-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -14,66 +18,101 @@ using static Raylib_cs.Raylib;
|
|||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public class BasicShapes
|
||||
public partial class BasicShapes : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Basic Shapes";
|
||||
|
||||
public string Title => "raylib [shapes] example - basic shapes";
|
||||
|
||||
private float rotation;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
rotation = 0.0f;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
rotation += 0.2f;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawText("some basic shapes available on raylib", 20, 20, 20, Color.DarkGray);
|
||||
|
||||
// Circle shapes and lines
|
||||
DrawCircle(screenWidth / 5, 120, 35, Color.DarkBlue);
|
||||
DrawCircleGradient(new Vector2(screenWidth / 5.0f, 220.0f), 60, Color.Green, Color.SkyBlue);
|
||||
DrawCircleLines(screenWidth / 5, 340, 80, Color.DarkBlue);
|
||||
DrawEllipse(screenWidth / 5, 120, 25, 20, Color.Yellow);
|
||||
DrawEllipseLines(screenWidth / 5, 120, 30, 25, Color.Yellow);
|
||||
|
||||
// Rectangle shapes and lines
|
||||
DrawRectangle(screenWidth / 4 * 2 - 60, 100, 120, 60, Color.Red);
|
||||
DrawRectangleGradientH(screenWidth / 4 * 2 - 90, 170, 180, 130, Color.Maroon, Color.Gold);
|
||||
DrawRectangleLines(screenWidth / 4 * 2 - 40, 320, 80, 60, Color.Orange); // NOTE: Uses QUADS internally, not lines
|
||||
|
||||
// Triangle shapes and lines
|
||||
DrawTriangle(
|
||||
new Vector2(screenWidth / 4.0f * 3.0f, 80.0f),
|
||||
new Vector2(screenWidth / 4.0f * 3.0f - 60.0f, 150.0f),
|
||||
new Vector2(screenWidth / 4.0f * 3.0f + 60.0f, 150.0f), Color.Violet
|
||||
);
|
||||
|
||||
DrawTriangleLines(
|
||||
new Vector2(screenWidth / 4.0f * 3.0f, 160.0f),
|
||||
new Vector2(screenWidth / 4.0f * 3.0f - 20.0f, 230.0f),
|
||||
new Vector2(screenWidth / 4.0f * 3.0f + 20.0f, 230.0f), Color.DarkBlue
|
||||
);
|
||||
|
||||
// Polygon shapes and lines
|
||||
DrawPoly(new Vector2(screenWidth / 4.0f * 3, 330), 6, 80, rotation, Color.Brown);
|
||||
DrawPolyLines(new Vector2(screenWidth / 4.0f * 3, 330), 6, 90, rotation, Color.Brown);
|
||||
DrawPolyLinesEx(new Vector2(screenWidth / 4.0f * 3, 330), 6, 85, rotation, 6, Color.Beige);
|
||||
|
||||
// NOTE: We draw all LINES based shapes together to optimize internal drawing,
|
||||
// this way, all LINES are rendered in a single draw pass
|
||||
DrawLine(18, 42, screenWidth - 18, 42, Color.Black);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - basic shapes");
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - basic shapes drawing");
|
||||
|
||||
SetTargetFPS(60);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new BasicShapes();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawText("some basic shapes available on raylib", 20, 20, 20, Color.DarkGray);
|
||||
|
||||
DrawLine(18, 42, screenWidth - 18, 42, Color.Black);
|
||||
|
||||
DrawCircle(screenWidth / 4, 120, 35, Color.DarkBlue);
|
||||
DrawCircleGradient(new Vector2(screenWidth / 4, 220), 60, Color.Green, Color.SkyBlue);
|
||||
DrawCircleLines(screenWidth / 4, 340, 80, Color.DarkBlue);
|
||||
|
||||
DrawRectangle(screenWidth / 4 * 2 - 60, 100, 120, 60, Color.Red);
|
||||
DrawRectangleGradientH(screenWidth / 4 * 2 - 90, 170, 180, 130, Color.Maroon, Color.Gold);
|
||||
DrawRectangleLines(screenWidth / 4 * 2 - 40, 320, 80, 60, Color.Orange);
|
||||
|
||||
DrawTriangle(
|
||||
new Vector2(screenWidth / 4 * 3, 80),
|
||||
new Vector2(screenWidth / 4 * 3 - 60, 150),
|
||||
new Vector2(screenWidth / 4 * 3 + 60, 150), Color.Violet
|
||||
);
|
||||
|
||||
DrawTriangleLines(
|
||||
new Vector2(screenWidth / 4 * 3, 160),
|
||||
new Vector2(screenWidth / 4 * 3 - 20, 230),
|
||||
new Vector2(screenWidth / 4 * 3 + 20, 230), Color.DarkBlue
|
||||
);
|
||||
|
||||
DrawPoly(new Vector2(screenWidth / 4 * 3, 320), 6, 80, 0, Color.Brown);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,16 @@
|
|||
*
|
||||
* raylib [shapes] example - bouncing ball
|
||||
*
|
||||
* This example has been created using raylib 1.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Copyright (c) 2013 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Ramon Santamaria (@raysan5), reviewed by Jopestpe (@jopestpe)
|
||||
*
|
||||
* 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) 2013-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -14,83 +20,136 @@ using static Raylib_cs.Raylib;
|
|||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public class BouncingBall
|
||||
public partial class BouncingBall : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Bouncing Ball";
|
||||
|
||||
public string Title => "raylib [shapes] example - bouncing ball";
|
||||
|
||||
public ConfigFlags ConfigFlags => ConfigFlags.Msaa4xHint;
|
||||
|
||||
private Vector2 ballPosition;
|
||||
private Vector2 ballSpeed;
|
||||
private int ballRadius;
|
||||
private float gravity;
|
||||
|
||||
private bool useGravity;
|
||||
private bool pause;
|
||||
private int framesCounter;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
ballPosition = new(GetScreenWidth() / 2.0f, GetScreenHeight() / 2.0f);
|
||||
ballSpeed = new(5.0f, 4.0f);
|
||||
ballRadius = 20;
|
||||
gravity = 0.2f;
|
||||
|
||||
useGravity = true;
|
||||
pause = false;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//-----------------------------------------------------
|
||||
if (IsKeyPressed(KeyboardKey.G))
|
||||
{
|
||||
useGravity = !useGravity;
|
||||
}
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
pause = !pause;
|
||||
}
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
ballPosition.X += ballSpeed.X;
|
||||
ballPosition.Y += ballSpeed.Y;
|
||||
|
||||
if (useGravity)
|
||||
{
|
||||
ballSpeed.Y += gravity;
|
||||
}
|
||||
|
||||
// Check walls collision for bouncing
|
||||
if ((ballPosition.X >= (GetScreenWidth() - ballRadius)) || (ballPosition.X <= ballRadius))
|
||||
{
|
||||
ballSpeed.X *= -1.0f;
|
||||
}
|
||||
if ((ballPosition.Y >= (GetScreenHeight() - ballRadius)) || (ballPosition.Y <= ballRadius))
|
||||
{
|
||||
ballSpeed.Y *= -0.95f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
framesCounter++;
|
||||
}
|
||||
//-----------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//-----------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawCircleV(ballPosition, (float)ballRadius, Color.Maroon);
|
||||
DrawText("PRESS SPACE to PAUSE BALL MOVEMENT", 10, GetScreenHeight() - 25, 20, Color.LightGray);
|
||||
|
||||
if (useGravity)
|
||||
{
|
||||
DrawText("GRAVITY: ON (Press G to disable)", 10, GetScreenHeight() - 50, 20, Color.DarkGreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText("GRAVITY: OFF (Press G to enable)", 10, GetScreenHeight() - 50, 20, Color.Red);
|
||||
}
|
||||
|
||||
// On pause, we draw a blinking message
|
||||
if (pause && ((framesCounter / 30) % 2) != 0)
|
||||
{
|
||||
DrawText("PAUSED", 350, 200, 30, Color.Gray);
|
||||
}
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//-----------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//---------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(ConfigFlags.Msaa4xHint);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - bouncing ball");
|
||||
|
||||
Vector2 ballPosition = new(GetScreenWidth() / 2, GetScreenHeight() / 2);
|
||||
Vector2 ballSpeed = new(5.0f, 4.0f);
|
||||
int ballRadius = 20;
|
||||
|
||||
bool pause = false;
|
||||
int framesCounter = 0;
|
||||
|
||||
SetTargetFPS(60);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//----------------------------------------------------------
|
||||
|
||||
var game = new BouncingBall();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//-----------------------------------------------------
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
pause = !pause;
|
||||
}
|
||||
|
||||
if (!pause)
|
||||
{
|
||||
ballPosition.X += ballSpeed.X;
|
||||
ballPosition.Y += ballSpeed.Y;
|
||||
|
||||
// Check walls collision for bouncing
|
||||
if ((ballPosition.X >= (GetScreenWidth() - ballRadius)) || (ballPosition.X <= ballRadius))
|
||||
{
|
||||
ballSpeed.X *= -1.0f;
|
||||
}
|
||||
if ((ballPosition.Y >= (GetScreenHeight() - ballRadius)) || (ballPosition.Y <= ballRadius))
|
||||
{
|
||||
ballSpeed.Y *= -1.0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
framesCounter += 1;
|
||||
}
|
||||
//-----------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//-----------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawCircleV(ballPosition, ballRadius, Color.Maroon);
|
||||
DrawText("PRESS SPACE to PAUSE BALL MOVEMENT", 10, GetScreenHeight() - 25, 20, Color.LightGray);
|
||||
|
||||
// On pause, we draw a blinking message
|
||||
if (pause && ((framesCounter / 30) % 2) == 0)
|
||||
{
|
||||
DrawText("PAUSED", 350, 200, 30, Color.Gray);
|
||||
}
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//-----------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//---------------------------------------------------------
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//----------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
290
Examples/Shapes/BulletHell.cs
Normal file
290
Examples/Shapes/BulletHell.cs
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - bullet hell
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||
*
|
||||
* Example contributed by Zero (@zerohorsepower) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* 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) 2025 Zero (@zerohorsepower)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public partial class BulletHell : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
private const int MAX_BULLETS = 500000; // Max bullets to be processed
|
||||
|
||||
public string Name => "Shapes / Bullet Hell";
|
||||
|
||||
public string Title => "raylib [shapes] example - bullet hell";
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
private struct Bullet
|
||||
{
|
||||
public Vector2 position; // Bullet position on screen
|
||||
public Vector2 acceleration; // Amount of pixels to be incremented to position every frame
|
||||
public bool disabled; // Skip processing and draw case out of screen
|
||||
public Color color; // Bullet color
|
||||
}
|
||||
|
||||
// Bullets definition
|
||||
private Bullet[] bullets;
|
||||
private int bulletCount;
|
||||
private int bulletDisabledCount; // Used to calculate how many bullets are on screen
|
||||
private int bulletRadius;
|
||||
private float bulletSpeed;
|
||||
private int bulletRows;
|
||||
private Color[] bulletColor;
|
||||
|
||||
// Spawner variables
|
||||
private float baseDirection;
|
||||
private int angleIncrement; // After spawn all bullet rows, increment this value on the baseDirection for next the frame
|
||||
private float spawnCooldown;
|
||||
private float spawnCooldownTimer;
|
||||
|
||||
// Magic circle
|
||||
private float magicCircleRotation;
|
||||
|
||||
// Used on performance drawing
|
||||
private RenderTexture2D bulletTexture;
|
||||
|
||||
private bool drawInPerformanceMode; // Switch between DrawCircle() and DrawTexture()
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Bullets definition
|
||||
bullets = new Bullet[MAX_BULLETS]; // Bullets array
|
||||
bulletCount = 0;
|
||||
bulletDisabledCount = 0;
|
||||
bulletRadius = 10;
|
||||
bulletSpeed = 3.0f;
|
||||
bulletRows = 6;
|
||||
bulletColor = new[] { Color.Red, Color.Blue };
|
||||
|
||||
// Spawner variables
|
||||
baseDirection = 0;
|
||||
angleIncrement = 5;
|
||||
spawnCooldown = 2;
|
||||
spawnCooldownTimer = spawnCooldown;
|
||||
|
||||
// Magic circle
|
||||
magicCircleRotation = 0;
|
||||
|
||||
// Used on performance drawing
|
||||
bulletTexture = LoadRenderTexture(24, 24);
|
||||
|
||||
// Draw circle to bullet texture, then draw bullet using DrawTexture()
|
||||
// NOTE: This is done to improve the performance, since DrawCircle() is very slow
|
||||
BeginTextureMode(bulletTexture);
|
||||
DrawCircle(12, 12, (float)bulletRadius, Color.White);
|
||||
DrawCircleLines(12, 12, (float)bulletRadius, Color.Black);
|
||||
EndTextureMode();
|
||||
|
||||
drawInPerformanceMode = true;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Reset the bullet index
|
||||
// New bullets will replace the old ones that are already disabled due to out-of-screen
|
||||
if (bulletCount >= MAX_BULLETS)
|
||||
{
|
||||
bulletCount = 0;
|
||||
bulletDisabledCount = 0;
|
||||
}
|
||||
|
||||
spawnCooldownTimer--;
|
||||
if (spawnCooldownTimer < 0)
|
||||
{
|
||||
spawnCooldownTimer = spawnCooldown;
|
||||
|
||||
// Spawn bullets
|
||||
float degreesPerRow = 360.0f/bulletRows;
|
||||
for (int row = 0; row < bulletRows; row++)
|
||||
{
|
||||
if (bulletCount < MAX_BULLETS)
|
||||
{
|
||||
bullets[bulletCount].position = new Vector2((float)screenWidth/2, (float)screenHeight/2);
|
||||
bullets[bulletCount].disabled = false;
|
||||
bullets[bulletCount].color = bulletColor[row%2];
|
||||
|
||||
float bulletDirection = baseDirection + (degreesPerRow*row);
|
||||
|
||||
// Bullet speed*bullet direction, this will determine how much pixels will be incremented/decremented
|
||||
// from the bullet position every frame. Since the bullets doesn't change its direction and speed,
|
||||
// only need to calculate it at the spawning time
|
||||
// 0 degrees = right, 90 degrees = down, 180 degrees = left and 270 degrees = up, basically clockwise
|
||||
// Case you want it to be anti-clockwise, add "* -1" at the y acceleration
|
||||
bullets[bulletCount].acceleration = new Vector2(
|
||||
bulletSpeed*MathF.Cos(bulletDirection*DEG2RAD),
|
||||
bulletSpeed*MathF.Sin(bulletDirection*DEG2RAD)
|
||||
);
|
||||
|
||||
bulletCount++;
|
||||
}
|
||||
}
|
||||
|
||||
baseDirection += angleIncrement;
|
||||
}
|
||||
|
||||
// Update bullets position based on its acceleration
|
||||
for (int i = 0; i < bulletCount; i++)
|
||||
{
|
||||
// Only update bullet if inside the screen
|
||||
if (!bullets[i].disabled)
|
||||
{
|
||||
bullets[i].position.X += bullets[i].acceleration.X;
|
||||
bullets[i].position.Y += bullets[i].acceleration.Y;
|
||||
|
||||
// Disable bullet if out of screen
|
||||
if ((bullets[i].position.X < -bulletRadius*2) ||
|
||||
(bullets[i].position.X > screenWidth + bulletRadius*2) ||
|
||||
(bullets[i].position.Y < -bulletRadius*2) ||
|
||||
(bullets[i].position.Y > screenHeight + bulletRadius*2))
|
||||
{
|
||||
bullets[i].disabled = true;
|
||||
bulletDisabledCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Input logic
|
||||
if ((IsKeyPressed(KeyboardKey.Right) || IsKeyPressed(KeyboardKey.D)) && (bulletRows < 359)) bulletRows++;
|
||||
if ((IsKeyPressed(KeyboardKey.Left) || IsKeyPressed(KeyboardKey.A)) && (bulletRows > 1)) bulletRows--;
|
||||
if (IsKeyPressed(KeyboardKey.Up) || IsKeyPressed(KeyboardKey.W)) bulletSpeed += 0.25f;
|
||||
if ((IsKeyPressed(KeyboardKey.Down) || IsKeyPressed(KeyboardKey.S)) && (bulletSpeed > 0.50f)) bulletSpeed -= 0.25f;
|
||||
if (IsKeyPressed(KeyboardKey.Z) && (spawnCooldown > 1)) spawnCooldown--;
|
||||
if (IsKeyPressed(KeyboardKey.X)) spawnCooldown++;
|
||||
if (IsKeyPressed(KeyboardKey.Enter)) drawInPerformanceMode = !drawInPerformanceMode;
|
||||
|
||||
if (IsKeyDown(KeyboardKey.Space))
|
||||
{
|
||||
angleIncrement += 1;
|
||||
angleIncrement %= 360;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.C))
|
||||
{
|
||||
bulletCount = 0;
|
||||
bulletDisabledCount = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw magic circle
|
||||
magicCircleRotation++;
|
||||
DrawRectanglePro(new Rectangle((float)screenWidth/2, (float)screenHeight/2, 120, 120),
|
||||
new Vector2(60.0f, 60.0f), magicCircleRotation, Color.Purple);
|
||||
DrawRectanglePro(new Rectangle((float)screenWidth/2, (float)screenHeight/2, 120, 120),
|
||||
new Vector2(60.0f, 60.0f), magicCircleRotation + 45, Color.Purple);
|
||||
DrawCircleLines(screenWidth/2, screenHeight/2, 70, Color.Black);
|
||||
DrawCircleLines(screenWidth/2, screenHeight/2, 50, Color.Black);
|
||||
DrawCircleLines(screenWidth/2, screenHeight/2, 30, Color.Black);
|
||||
|
||||
// Draw bullets
|
||||
if (drawInPerformanceMode)
|
||||
{
|
||||
// Draw bullets using pre-rendered texture containing circle
|
||||
for (int i = 0; i < bulletCount; i++)
|
||||
{
|
||||
// Do not draw disabled bullets (out of screen)
|
||||
if (!bullets[i].disabled)
|
||||
{
|
||||
DrawTexture(bulletTexture.Texture,
|
||||
(int)(bullets[i].position.X - bulletTexture.Texture.Width*0.5f),
|
||||
(int)(bullets[i].position.Y - bulletTexture.Texture.Height*0.5f),
|
||||
bullets[i].color);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw bullets using DrawCircle(), less performant
|
||||
for (int i = 0; i < bulletCount; i++)
|
||||
{
|
||||
// Do not draw disabled bullets (out of screen)
|
||||
if (!bullets[i].disabled)
|
||||
{
|
||||
DrawCircleV(bullets[i].position, (float)bulletRadius, bullets[i].color);
|
||||
DrawCircleLinesV(bullets[i].position, (float)bulletRadius, Color.Black);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw UI
|
||||
DrawRectangle(10, 10, 280, 150, new Color(0, 0, 0, 200));
|
||||
DrawText("Controls:", 20, 20, 10, Color.LightGray);
|
||||
DrawText("- Right/Left or A/D: Change rows number", 40, 40, 10, Color.LightGray);
|
||||
DrawText("- Up/Down or W/S: Change bullet speed", 40, 60, 10, Color.LightGray);
|
||||
DrawText("- Z or X: Change spawn cooldown", 40, 80, 10, Color.LightGray);
|
||||
DrawText("- Space (Hold): Change the angle increment", 40, 100, 10, Color.LightGray);
|
||||
DrawText("- Enter: Switch draw method (Performance)", 40, 120, 10, Color.LightGray);
|
||||
DrawText("- C: Clear bullets", 40, 140, 10, Color.LightGray);
|
||||
|
||||
DrawRectangle(610, 10, 170, 30, new Color(0, 0, 0, 200));
|
||||
if (drawInPerformanceMode) DrawText("Draw method: DrawTexture(*)", 620, 20, 10, Color.Green);
|
||||
else DrawText("Draw method: DrawCircle(*)", 620, 20, 10, Color.Red);
|
||||
|
||||
DrawRectangle(135, 410, 530, 30, new Color(0, 0, 0, 200));
|
||||
DrawText($"[ FPS: {GetFPS()}, Bullets: {bulletCount - bulletDisabledCount}, Rows: {bulletRows}, Bullet speed: {bulletSpeed:F2}, Angle increment per frame: {angleIncrement}, Cooldown: {spawnCooldown:F0} ]",
|
||||
155, 420, 10, Color.Green);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadRenderTexture(bulletTexture); // Unload bullet texture
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - bullet hell");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new BulletHell();
|
||||
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;
|
||||
}
|
||||
}
|
||||
240
Examples/Shapes/ClockOfClocks.cs
Normal file
240
Examples/Shapes/ClockOfClocks.cs
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - clock of clocks
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by JP Mortiboys (@themushroompirates) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* 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) 2025 JP Mortiboys (@themushroompirates)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
using static Raylib_cs.Raymath; // Required for: Lerp(), Clamp()
|
||||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public partial class ClockOfClocks : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Clock of Clocks";
|
||||
|
||||
public string Title => "raylib [shapes] example - clock of clocks";
|
||||
|
||||
public ConfigFlags ConfigFlags => ConfigFlags.Msaa4xHint;
|
||||
|
||||
private Color bgColor;
|
||||
private Color handsColor;
|
||||
|
||||
private const float clockFaceSize = 24;
|
||||
private const float clockFaceSpacing = 8.0f;
|
||||
private const float sectionSpacing = 16.0f;
|
||||
|
||||
private static readonly Vector2 TL = new(0.0f, 90.0f); // Top-left corner
|
||||
private static readonly Vector2 TR = new(90.0f, 180.0f); // Top-right corner
|
||||
private static readonly Vector2 BR = new(180.0f, 270.0f); // Bottom-right corner
|
||||
private static readonly Vector2 BL = new(0.0f, 270.0f); // Bottom-left corner
|
||||
private static readonly Vector2 HH = new(0.0f, 180.0f); // Horizontal line
|
||||
private static readonly Vector2 VV = new(90.0f, 270.0f); // Vertical line
|
||||
private static readonly Vector2 ZZ = new(135.0f, 135.0f); // Not relevant
|
||||
|
||||
private Vector2[,] digitAngles;
|
||||
|
||||
// Time for the hands to move to the new position (in seconds); this must be <1s
|
||||
private const float handsMoveDuration = 0.5f;
|
||||
|
||||
private int prevSeconds;
|
||||
private Vector2[,] currentAngles;
|
||||
private Vector2[,] srcAngles;
|
||||
private Vector2[,] dstAngles;
|
||||
|
||||
private float handsMoveTimer;
|
||||
private int hourMode;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
bgColor = ColorLerp(Color.DarkBlue, Color.Black, 0.75f);
|
||||
handsColor = ColorLerp(Color.Yellow, Color.RayWhite, .25f);
|
||||
|
||||
digitAngles = new Vector2[10, 24]
|
||||
{
|
||||
/* 0 */ { TL, HH, HH, TR, /* */ VV, TL, TR, VV, /* */ VV, VV, VV, VV, /* */ VV, VV, VV, VV, /* */ VV, BL, BR, VV, /* */ BL, HH, HH, BR },
|
||||
/* 1 */ { TL, HH, TR, ZZ, /* */ BL, TR, VV, ZZ, /* */ ZZ, VV, VV, ZZ, /* */ ZZ, VV, VV, ZZ, /* */ TL, BR, BL, TR, /* */ BL, HH, HH, BR },
|
||||
/* 2 */ { TL, HH, HH, TR, /* */ BL, HH, TR, VV, /* */ TL, HH, BR, VV, /* */ VV, TL, HH, BR, /* */ VV, BL, HH, TR, /* */ BL, HH, HH, BR },
|
||||
/* 3 */ { TL, HH, HH, TR, /* */ BL, HH, TR, VV, /* */ TL, HH, BR, VV, /* */ BL, HH, TR, VV, /* */ TL, HH, BR, VV, /* */ BL, HH, HH, BR },
|
||||
/* 4 */ { TL, TR, TL, TR, /* */ VV, VV, VV, VV, /* */ VV, BL, BR, VV, /* */ BL, HH, TR, VV, /* */ ZZ, ZZ, VV, VV, /* */ ZZ, ZZ, BL, BR },
|
||||
/* 5 */ { TL, HH, HH, TR, /* */ VV, TL, HH, BR, /* */ VV, BL, HH, TR, /* */ BL, HH, TR, VV, /* */ TL, HH, BR, VV, /* */ BL, HH, HH, BR },
|
||||
/* 6 */ { TL, HH, HH, TR, /* */ VV, TL, HH, BR, /* */ VV, BL, HH, TR, /* */ VV, TL, TR, VV, /* */ VV, BL, BR, VV, /* */ BL, HH, HH, BR },
|
||||
/* 7 */ { TL, HH, HH, TR, /* */ BL, HH, TR, VV, /* */ ZZ, ZZ, VV, VV, /* */ ZZ, ZZ, VV, VV, /* */ ZZ, ZZ, VV, VV, /* */ ZZ, ZZ, BL, BR },
|
||||
/* 8 */ { TL, HH, HH, TR, /* */ VV, TL, TR, VV, /* */ VV, BL, BR, VV, /* */ VV, TL, TR, VV, /* */ VV, BL, BR, VV, /* */ BL, HH, HH, BR },
|
||||
/* 9 */ { TL, HH, HH, TR, /* */ VV, TL, TR, VV, /* */ VV, BL, BR, VV, /* */ BL, HH, TR, VV, /* */ TL, HH, BR, VV, /* */ BL, HH, HH, BR },
|
||||
};
|
||||
|
||||
prevSeconds = -1;
|
||||
currentAngles = new Vector2[6, 24];
|
||||
srcAngles = new Vector2[6, 24];
|
||||
dstAngles = new Vector2[6, 24];
|
||||
|
||||
handsMoveTimer = 0.0f;
|
||||
hourMode = 24;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Get the current time
|
||||
DateTime timeinfo = DateTime.Now;
|
||||
|
||||
if (timeinfo.Second != prevSeconds)
|
||||
{
|
||||
// The time has changed, so we need to move the hands to the new positions
|
||||
prevSeconds = timeinfo.Second;
|
||||
|
||||
// Format the current time so we can access the individual digits
|
||||
string clockDigits = $"{timeinfo.Hour % hourMode:D2}{timeinfo.Minute:D2}{timeinfo.Second:D2}";
|
||||
|
||||
// Fetch where we want all the hands to be
|
||||
for (int digit = 0; digit < 6; digit++)
|
||||
{
|
||||
for (int cell = 0; cell < 24; cell++)
|
||||
{
|
||||
srcAngles[digit, cell] = currentAngles[digit, cell];
|
||||
dstAngles[digit, cell] = digitAngles[clockDigits[digit] - '0', cell];
|
||||
|
||||
// Quick exception for 12h mode
|
||||
if ((digit == 0) && (hourMode == 12) && (clockDigits[0] == '0')) dstAngles[digit, cell] = ZZ;
|
||||
if (srcAngles[digit, cell].X > dstAngles[digit, cell].X) srcAngles[digit, cell].X -= 360.0f;
|
||||
if (srcAngles[digit, cell].Y > dstAngles[digit, cell].Y) srcAngles[digit, cell].Y -= 360.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the timer
|
||||
handsMoveTimer = -GetFrameTime();
|
||||
}
|
||||
|
||||
// Now let's animate all the hands if we need to
|
||||
if (handsMoveTimer < handsMoveDuration)
|
||||
{
|
||||
// Increase the timer but don't go above the maximum
|
||||
handsMoveTimer = Clamp(handsMoveTimer + GetFrameTime(), 0, handsMoveDuration);
|
||||
|
||||
// Calculate the % completion of the animation
|
||||
float t = handsMoveTimer / handsMoveDuration;
|
||||
|
||||
// A little cheeky smoothstep
|
||||
t = t * t * (3.0f - 2.0f * t);
|
||||
|
||||
for (int digit = 0; digit < 6; digit++)
|
||||
{
|
||||
for (int cell = 0; cell < 24; cell++)
|
||||
{
|
||||
currentAngles[digit, cell].X = Lerp(srcAngles[digit, cell].X, dstAngles[digit, cell].X, t);
|
||||
currentAngles[digit, cell].Y = Lerp(srcAngles[digit, cell].Y, dstAngles[digit, cell].Y, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle input
|
||||
if (IsKeyPressed(KeyboardKey.Space)) hourMode = 36 - hourMode; // Toggle between 12 and 24 hour mode with space
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(bgColor);
|
||||
|
||||
DrawText($"{hourMode}-h mode, space to change", 10, 30, 20, Color.RayWhite);
|
||||
|
||||
float xOffset = 4.0f;
|
||||
|
||||
for (int digit = 0; digit < 6; digit++)
|
||||
{
|
||||
for (int row = 0; row < 6; row++)
|
||||
{
|
||||
for (int col = 0; col < 4; col++)
|
||||
{
|
||||
Vector2 centre = new(
|
||||
xOffset + col * (clockFaceSize + clockFaceSpacing) + clockFaceSize * 0.5f,
|
||||
100 + row * (clockFaceSize + clockFaceSpacing) + clockFaceSize * 0.5f
|
||||
);
|
||||
|
||||
DrawRing(centre, clockFaceSize * 0.5f - 2.0f, clockFaceSize * 0.5f, 0, 360, 24, Color.DarkGray);
|
||||
|
||||
// Big hand
|
||||
DrawRectanglePro(
|
||||
new Rectangle(centre.X, centre.Y, clockFaceSize * 0.5f + 4.0f, 4.0f),
|
||||
new Vector2(2.0f, 2.0f),
|
||||
currentAngles[digit, row * 4 + col].X,
|
||||
handsColor
|
||||
);
|
||||
|
||||
// Little hand
|
||||
DrawRectanglePro(
|
||||
new Rectangle(centre.X, centre.Y, clockFaceSize * 0.5f + 2.0f, 4.0f),
|
||||
new Vector2(2.0f, 2.0f),
|
||||
currentAngles[digit, row * 4 + col].Y,
|
||||
handsColor
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
xOffset += (clockFaceSize + clockFaceSpacing) * 4;
|
||||
if (digit % 2 == 1)
|
||||
{
|
||||
DrawRing(new Vector2(xOffset + 4.0f, 160.0f), 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor);
|
||||
DrawRing(new Vector2(xOffset + 4.0f, 225.0f), 6.0f, 8.0f, 0.0f, 360.0f, 24, handsColor);
|
||||
xOffset += sectionSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
SetConfigFlags(ConfigFlags.Msaa4xHint);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - clock of clocks");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ClockOfClocks();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,14 @@
|
|||
*
|
||||
* raylib [shapes] example - collision area
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.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) 2013-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -13,124 +17,156 @@ using static Raylib_cs.Raylib;
|
|||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public class CollisionArea
|
||||
public partial class CollisionArea : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Collision Area";
|
||||
|
||||
public string Title => "raylib [shapes] example - collision area";
|
||||
|
||||
private Rectangle boxA;
|
||||
private int boxASpeedX;
|
||||
private Rectangle boxB;
|
||||
private Rectangle boxCollision;
|
||||
private int screenUpperLimit;
|
||||
private bool pause;
|
||||
private bool collision;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Box A: Moving box
|
||||
boxA = new(10, GetScreenHeight() / 2.0f - 50, 200, 100);
|
||||
boxASpeedX = 4;
|
||||
|
||||
// Box B: Mouse moved box
|
||||
boxB = new(GetScreenWidth() / 2.0f - 30, GetScreenHeight() / 2.0f - 30, 60, 60);
|
||||
|
||||
boxCollision = new(); // Collision rectangle
|
||||
|
||||
screenUpperLimit = 40; // Top menu limits
|
||||
|
||||
pause = false; // Movement pause
|
||||
collision = false; // Collision detection
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//-----------------------------------------------------
|
||||
// Move box if not paused
|
||||
if (!pause)
|
||||
{
|
||||
boxA.X += boxASpeedX;
|
||||
}
|
||||
|
||||
// Bounce box on x screen limits
|
||||
if (((boxA.X + boxA.Width) >= GetScreenWidth()) || (boxA.X <= 0))
|
||||
{
|
||||
boxASpeedX *= -1;
|
||||
}
|
||||
|
||||
// Update player-controlled-box (box02)
|
||||
boxB.X = GetMouseX() - boxB.Width / 2;
|
||||
boxB.Y = GetMouseY() - boxB.Height / 2;
|
||||
|
||||
// Make sure Box B does not go out of move area limits
|
||||
if ((boxB.X + boxB.Width) >= GetScreenWidth())
|
||||
{
|
||||
boxB.X = GetScreenWidth() - boxB.Width;
|
||||
}
|
||||
else if (boxB.X <= 0)
|
||||
{
|
||||
boxB.X = 0;
|
||||
}
|
||||
|
||||
if ((boxB.Y + boxB.Height) >= GetScreenHeight())
|
||||
{
|
||||
boxB.Y = GetScreenHeight() - boxB.Height;
|
||||
}
|
||||
else if (boxB.Y <= screenUpperLimit)
|
||||
{
|
||||
boxB.Y = screenUpperLimit;
|
||||
}
|
||||
|
||||
// Check boxes collision
|
||||
collision = CheckCollisionRecs(boxA, boxB);
|
||||
|
||||
// Get collision rectangle (only on collision)
|
||||
if (collision)
|
||||
{
|
||||
boxCollision = GetCollisionRec(boxA, boxB);
|
||||
}
|
||||
|
||||
// Pause Box A movement
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
pause = !pause;
|
||||
}
|
||||
//-----------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//-----------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawRectangle(0, 0, screenWidth, screenUpperLimit, collision ? Color.Red : Color.Black);
|
||||
|
||||
DrawRectangleRec(boxA, Color.Gold);
|
||||
DrawRectangleRec(boxB, Color.Blue);
|
||||
|
||||
if (collision)
|
||||
{
|
||||
// Draw collision area
|
||||
DrawRectangleRec(boxCollision, Color.Lime);
|
||||
|
||||
// Draw collision message
|
||||
var cx = GetScreenWidth() / 2 - MeasureText("COLLISION!", 20) / 2;
|
||||
var cy = screenUpperLimit / 2 - 10;
|
||||
DrawText("COLLISION!", cx, cy, 20, Color.Black);
|
||||
|
||||
// Draw collision area
|
||||
var text = $"Collision Area: {(int)boxCollision.Width * (int)boxCollision.Height}";
|
||||
DrawText(text, GetScreenWidth() / 2 - 100, screenUpperLimit + 10, 20, Color.Black);
|
||||
}
|
||||
|
||||
// Draw help instructions
|
||||
DrawText("Press SPACE to PAUSE/RESUME", 20, screenHeight - 35, 20, Color.LightGray);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//-----------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//---------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - collision area");
|
||||
|
||||
// Box A: Moving box
|
||||
Rectangle boxA = new(10, GetScreenHeight() / 2 - 50, 200, 100);
|
||||
int boxASpeedX = 4;
|
||||
|
||||
// Box B: Mouse moved box
|
||||
Rectangle boxB = new(GetScreenWidth() / 2 - 30, GetScreenHeight() / 2 - 30, 60, 60);
|
||||
Rectangle boxCollision = new();
|
||||
|
||||
int screenUpperLimit = 40;
|
||||
|
||||
// Movement pause
|
||||
bool pause = false;
|
||||
bool collision = false;
|
||||
|
||||
SetTargetFPS(60);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//----------------------------------------------------------
|
||||
|
||||
var game = new CollisionArea();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//-----------------------------------------------------
|
||||
// Move box if not paused
|
||||
if (!pause)
|
||||
{
|
||||
boxA.X += boxASpeedX;
|
||||
}
|
||||
|
||||
// Bounce box on x screen limits
|
||||
if (((boxA.X + boxA.Width) >= GetScreenWidth()) || (boxA.X <= 0))
|
||||
{
|
||||
boxASpeedX *= -1;
|
||||
}
|
||||
|
||||
// Update player-controlled-box (box02)
|
||||
boxB.X = GetMouseX() - boxB.Width / 2;
|
||||
boxB.Y = GetMouseY() - boxB.Height / 2;
|
||||
|
||||
// Make sure Box B does not go out of move area limits
|
||||
if ((boxB.X + boxB.Width) >= GetScreenWidth())
|
||||
{
|
||||
boxB.X = GetScreenWidth() - boxB.Width;
|
||||
}
|
||||
else if (boxB.X <= 0)
|
||||
{
|
||||
boxB.X = 0;
|
||||
}
|
||||
|
||||
if ((boxB.Y + boxB.Height) >= GetScreenHeight())
|
||||
{
|
||||
boxB.Y = GetScreenHeight() - boxB.Height;
|
||||
}
|
||||
else if (boxB.Y <= screenUpperLimit)
|
||||
{
|
||||
boxB.Y = screenUpperLimit;
|
||||
}
|
||||
|
||||
// Check boxes collision
|
||||
collision = CheckCollisionRecs(boxA, boxB);
|
||||
|
||||
// Get collision rectangle (only on collision)
|
||||
if (collision)
|
||||
{
|
||||
boxCollision = GetCollisionRec(boxA, boxB);
|
||||
}
|
||||
|
||||
// Pause Box A movement
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
pause = !pause;
|
||||
}
|
||||
//-----------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//-----------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawRectangle(0, 0, screenWidth, screenUpperLimit, collision ? Color.Red : Color.Black);
|
||||
|
||||
DrawRectangleRec(boxA, Color.Gold);
|
||||
DrawRectangleRec(boxB, Color.Blue);
|
||||
|
||||
if (collision)
|
||||
{
|
||||
// Draw collision area
|
||||
DrawRectangleRec(boxCollision, Color.Lime);
|
||||
|
||||
// Draw collision message
|
||||
int cx = GetScreenWidth() / 2 - MeasureText("COLLISION!", 20) / 2;
|
||||
int cy = screenUpperLimit / 2 - 10;
|
||||
DrawText("COLLISION!", cx, cy, 20, Color.Black);
|
||||
|
||||
// Draw collision area
|
||||
string text = $"Collision Area: {(int)boxCollision.Width * (int)boxCollision.Height}";
|
||||
DrawText(text, GetScreenWidth() / 2 - 100, screenUpperLimit + 10, 20, Color.Black);
|
||||
}
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//-----------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//---------------------------------------------------------
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//----------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - Colors palette
|
||||
* raylib [shapes] example - colors palette
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 1.0, last time updated with raylib 2.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) 2014-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -14,72 +18,80 @@ using static Raylib_cs.Raylib;
|
|||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public class ColorsPalette
|
||||
public partial class ColorsPalette : IExample
|
||||
{
|
||||
public static int Main()
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public const int MaxColorsCount = 21; // Number of colors available
|
||||
|
||||
public string Name => "Shapes / Colors Palette";
|
||||
|
||||
public string Title => "raylib [shapes] example - colors palette";
|
||||
|
||||
private Color[] colors;
|
||||
private string[] colorNames;
|
||||
private Rectangle[] colorsRecs;
|
||||
private int[] colorState;
|
||||
private Vector2 mousePoint;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - colors palette");
|
||||
|
||||
Color[] colors = new[]
|
||||
colors = new[]
|
||||
{
|
||||
Color.DarkGray,
|
||||
Color.Maroon,
|
||||
Color.Orange,
|
||||
Color.DarkGreen,
|
||||
Color.DarkBlue,
|
||||
Color.DarkPurple,
|
||||
Color.DarkBrown,
|
||||
Color.Gray,
|
||||
Color.Red,
|
||||
Color.Gold,
|
||||
Color.Lime,
|
||||
Color.Blue,
|
||||
Color.Violet,
|
||||
Color.Brown,
|
||||
Color.LightGray,
|
||||
Color.Pink,
|
||||
Color.Yellow,
|
||||
Color.Green,
|
||||
Color.SkyBlue,
|
||||
Color.Purple,
|
||||
Color.Beige
|
||||
};
|
||||
Color.DarkGray,
|
||||
Color.Maroon,
|
||||
Color.Orange,
|
||||
Color.DarkGreen,
|
||||
Color.DarkBlue,
|
||||
Color.DarkPurple,
|
||||
Color.DarkBrown,
|
||||
Color.Gray,
|
||||
Color.Red,
|
||||
Color.Gold,
|
||||
Color.Lime,
|
||||
Color.Blue,
|
||||
Color.Violet,
|
||||
Color.Brown,
|
||||
Color.LightGray,
|
||||
Color.Pink,
|
||||
Color.Yellow,
|
||||
Color.Green,
|
||||
Color.SkyBlue,
|
||||
Color.Purple,
|
||||
Color.Beige
|
||||
};
|
||||
|
||||
string[] colorNames = new[]
|
||||
colorNames = new[]
|
||||
{
|
||||
"DARKGRAY",
|
||||
"MAROON",
|
||||
"ORANGE",
|
||||
"DARKGREEN",
|
||||
"DARKBLUE",
|
||||
"DARKPURPLE",
|
||||
"DARKBROWN",
|
||||
"GRAY",
|
||||
"RED",
|
||||
"GOLD",
|
||||
"LIME",
|
||||
"BLUE",
|
||||
"VIOLET",
|
||||
"BROWN",
|
||||
"LIGHTGRAY",
|
||||
"PINK",
|
||||
"YELLOW",
|
||||
"GREEN",
|
||||
"SKYBLUE",
|
||||
"PURPLE",
|
||||
"BEIGE"
|
||||
};
|
||||
"DARKGRAY",
|
||||
"MAROON",
|
||||
"ORANGE",
|
||||
"DARKGREEN",
|
||||
"DARKBLUE",
|
||||
"DARKPURPLE",
|
||||
"DARKBROWN",
|
||||
"GRAY",
|
||||
"RED",
|
||||
"GOLD",
|
||||
"LIME",
|
||||
"BLUE",
|
||||
"VIOLET",
|
||||
"BROWN",
|
||||
"LIGHTGRAY",
|
||||
"PINK",
|
||||
"YELLOW",
|
||||
"GREEN",
|
||||
"SKYBLUE",
|
||||
"PURPLE",
|
||||
"BEIGE"
|
||||
};
|
||||
|
||||
// Rectangles array
|
||||
Rectangle[] colorsRecs = new Rectangle[colors.Length];
|
||||
colorsRecs = new Rectangle[colors.Length];
|
||||
|
||||
// Fills colorsRecs data (for every rectangle)
|
||||
for (int i = 0; i < colorsRecs.Length; i++)
|
||||
for (var i = 0; i < colorsRecs.Length; i++)
|
||||
{
|
||||
colorsRecs[i].X = 20 + 100 * (i % 7) + 10 * (i % 7);
|
||||
colorsRecs[i].Y = 80 + 100 * (i / 7) + 10 * (i / 7);
|
||||
|
|
@ -88,82 +100,101 @@ public class ColorsPalette
|
|||
}
|
||||
|
||||
// Color state: 0-DEFAULT, 1-MOUSE_HOVER
|
||||
int[] colorState = new int[colors.Length];
|
||||
colorState = new int[colors.Length];
|
||||
|
||||
Vector2 mousePoint = new(0.0f, 0.0f);
|
||||
mousePoint = new(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
SetTargetFPS(60);
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
mousePoint = GetMousePosition();
|
||||
|
||||
for (var i = 0; i < colors.Length; i++)
|
||||
{
|
||||
if (CheckCollisionPointRec(mousePoint, colorsRecs[i]))
|
||||
{
|
||||
colorState[i] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
colorState[i] = 0;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawText("raylib colors palette", 28, 42, 20, Color.Black);
|
||||
DrawText(
|
||||
"press SPACE to see all colors",
|
||||
GetScreenWidth() - 180,
|
||||
GetScreenHeight() - 40,
|
||||
10,
|
||||
Color.Gray
|
||||
);
|
||||
|
||||
for (var i = 0; i < colorsRecs.Length; i++) // Draw all rectangles
|
||||
{
|
||||
DrawRectangleRec(colorsRecs[i], Fade(colors[i], colorState[i] != 0 ? 0.6f : 1.0f));
|
||||
|
||||
if (IsKeyDown(KeyboardKey.Space) || colorState[i] != 0)
|
||||
{
|
||||
DrawRectangle(
|
||||
(int)colorsRecs[i].X,
|
||||
(int)(colorsRecs[i].Y + colorsRecs[i].Height - 26),
|
||||
(int)colorsRecs[i].Width,
|
||||
20,
|
||||
Color.Black
|
||||
);
|
||||
DrawRectangleLinesEx(colorsRecs[i], 6, Fade(Color.Black, 0.3f));
|
||||
DrawText(
|
||||
colorNames[i],
|
||||
(int)(colorsRecs[i].X + colorsRecs[i].Width - MeasureText(colorNames[i], 10) - 12),
|
||||
(int)(colorsRecs[i].Y + colorsRecs[i].Height - 20),
|
||||
10,
|
||||
colors[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - colors palette");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new ColorsPalette();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
mousePoint = GetMousePosition();
|
||||
|
||||
for (int i = 0; i < colors.Length; i++)
|
||||
{
|
||||
if (CheckCollisionPointRec(mousePoint, colorsRecs[i]))
|
||||
{
|
||||
colorState[i] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
colorState[i] = 0;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawText("raylib colors palette", 28, 42, 20, Color.Black);
|
||||
DrawText(
|
||||
"press SPACE to see all colors",
|
||||
GetScreenWidth() - 180,
|
||||
GetScreenHeight() - 40,
|
||||
10,
|
||||
Color.Gray
|
||||
);
|
||||
|
||||
// Draw all rectangles
|
||||
for (int i = 0; i < colorsRecs.Length; i++)
|
||||
{
|
||||
DrawRectangleRec(colorsRecs[i], ColorAlpha(colors[i], colorState[i] != 0 ? 0.6f : 1.0f));
|
||||
|
||||
if (IsKeyDown(KeyboardKey.Space) || colorState[i] != 0)
|
||||
{
|
||||
DrawRectangle(
|
||||
(int)colorsRecs[i].X,
|
||||
(int)(colorsRecs[i].Y + colorsRecs[i].Height - 26),
|
||||
(int)colorsRecs[i].Width,
|
||||
20,
|
||||
Color.Black
|
||||
);
|
||||
DrawRectangleLinesEx(colorsRecs[i], 6, ColorAlpha(Color.Black, 0.3f));
|
||||
DrawText(
|
||||
colorNames[i],
|
||||
(int)(colorsRecs[i].X + colorsRecs[i].Width - MeasureText(colorNames[i], 10) - 12),
|
||||
(int)(colorsRecs[i].Y + colorsRecs[i].Height - 20),
|
||||
10,
|
||||
colors[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
130
Examples/Shapes/DashedLine.cs
Normal file
130
Examples/Shapes/DashedLine.cs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - dashed line
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||
*
|
||||
* Example contributed by Luís Almeida (@luis605)
|
||||
*
|
||||
* 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) 2025 Luís Almeida (@luis605)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public partial class DashedLine : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Dashed Line";
|
||||
|
||||
public string Title => "raylib [shapes] example - dashed line";
|
||||
|
||||
// Line Properties
|
||||
private Vector2 lineStartPosition;
|
||||
private Vector2 lineEndPosition;
|
||||
private float dashLength;
|
||||
private float blankLength;
|
||||
|
||||
// Color selection
|
||||
private Color[] lineColors;
|
||||
private int colorIndex;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Line Properties
|
||||
lineStartPosition = new Vector2(20.0f, 50.0f);
|
||||
lineEndPosition = new Vector2(780.0f, 400.0f);
|
||||
dashLength = 25.0f;
|
||||
blankLength = 15.0f;
|
||||
|
||||
// Color selection
|
||||
lineColors = new[] { Color.Red, Color.Orange, Color.Gold, Color.Green, Color.Blue, Color.Violet, Color.Pink, Color.Black };
|
||||
colorIndex = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
lineEndPosition = GetMousePosition(); // Line endpoint follows the mouse
|
||||
|
||||
// Change Dash Length (UP/DOWN arrows)
|
||||
if (IsKeyDown(KeyboardKey.Up)) dashLength += 1.0f;
|
||||
if (IsKeyDown(KeyboardKey.Down) && dashLength > 1.0f) dashLength -= 1.0f;
|
||||
|
||||
// Change Space Length (LEFT/RIGHT arrows)
|
||||
if (IsKeyDown(KeyboardKey.Right)) blankLength += 1.0f;
|
||||
if (IsKeyDown(KeyboardKey.Left) && blankLength > 1.0f) blankLength -= 1.0f;
|
||||
|
||||
// Cycle through colors ('C' key)
|
||||
if (IsKeyPressed(KeyboardKey.C)) colorIndex = (colorIndex + 1)%lineColors.Length;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw the dashed line with the current properties
|
||||
DrawLineDashed(lineStartPosition, lineEndPosition, (int)dashLength, (int)blankLength, lineColors[colorIndex]);
|
||||
|
||||
// Draw UI and Instructions
|
||||
DrawRectangle(5, 5, 265, 95, Fade(Color.SkyBlue, 0.5f));
|
||||
DrawRectangleLines(5, 5, 265, 95, Color.Blue);
|
||||
|
||||
DrawText("CONTROLS:", 15, 15, 10, Color.Black);
|
||||
DrawText("UP/DOWN: Change Dash Length", 15, 35, 10, Color.Black);
|
||||
DrawText("LEFT/RIGHT: Change Space Length", 15, 55, 10, Color.Black);
|
||||
DrawText("C: Cycle Color", 15, 75, 10, Color.Black);
|
||||
|
||||
DrawText($"Dash: {dashLength:F0} | Space: {blankLength:F0}", 15, 115, 10, Color.DarkGray);
|
||||
|
||||
DrawFPS(screenWidth - 80, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - dashed line");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new DashedLine();
|
||||
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;
|
||||
}
|
||||
}
|
||||
327
Examples/Shapes/DigitalClock.cs
Normal file
327
Examples/Shapes/DigitalClock.cs
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - digital clock
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.6
|
||||
*
|
||||
* Example contributed by Hamza RAHAL (@hmz-rhl) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* 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) 2025 Hamza RAHAL (@hmz-rhl) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public partial class DigitalClock : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
private const int CLOCK_ANALOG = 0;
|
||||
private const int CLOCK_DIGITAL = 1;
|
||||
|
||||
public string Name => "Shapes / Digital Clock";
|
||||
|
||||
public string Title => "raylib [shapes] example - digital clock";
|
||||
|
||||
public ConfigFlags ConfigFlags => ConfigFlags.Msaa4xHint;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Clock hand type
|
||||
private struct ClockHand
|
||||
{
|
||||
public int value; // Time value
|
||||
|
||||
// Visual elements
|
||||
public float angle; // Hand angle
|
||||
public int length; // Hand length
|
||||
public int thickness; // Hand thickness
|
||||
public Color color; // Hand color
|
||||
}
|
||||
|
||||
// Clock hands
|
||||
private struct Clock
|
||||
{
|
||||
public ClockHand second; // Clock hand for seconds
|
||||
public ClockHand minute; // Clock hand for minutes
|
||||
public ClockHand hour; // Clock hand for hours
|
||||
}
|
||||
|
||||
private int clockMode;
|
||||
private Clock clock;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
clockMode = CLOCK_DIGITAL;
|
||||
|
||||
// Initialize clock
|
||||
// NOTE: Includes visual info for analog clock
|
||||
clock = new Clock();
|
||||
|
||||
clock.second.angle = 45;
|
||||
clock.second.length = 140;
|
||||
clock.second.thickness = 3;
|
||||
clock.second.color = Color.Maroon;
|
||||
|
||||
clock.minute.angle = 10;
|
||||
clock.minute.length = 130;
|
||||
clock.minute.thickness = 7;
|
||||
clock.minute.color = Color.DarkGray;
|
||||
|
||||
clock.hour.angle = 0;
|
||||
clock.hour.length = 100;
|
||||
clock.hour.thickness = 7;
|
||||
clock.hour.color = Color.Black;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
// Toggle clock mode
|
||||
if (clockMode == CLOCK_DIGITAL) clockMode = CLOCK_ANALOG;
|
||||
else if (clockMode == CLOCK_ANALOG) clockMode = CLOCK_DIGITAL;
|
||||
}
|
||||
|
||||
UpdateClock(); // Update clock required data: value and angle
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw clock in selected mode
|
||||
if (clockMode == CLOCK_ANALOG) DrawClockAnalog(clock, new Vector2(400, 240));
|
||||
else if (clockMode == CLOCK_DIGITAL)
|
||||
{
|
||||
DrawClockDigital(clock, new Vector2(30, 60));
|
||||
|
||||
// Draw clock using default raylib font
|
||||
string clockTime = $"{clock.hour.value:D2}:{clock.minute.value:D2}:{clock.second.value:D2}";
|
||||
DrawText(clockTime, GetScreenWidth() / 2 - MeasureText(clockTime, 150) / 2, 300, 150, Color.Black);
|
||||
}
|
||||
|
||||
DrawText($"Press [SPACE] to switch clock mode: {((clockMode == CLOCK_DIGITAL) ? "DIGITAL CLOCK" : "ANALOGUE CLOCK")}",
|
||||
10, 10, 20, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Update clock time
|
||||
private void UpdateClock()
|
||||
{
|
||||
DateTime timeinfo = DateTime.Now;
|
||||
|
||||
// Updating time data
|
||||
clock.second.value = timeinfo.Second;
|
||||
clock.minute.value = timeinfo.Minute;
|
||||
clock.hour.value = timeinfo.Hour;
|
||||
|
||||
clock.hour.angle = (timeinfo.Hour % 12) * 180.0f / 6.0f;
|
||||
clock.hour.angle += (timeinfo.Minute % 60) * 30 / 60.0f;
|
||||
clock.hour.angle -= 90;
|
||||
|
||||
clock.minute.angle = (timeinfo.Minute % 60) * 6.0f;
|
||||
clock.minute.angle += (timeinfo.Second % 60) * 6 / 60.0f;
|
||||
clock.minute.angle -= 90;
|
||||
|
||||
clock.second.angle = (timeinfo.Second % 60) * 6.0f;
|
||||
clock.second.angle -= 90;
|
||||
}
|
||||
|
||||
// Draw analog clock
|
||||
// Parameter: position, refers to center position
|
||||
private static void DrawClockAnalog(Clock clock, Vector2 position)
|
||||
{
|
||||
// Draw clock base
|
||||
DrawCircleV(position, clock.second.length + 40.0f, Color.LightGray);
|
||||
DrawCircleV(position, 12.0f, Color.Gray);
|
||||
|
||||
// Draw clock minutes/seconds lines
|
||||
for (int i = 0; i < 60; i++)
|
||||
{
|
||||
DrawLineEx(new Vector2(position.X + (clock.second.length + ((i % 5) != 0 ? 10 : 6)) * MathF.Cos((6.0f * i - 90.0f) * DEG2RAD),
|
||||
position.Y + (clock.second.length + ((i % 5) != 0 ? 10 : 6)) * MathF.Sin((6.0f * i - 90.0f) * DEG2RAD)),
|
||||
new Vector2(position.X + (clock.second.length + 20) * MathF.Cos((6.0f * i - 90.0f) * DEG2RAD),
|
||||
position.Y + (clock.second.length + 20) * MathF.Sin((6.0f * i - 90.0f) * DEG2RAD)), ((i % 5) != 0 ? 1.0f : 3.0f), Color.DarkGray);
|
||||
}
|
||||
|
||||
// Draw hand seconds
|
||||
DrawRectanglePro(new Rectangle(position.X, position.Y, (float)clock.second.length, (float)clock.second.thickness),
|
||||
new Vector2(0.0f, clock.second.thickness / 2.0f), clock.second.angle, clock.second.color);
|
||||
|
||||
// Draw hand minutes
|
||||
DrawRectanglePro(new Rectangle(position.X, position.Y, (float)clock.minute.length, (float)clock.minute.thickness),
|
||||
new Vector2(0.0f, clock.minute.thickness / 2.0f), clock.minute.angle, clock.minute.color);
|
||||
|
||||
// Draw hand hours
|
||||
DrawRectanglePro(new Rectangle(position.X, position.Y, (float)clock.hour.length, (float)clock.hour.thickness),
|
||||
new Vector2(0.0f, clock.hour.thickness / 2.0f), clock.hour.angle, clock.hour.color);
|
||||
}
|
||||
|
||||
// Draw digital clock
|
||||
// PARAM: position, refers to top-left corner
|
||||
private static void DrawClockDigital(Clock clock, Vector2 position)
|
||||
{
|
||||
// Draw clock using custom 7-segments display (made of shapes)
|
||||
DrawDisplayValue(new Vector2(position.X, position.Y), clock.hour.value / 10, Color.Red, Fade(Color.LightGray, 0.3f));
|
||||
DrawDisplayValue(new Vector2(position.X + 120, position.Y), clock.hour.value % 10, Color.Red, Fade(Color.LightGray, 0.3f));
|
||||
|
||||
DrawCircle((int)position.X + 240, (int)position.Y + 70, 12, (clock.second.value % 2) != 0 ? Color.Red : Fade(Color.LightGray, 0.3f));
|
||||
DrawCircle((int)position.X + 240, (int)position.Y + 150, 12, (clock.second.value % 2) != 0 ? Color.Red : Fade(Color.LightGray, 0.3f));
|
||||
|
||||
DrawDisplayValue(new Vector2(position.X + 260, position.Y), clock.minute.value / 10, Color.Red, Fade(Color.LightGray, 0.3f));
|
||||
DrawDisplayValue(new Vector2(position.X + 380, position.Y), clock.minute.value % 10, Color.Red, Fade(Color.LightGray, 0.3f));
|
||||
|
||||
DrawCircle((int)position.X + 500, (int)position.Y + 70, 12, (clock.second.value % 2) != 0 ? Color.Red : Fade(Color.LightGray, 0.3f));
|
||||
DrawCircle((int)position.X + 500, (int)position.Y + 150, 12, (clock.second.value % 2) != 0 ? Color.Red : Fade(Color.LightGray, 0.3f));
|
||||
|
||||
DrawDisplayValue(new Vector2(position.X + 520, position.Y), clock.second.value / 10, Color.Red, Fade(Color.LightGray, 0.3f));
|
||||
DrawDisplayValue(new Vector2(position.X + 640, position.Y), clock.second.value % 10, Color.Red, Fade(Color.LightGray, 0.3f));
|
||||
}
|
||||
|
||||
// Draw 7-segment display with value
|
||||
private static void DrawDisplayValue(Vector2 position, int value, Color colorOn, Color colorOff)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case 0: Draw7SDisplay(position, 0b00111111, colorOn, colorOff); break;
|
||||
case 1: Draw7SDisplay(position, 0b00000110, colorOn, colorOff); break;
|
||||
case 2: Draw7SDisplay(position, 0b01011011, colorOn, colorOff); break;
|
||||
case 3: Draw7SDisplay(position, 0b01001111, colorOn, colorOff); break;
|
||||
case 4: Draw7SDisplay(position, 0b01100110, colorOn, colorOff); break;
|
||||
case 5: Draw7SDisplay(position, 0b01101101, colorOn, colorOff); break;
|
||||
case 6: Draw7SDisplay(position, 0b01111101, colorOn, colorOff); break;
|
||||
case 7: Draw7SDisplay(position, 0b00000111, colorOn, colorOff); break;
|
||||
case 8: Draw7SDisplay(position, 0b01111111, colorOn, colorOff); break;
|
||||
case 9: Draw7SDisplay(position, 0b01101111, colorOn, colorOff); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw seven segments display
|
||||
// Parameter: position, refers to top-left corner of display
|
||||
// Parameter: segments, defines in binary the segments to be activated
|
||||
private static void Draw7SDisplay(Vector2 position, int segments, Color colorOn, Color colorOff)
|
||||
{
|
||||
int segmentLen = 60;
|
||||
int segmentThick = 20;
|
||||
float offsetYAdjust = segmentThick * 0.3f; // HACK: Adjust gap space between segment limits
|
||||
|
||||
// Segment A
|
||||
DrawDisplaySegment(new Vector2(position.X + segmentThick + segmentLen / 2.0f, position.Y + segmentThick),
|
||||
segmentLen, segmentThick, false, (segments & 0b00000001) != 0 ? colorOn : colorOff);
|
||||
// Segment B
|
||||
DrawDisplaySegment(new Vector2(position.X + segmentThick + segmentLen + segmentThick / 2.0f, position.Y + 2 * segmentThick + segmentLen / 2.0f - offsetYAdjust),
|
||||
segmentLen, segmentThick, true, (segments & 0b00000010) != 0 ? colorOn : colorOff);
|
||||
// Segment C
|
||||
DrawDisplaySegment(new Vector2(position.X + segmentThick + segmentLen + segmentThick / 2.0f, position.Y + 4 * segmentThick + segmentLen + segmentLen / 2.0f - 3 * offsetYAdjust),
|
||||
segmentLen, segmentThick, true, (segments & 0b00000100) != 0 ? colorOn : colorOff);
|
||||
// Segment D
|
||||
DrawDisplaySegment(new Vector2(position.X + segmentThick + segmentLen / 2.0f, position.Y + 5 * segmentThick + 2 * segmentLen - 4 * offsetYAdjust),
|
||||
segmentLen, segmentThick, false, (segments & 0b00001000) != 0 ? colorOn : colorOff);
|
||||
// Segment E
|
||||
DrawDisplaySegment(new Vector2(position.X + segmentThick / 2.0f, position.Y + 4 * segmentThick + segmentLen + segmentLen / 2.0f - 3 * offsetYAdjust),
|
||||
segmentLen, segmentThick, true, (segments & 0b00010000) != 0 ? colorOn : colorOff);
|
||||
// Segment F
|
||||
DrawDisplaySegment(new Vector2(position.X + segmentThick / 2.0f, position.Y + 2 * segmentThick + segmentLen / 2.0f - offsetYAdjust),
|
||||
segmentLen, segmentThick, true, (segments & 0b00100000) != 0 ? colorOn : colorOff);
|
||||
// Segment G
|
||||
DrawDisplaySegment(new Vector2(position.X + segmentThick + segmentLen / 2.0f, position.Y + 3 * segmentThick + segmentLen - 2 * offsetYAdjust),
|
||||
segmentLen, segmentThick, false, (segments & 0b01000000) != 0 ? colorOn : colorOff);
|
||||
}
|
||||
|
||||
// Draw one 7-segment display segment, horizontal or vertical
|
||||
private static void DrawDisplaySegment(Vector2 center, int length, int thick, bool vertical, Color color)
|
||||
{
|
||||
if (!vertical)
|
||||
{
|
||||
// Horizontal segment points
|
||||
/*
|
||||
3___________________________5
|
||||
/ \
|
||||
/1 x 6\
|
||||
\ /
|
||||
\2___________________________4/
|
||||
*/
|
||||
Vector2[] segmentPointsH = new Vector2[6]
|
||||
{
|
||||
new Vector2(center.X - length / 2.0f - thick / 2.0f, center.Y), // Point 1
|
||||
new Vector2(center.X - length / 2.0f, center.Y + thick / 2.0f), // Point 2
|
||||
new Vector2(center.X - length / 2.0f, center.Y - thick / 2.0f), // Point 3
|
||||
new Vector2(center.X + length / 2.0f, center.Y + thick / 2.0f), // Point 4
|
||||
new Vector2(center.X + length / 2.0f, center.Y - thick / 2.0f), // Point 5
|
||||
new Vector2(center.X + length / 2.0f + thick / 2.0f, center.Y), // Point 6
|
||||
};
|
||||
|
||||
DrawTriangleStrip(segmentPointsH, 6, color);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Vertical segment points
|
||||
Vector2[] segmentPointsV = new Vector2[6]
|
||||
{
|
||||
new Vector2(center.X, center.Y - length / 2.0f - thick / 2.0f), // Point 1
|
||||
new Vector2(center.X - thick / 2.0f, center.Y - length / 2.0f), // Point 2
|
||||
new Vector2(center.X + thick / 2.0f, center.Y - length / 2.0f), // Point 3
|
||||
new Vector2(center.X - thick / 2.0f, center.Y + length / 2.0f), // Point 4
|
||||
new Vector2(center.X + thick / 2.0f, center.Y + length / 2.0f), // Point 5
|
||||
new Vector2(center.X, center.Y + (float)length / 2 + thick / 2.0f), // Point 6
|
||||
};
|
||||
|
||||
DrawTriangleStrip(segmentPointsV, 6, color);
|
||||
}
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
SetConfigFlags(ConfigFlags.Msaa4xHint);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - digital clock");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new DigitalClock();
|
||||
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;
|
||||
}
|
||||
}
|
||||
205
Examples/Shapes/DoublePendulum.cs
Normal file
205
Examples/Shapes/DoublePendulum.cs
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - double pendulum
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||
*
|
||||
* Example contributed by JoeCheong (@Joecheong2006) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* 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) 2025 JoeCheong (@Joecheong2006)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public partial class DoublePendulum : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
// Constant for Simulation
|
||||
private const int SIMULATION_STEPS = 30;
|
||||
private const float G = 9.81f;
|
||||
|
||||
public string Name => "Shapes / Double Pendulum";
|
||||
|
||||
public string Title => "raylib [shapes] example - double pendulum";
|
||||
|
||||
public ConfigFlags ConfigFlags => ConfigFlags.HighDpiWindow;
|
||||
|
||||
// Simulation Parameters
|
||||
private float l1, m1, theta1, w1;
|
||||
private float l2, m2, theta2, w2;
|
||||
private float lengthScaler;
|
||||
private float totalM;
|
||||
|
||||
private Vector2 previousPosition;
|
||||
|
||||
// Scale length
|
||||
private float L1;
|
||||
private float L2;
|
||||
|
||||
// Draw parameters
|
||||
private float lineThick, trailThick;
|
||||
private float fateAlpha;
|
||||
|
||||
// Create framebuffer
|
||||
private RenderTexture2D target;
|
||||
|
||||
// Calculate pendulum end point
|
||||
private static Vector2 CalculatePendulumEndPoint(float l, float theta)
|
||||
{
|
||||
return new(10 * l * MathF.Sin(theta), 10 * l * MathF.Cos(theta));
|
||||
}
|
||||
|
||||
// Calculate double pendulum end point
|
||||
private static Vector2 CalculateDoublePendulumEndPoint(float l1, float theta1, float l2, float theta2)
|
||||
{
|
||||
Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
|
||||
Vector2 endpoint2 = CalculatePendulumEndPoint(l2, theta2);
|
||||
return new(endpoint1.X + endpoint2.X, endpoint1.Y + endpoint2.Y);
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Simulation Parameters
|
||||
l1 = 15.0f; m1 = 0.2f; theta1 = DEG2RAD * 170; w1 = 0;
|
||||
l2 = 15.0f; m2 = 0.1f; theta2 = DEG2RAD * 0; w2 = 0;
|
||||
lengthScaler = 0.1f;
|
||||
totalM = m1 + m2;
|
||||
|
||||
previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
|
||||
previousPosition.X += ((float)screenWidth / 2);
|
||||
previousPosition.Y += ((float)screenHeight / 2 - 100);
|
||||
|
||||
// Scale length
|
||||
L1 = l1 * lengthScaler;
|
||||
L2 = l2 * lengthScaler;
|
||||
|
||||
// Draw parameters
|
||||
lineThick = 20; trailThick = 2;
|
||||
fateAlpha = 0.01f;
|
||||
|
||||
// Create framebuffer
|
||||
target = LoadRenderTexture(screenWidth, screenHeight);
|
||||
SetTextureFilter(target.Texture, TextureFilter.Bilinear);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
float dt = GetFrameTime();
|
||||
float step = dt / SIMULATION_STEPS, step2 = step * step;
|
||||
|
||||
// Update Physics - larger steps = better approximation
|
||||
for (int i = 0; i < SIMULATION_STEPS; i++)
|
||||
{
|
||||
float delta = theta1 - theta2;
|
||||
float sinD = MathF.Sin(delta), cosD = MathF.Cos(delta), cos2D = MathF.Cos(2 * delta);
|
||||
float ww1 = w1 * w1, ww2 = w2 * w2;
|
||||
|
||||
// Calculate a1
|
||||
float a1 = (-G * (2 * m1 + m2) * MathF.Sin(theta1)
|
||||
- m2 * G * MathF.Sin(theta1 - 2 * theta2)
|
||||
- 2 * sinD * m2 * (ww2 * L2 + ww1 * L1 * cosD))
|
||||
/ (L1 * (2 * m1 + m2 - m2 * cos2D));
|
||||
|
||||
// Calculate a2
|
||||
float a2 = (2 * sinD * (ww1 * L1 * totalM
|
||||
+ G * totalM * MathF.Cos(theta1)
|
||||
+ ww2 * L2 * m2 * cosD))
|
||||
/ (L2 * (2 * m1 + m2 - m2 * cos2D));
|
||||
|
||||
// Update thetas
|
||||
theta1 += w1 * step + 0.5f * a1 * step2;
|
||||
theta2 += w2 * step + 0.5f * a2 * step2;
|
||||
|
||||
// Update omegas
|
||||
w1 += a1 * step;
|
||||
w2 += a2 * step;
|
||||
}
|
||||
|
||||
// Calculate position
|
||||
Vector2 currentPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2);
|
||||
currentPosition.X += (float)screenWidth / 2;
|
||||
currentPosition.Y += (float)screenHeight / 2 - 100;
|
||||
|
||||
// Draw to render texture
|
||||
BeginTextureMode(target);
|
||||
// Draw a transparent rectangle - smaller alpha = longer trails
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(Color.Black, fateAlpha));
|
||||
|
||||
// Draw trail
|
||||
DrawCircleV(previousPosition, trailThick, Color.Red);
|
||||
DrawLineEx(previousPosition, currentPosition, trailThick * 2, Color.Red);
|
||||
EndTextureMode();
|
||||
|
||||
// Update previous position
|
||||
previousPosition = currentPosition;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.Black);
|
||||
|
||||
// Draw trails texture
|
||||
DrawTextureRec(target.Texture, new Rectangle(0, 0, (float)target.Texture.Width, (float)-target.Texture.Height), new Vector2(0, 0), Color.White);
|
||||
|
||||
// Draw double pendulum
|
||||
DrawRectanglePro(new Rectangle(screenWidth / 2.0f, screenHeight / 2.0f - 100, 10 * l1, lineThick),
|
||||
new Vector2(0, lineThick * 0.5f), 90 - RAD2DEG * theta1, Color.RayWhite);
|
||||
|
||||
Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
|
||||
DrawRectanglePro(new Rectangle(screenWidth / 2.0f + endpoint1.X, screenHeight / 2.0f - 100 + endpoint1.Y, 10 * l2, lineThick),
|
||||
new Vector2(0, lineThick * 0.5f), 90 - RAD2DEG * theta2, Color.RayWhite);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
UnloadRenderTexture(target);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
SetConfigFlags(ConfigFlags.HighDpiWindow);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - double pendulum");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new DoublePendulum();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - draw circle sector (with gui options)
|
||||
* raylib [shapes] example - circle sector drawing
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Copyright (c) 2018 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
* 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) 2018-2025 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -17,79 +21,128 @@ using static Raylib_cs.Raylib;
|
|||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public class DrawCircleSector
|
||||
public partial class DrawCircleSector : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Draw Circle Sector";
|
||||
|
||||
public string Title => "raylib [shapes] example - circle sector drawing";
|
||||
|
||||
private Vector2 center;
|
||||
private float outerRadius;
|
||||
private float startAngle;
|
||||
private float endAngle;
|
||||
private float segments;
|
||||
private float minSegments;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
center = new((GetScreenWidth() - 300) / 2.0f, GetScreenHeight() / 2.0f);
|
||||
|
||||
outerRadius = 180.0f;
|
||||
startAngle = 0.0f;
|
||||
endAngle = 180.0f;
|
||||
segments = 10.0f;
|
||||
minSegments = 4;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// NOTE: All variables update happens inside GUI control functions
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawLine(500, 0, 500, GetScreenHeight(), Fade(Color.LightGray, 0.6f));
|
||||
DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(Color.LightGray, 0.3f));
|
||||
|
||||
DrawCircleSector(center, outerRadius, startAngle, endAngle, (int)segments, Fade(Color.Maroon, 0.3f));
|
||||
DrawCircleSectorLines(
|
||||
center,
|
||||
outerRadius,
|
||||
startAngle,
|
||||
endAngle,
|
||||
(int)segments,
|
||||
Fade(Color.Maroon, 0.6f)
|
||||
);
|
||||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
GuiSliderBar(new Rectangle(600, 40, 120, 20), "StartAngle", $"{startAngle:F2}", ref startAngle, 0, 720);
|
||||
GuiSliderBar(new Rectangle(600, 70, 120, 20), "EndAngle", $"{endAngle:F2}", ref endAngle, 0, 720);
|
||||
|
||||
GuiSliderBar(new Rectangle(600, 140, 120, 20), "Radius", $"{outerRadius:F2}", ref outerRadius, 0, 200);
|
||||
GuiSliderBar(new Rectangle(600, 170, 120, 20), "Segments", $"{segments:F2}", ref segments, 0, 100);
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
minSegments = MathF.Truncate(MathF.Ceiling((endAngle - startAngle) / 90));
|
||||
var color = (segments >= minSegments) ? Color.Maroon : Color.DarkGray;
|
||||
DrawText($"MODE: {((segments >= minSegments) ? "MANUAL" : "AUTO")}", 600, 200, 10, color);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Minimal raygui-like widgets (plain raylib re-implementation)
|
||||
//----------------------------------------------------------------------------------
|
||||
private static void GuiSliderBar(Rectangle bounds, string textLeft, string textRight, ref float value, float minValue, float maxValue)
|
||||
{
|
||||
Vector2 mouse = GetMousePosition();
|
||||
bool hover = CheckCollisionPointRec(mouse, bounds);
|
||||
if (hover && IsMouseButtonDown(MouseButton.Left))
|
||||
{
|
||||
value = minValue + ((mouse.X - bounds.X) / bounds.Width) * (maxValue - minValue);
|
||||
if (value < minValue) value = minValue;
|
||||
if (value > maxValue) value = maxValue;
|
||||
}
|
||||
|
||||
DrawRectangleRec(bounds, Color.LightGray);
|
||||
float pct = (value - minValue) / (maxValue - minValue);
|
||||
DrawRectangleRec(new Rectangle(bounds.X, bounds.Y, bounds.Width * pct, bounds.Height), Color.SkyBlue);
|
||||
DrawRectangleLinesEx(bounds, 1, Color.Gray);
|
||||
if (!string.IsNullOrEmpty(textLeft)) DrawText(textLeft, (int)bounds.X - MeasureText(textLeft, 10) - 5, (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
if (!string.IsNullOrEmpty(textRight)) DrawText(textRight, (int)(bounds.X + bounds.Width + 5), (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - circle sector drawing");
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw circle sector");
|
||||
|
||||
Vector2 center = new((GetScreenWidth() - 300) / 2, GetScreenHeight() / 2);
|
||||
|
||||
float outerRadius = 180.0f;
|
||||
int startAngle = 0;
|
||||
int endAngle = 180;
|
||||
int segments = 0;
|
||||
int minSegments = 4;
|
||||
|
||||
SetTargetFPS(60);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new DrawCircleSector();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// NOTE: All variables update happens inside GUI control functions
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawLine(500, 0, 500, GetScreenHeight(), ColorAlpha(Color.LightGray, 0.6f));
|
||||
DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), ColorAlpha(Color.LightGray, 0.3f));
|
||||
|
||||
DrawCircleSector(center, outerRadius, startAngle, endAngle, segments, ColorAlpha(Color.Maroon, 0.3f));
|
||||
DrawCircleSectorLines(
|
||||
center,
|
||||
outerRadius,
|
||||
startAngle,
|
||||
endAngle,
|
||||
segments,
|
||||
ColorAlpha(Color.Maroon, 0.6f)
|
||||
);
|
||||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
/*startAngle = GuiSliderBar(new Rectangle( 600, 40, 120, 20), "StartAngle", startAngle, 0, 720, true );
|
||||
endAngle = GuiSliderBar(new Rectangle( 600, 70, 120, 20), "EndAngle", endAngle, 0, 720, true);
|
||||
|
||||
outerRadius = GuiSliderBar(new Rectangle( 600, 140, 120, 20), "Radius", outerRadius, 0, 200, true);
|
||||
segments = GuiSliderBar(new Rectangle( 600, 170, 120, 20), "Segments", segments, 0, 100, true);*/
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
minSegments = (int)MathF.Ceiling((endAngle - startAngle) / 90);
|
||||
Color color = (segments >= minSegments) ? Color.Maroon : Color.DarkGray;
|
||||
DrawText($"MODE: {((segments >= minSegments) ? "MANUAL" : "AUTO")}", 600, 270, 10, color);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - draw rectangle rounded (with gui options)
|
||||
* raylib [shapes] example - rounded rectangle drawing
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Copyright (c) 2018 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
* 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) 2018-2025 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -15,91 +19,154 @@ using static Raylib_cs.Raylib;
|
|||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public class DrawRectangleRounded
|
||||
public partial class DrawRectangleRounded : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Draw Rectangle Rounded";
|
||||
|
||||
public string Title => "raylib [shapes] example - rounded rectangle drawing";
|
||||
|
||||
private float roundness;
|
||||
private float width;
|
||||
private float height;
|
||||
private float segments;
|
||||
private float lineThick;
|
||||
|
||||
private bool drawRect;
|
||||
private bool drawRoundedRect;
|
||||
private bool drawRoundedLines;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
roundness = 0.2f;
|
||||
width = 200.0f;
|
||||
height = 100.0f;
|
||||
segments = 0.0f;
|
||||
lineThick = 1.0f;
|
||||
|
||||
drawRect = false;
|
||||
drawRoundedRect = true;
|
||||
drawRoundedLines = false;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
Rectangle rec = new(
|
||||
((float)GetScreenWidth() - width - 250) / 2,
|
||||
(GetScreenHeight() - height) / 2.0f,
|
||||
(float)width,
|
||||
(float)height
|
||||
);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawLine(560, 0, 560, GetScreenHeight(), Fade(Color.LightGray, 0.6f));
|
||||
DrawRectangle(560, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(Color.LightGray, 0.3f));
|
||||
|
||||
if (drawRect)
|
||||
{
|
||||
DrawRectangleRec(rec, Fade(Color.Gold, 0.6f));
|
||||
}
|
||||
if (drawRoundedRect)
|
||||
{
|
||||
DrawRectangleRounded(rec, roundness, (int)segments, Fade(Color.Maroon, 0.2f));
|
||||
}
|
||||
if (drawRoundedLines)
|
||||
{
|
||||
DrawRectangleRoundedLinesEx(rec, roundness, (int)segments, lineThick, Fade(Color.Maroon, 0.4f));
|
||||
}
|
||||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
GuiSliderBar(new Rectangle(640, 40, 105, 20), "Width", $"{width:F2}", ref width, 0, (float)GetScreenWidth() - 300);
|
||||
GuiSliderBar(new Rectangle(640, 70, 105, 20), "Height", $"{height:F2}", ref height, 0, (float)GetScreenHeight() - 50);
|
||||
GuiSliderBar(new Rectangle(640, 140, 105, 20), "Roundness", $"{roundness:F2}", ref roundness, 0.0f, 1.0f);
|
||||
GuiSliderBar(new Rectangle(640, 170, 105, 20), "Thickness", $"{lineThick:F2}", ref lineThick, 0, 20);
|
||||
GuiSliderBar(new Rectangle(640, 240, 105, 20), "Segments", $"{segments:F2}", ref segments, 0, 60);
|
||||
|
||||
GuiCheckBox(new Rectangle(640, 320, 20, 20), "DrawRoundedRect", ref drawRoundedRect);
|
||||
GuiCheckBox(new Rectangle(640, 350, 20, 20), "DrawRoundedLines", ref drawRoundedLines);
|
||||
GuiCheckBox(new Rectangle(640, 380, 20, 20), "DrawRect", ref drawRect);
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
var text = $"MODE: {((segments >= 4) ? "MANUAL" : "AUTO")}";
|
||||
DrawText(text, 640, 280, 10, (segments >= 4) ? Color.Maroon : Color.DarkGray);
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Minimal raygui-like widgets (plain raylib re-implementation)
|
||||
//----------------------------------------------------------------------------------
|
||||
private static void GuiSliderBar(Rectangle bounds, string textLeft, string textRight, ref float value, float minValue, float maxValue)
|
||||
{
|
||||
Vector2 mouse = GetMousePosition();
|
||||
bool hover = CheckCollisionPointRec(mouse, bounds);
|
||||
if (hover && IsMouseButtonDown(MouseButton.Left))
|
||||
{
|
||||
value = minValue + ((mouse.X - bounds.X) / bounds.Width) * (maxValue - minValue);
|
||||
if (value < minValue) value = minValue;
|
||||
if (value > maxValue) value = maxValue;
|
||||
}
|
||||
|
||||
DrawRectangleRec(bounds, Color.LightGray);
|
||||
float pct = (value - minValue) / (maxValue - minValue);
|
||||
DrawRectangleRec(new Rectangle(bounds.X, bounds.Y, bounds.Width * pct, bounds.Height), Color.SkyBlue);
|
||||
DrawRectangleLinesEx(bounds, 1, Color.Gray);
|
||||
if (!string.IsNullOrEmpty(textLeft)) DrawText(textLeft, (int)bounds.X - MeasureText(textLeft, 10) - 5, (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
if (!string.IsNullOrEmpty(textRight)) DrawText(textRight, (int)(bounds.X + bounds.Width + 5), (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
}
|
||||
|
||||
private static void GuiCheckBox(Rectangle bounds, string text, ref bool active)
|
||||
{
|
||||
Vector2 mouse = GetMousePosition();
|
||||
bool hover = CheckCollisionPointRec(mouse, bounds);
|
||||
if (hover && IsMouseButtonPressed(MouseButton.Left)) active = !active;
|
||||
|
||||
DrawRectangleLinesEx(bounds, 1, hover ? Color.DarkBlue : Color.Gray);
|
||||
if (active) DrawRectangle((int)bounds.X + 4, (int)bounds.Y + 4, (int)bounds.Width - 8, (int)bounds.Height - 8, Color.DarkGray);
|
||||
if (text != null) DrawText(text, (int)(bounds.X + bounds.Width + 8), (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - rounded rectangle drawing");
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw rectangle rounded");
|
||||
|
||||
float roundness = 0.2f;
|
||||
int width = 400;
|
||||
int height = 200;
|
||||
int segments = 0;
|
||||
int lineThick = 10;
|
||||
|
||||
bool drawRect = false;
|
||||
bool drawRoundedRect = false;
|
||||
bool drawRoundedLines = true;
|
||||
|
||||
SetTargetFPS(60);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new DrawRectangleRounded();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
Rectangle rec = new(
|
||||
(GetScreenWidth() - width - 250) / 2.0f,
|
||||
(GetScreenHeight() - height) / 2.0f,
|
||||
(float)width,
|
||||
(float)height
|
||||
);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawLine(560, 0, 560, GetScreenHeight(), ColorAlpha(Color.LightGray, 0.6f));
|
||||
DrawRectangle(560, 0, GetScreenWidth() - 500, GetScreenHeight(), ColorAlpha(Color.LightGray, 0.3f));
|
||||
|
||||
if (drawRect)
|
||||
{
|
||||
DrawRectangleRec(rec, ColorAlpha(Color.Gold, 0.6f));
|
||||
}
|
||||
if (drawRoundedRect)
|
||||
{
|
||||
DrawRectangleRounded(rec, roundness, segments, ColorAlpha(Color.Maroon, 0.2f));
|
||||
}
|
||||
if (drawRoundedLines)
|
||||
{
|
||||
DrawRectangleRoundedLinesEx(rec, roundness, segments, (float)lineThick, ColorAlpha(Color.Maroon, 0.4f));
|
||||
}
|
||||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
/*width = GuiSliderBar(new Rectangle( 640, 40, 105, 20 ), "Width", width, 0, GetScreenWidth() - 300, true );
|
||||
height = GuiSliderBar(new Rectangle( 640, 70, 105, 20 ), "Height", height, 0, GetScreenHeight() - 50, true);
|
||||
roundness = GuiSliderBar(new Rectangle( 640, 140, 105, 20 ), "Roundness", roundness, 0.0f, 1.0f, true);
|
||||
lineThick = GuiSliderBar(new Rectangle( 640, 170, 105, 20 ), "Thickness", lineThick, 0, 20, true);
|
||||
segments = GuiSliderBar(new Rectangle( 640, 240, 105, 20), "Segments", segments, 0, 60, true);
|
||||
|
||||
drawRoundedRect = GuiCheckBox(new Rectangle( 640, 320, 20, 20 ), "DrawRoundedRect", drawRoundedRect);
|
||||
drawRoundedLines = GuiCheckBox(new Rectangle( 640, 350, 20, 20 ), "DrawRoundedLines", drawRoundedLines);
|
||||
drawRect = GuiCheckBox(new Rectangle( 640, 380, 20, 20), "DrawRect", drawRect);*/
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
string text = $"MODE: {((segments >= 4) ? "MANUAL" : "AUTO")}";
|
||||
DrawText(text, 640, 280, 10, (segments >= 4) ? Color.Maroon : Color.DarkGray);
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - draw ring (with gui options)
|
||||
* raylib [shapes] example - ring drawing
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Copyright (c) 2018 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
* 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) 2018-2025 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -17,114 +21,180 @@ using static Raylib_cs.Raylib;
|
|||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public class DrawRing
|
||||
public partial class DrawRing : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Draw Ring";
|
||||
|
||||
public string Title => "raylib [shapes] example - ring drawing";
|
||||
|
||||
private Vector2 center;
|
||||
|
||||
private float innerRadius;
|
||||
private float outerRadius;
|
||||
|
||||
private float startAngle;
|
||||
private float endAngle;
|
||||
private float segments;
|
||||
|
||||
private bool drawRing;
|
||||
private bool drawRingLines;
|
||||
private bool drawCircleLines;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
center = new((GetScreenWidth() - 300) / 2.0f, GetScreenHeight() / 2.0f);
|
||||
|
||||
innerRadius = 80.0f;
|
||||
outerRadius = 190.0f;
|
||||
|
||||
startAngle = 0.0f;
|
||||
endAngle = 360.0f;
|
||||
segments = 0.0f;
|
||||
|
||||
drawRing = true;
|
||||
drawRingLines = false;
|
||||
drawCircleLines = false;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// NOTE: All variables update happens inside GUI control functions
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawLine(500, 0, 500, GetScreenHeight(), Fade(Color.LightGray, 0.6f));
|
||||
DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), Fade(Color.LightGray, 0.3f));
|
||||
|
||||
if (drawRing)
|
||||
{
|
||||
DrawRing(
|
||||
center,
|
||||
innerRadius,
|
||||
outerRadius,
|
||||
startAngle,
|
||||
endAngle,
|
||||
(int)segments,
|
||||
Fade(Color.Maroon, 0.3f)
|
||||
);
|
||||
}
|
||||
if (drawRingLines)
|
||||
{
|
||||
DrawRingLines(
|
||||
center,
|
||||
innerRadius,
|
||||
outerRadius,
|
||||
startAngle,
|
||||
endAngle,
|
||||
(int)segments,
|
||||
Fade(Color.Black, 0.4f)
|
||||
);
|
||||
}
|
||||
if (drawCircleLines)
|
||||
{
|
||||
DrawCircleSectorLines(
|
||||
center,
|
||||
outerRadius,
|
||||
startAngle,
|
||||
endAngle,
|
||||
(int)segments,
|
||||
Fade(Color.Black, 0.4f)
|
||||
);
|
||||
}
|
||||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
GuiSliderBar(new Rectangle(600, 40, 120, 20), "StartAngle", $"{startAngle:F2}", ref startAngle, -450, 450);
|
||||
GuiSliderBar(new Rectangle(600, 70, 120, 20), "EndAngle", $"{endAngle:F2}", ref endAngle, -450, 450);
|
||||
|
||||
GuiSliderBar(new Rectangle(600, 140, 120, 20), "InnerRadius", $"{innerRadius:F2}", ref innerRadius, 0, 100);
|
||||
GuiSliderBar(new Rectangle(600, 170, 120, 20), "OuterRadius", $"{outerRadius:F2}", ref outerRadius, 0, 200);
|
||||
|
||||
GuiSliderBar(new Rectangle(600, 240, 120, 20), "Segments", $"{segments:F2}", ref segments, 0, 100);
|
||||
|
||||
GuiCheckBox(new Rectangle(600, 320, 20, 20), "Draw Ring", ref drawRing);
|
||||
GuiCheckBox(new Rectangle(600, 350, 20, 20), "Draw RingLines", ref drawRingLines);
|
||||
GuiCheckBox(new Rectangle(600, 380, 20, 20), "Draw CircleLines", ref drawCircleLines);
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
var minSegments = (int)MathF.Ceiling((endAngle - startAngle) / 90);
|
||||
var color = (segments >= minSegments) ? Color.Maroon : Color.DarkGray;
|
||||
DrawText($"MODE: {((segments >= minSegments) ? "MANUAL" : "AUTO")}", 600, 270, 10, color);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Minimal raygui-like widgets (plain raylib re-implementation)
|
||||
//----------------------------------------------------------------------------------
|
||||
private static void GuiSliderBar(Rectangle bounds, string textLeft, string textRight, ref float value, float minValue, float maxValue)
|
||||
{
|
||||
Vector2 mouse = GetMousePosition();
|
||||
bool hover = CheckCollisionPointRec(mouse, bounds);
|
||||
if (hover && IsMouseButtonDown(MouseButton.Left))
|
||||
{
|
||||
value = minValue + ((mouse.X - bounds.X) / bounds.Width) * (maxValue - minValue);
|
||||
if (value < minValue) value = minValue;
|
||||
if (value > maxValue) value = maxValue;
|
||||
}
|
||||
|
||||
DrawRectangleRec(bounds, Color.LightGray);
|
||||
float pct = (value - minValue) / (maxValue - minValue);
|
||||
DrawRectangleRec(new Rectangle(bounds.X, bounds.Y, bounds.Width * pct, bounds.Height), Color.SkyBlue);
|
||||
DrawRectangleLinesEx(bounds, 1, Color.Gray);
|
||||
if (!string.IsNullOrEmpty(textLeft)) DrawText(textLeft, (int)bounds.X - MeasureText(textLeft, 10) - 5, (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
if (!string.IsNullOrEmpty(textRight)) DrawText(textRight, (int)(bounds.X + bounds.Width + 5), (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
}
|
||||
|
||||
private static void GuiCheckBox(Rectangle bounds, string text, ref bool active)
|
||||
{
|
||||
Vector2 mouse = GetMousePosition();
|
||||
bool hover = CheckCollisionPointRec(mouse, bounds);
|
||||
if (hover && IsMouseButtonPressed(MouseButton.Left)) active = !active;
|
||||
|
||||
DrawRectangleLinesEx(bounds, 1, hover ? Color.DarkBlue : Color.Gray);
|
||||
if (active) DrawRectangle((int)bounds.X + 4, (int)bounds.Y + 4, (int)bounds.Width - 8, (int)bounds.Height - 8, Color.DarkGray);
|
||||
if (text != null) DrawText(text, (int)(bounds.X + bounds.Width + 8), (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ring drawing");
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - draw ring");
|
||||
|
||||
Vector2 center = new((GetScreenWidth() - 300) / 2, GetScreenHeight() / 2);
|
||||
|
||||
float innerRadius = 80.0f;
|
||||
float outerRadius = 190.0f;
|
||||
|
||||
int startAngle = 0;
|
||||
int endAngle = 360;
|
||||
int segments = 0;
|
||||
int minSegments = 4;
|
||||
|
||||
bool drawRing = true;
|
||||
bool drawRingLines = false;
|
||||
bool drawCircleLines = false;
|
||||
|
||||
SetTargetFPS(60);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new DrawRing();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// NOTE: All variables update happens inside GUI control functions
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawLine(500, 0, 500, GetScreenHeight(), ColorAlpha(Color.LightGray, 0.6f));
|
||||
DrawRectangle(500, 0, GetScreenWidth() - 500, GetScreenHeight(), ColorAlpha(Color.LightGray, 0.3f));
|
||||
|
||||
if (drawRing)
|
||||
{
|
||||
DrawRing(
|
||||
center,
|
||||
innerRadius,
|
||||
outerRadius,
|
||||
startAngle,
|
||||
endAngle,
|
||||
segments,
|
||||
ColorAlpha(Color.Maroon, 0.3f)
|
||||
);
|
||||
}
|
||||
if (drawRingLines)
|
||||
{
|
||||
DrawRingLines(
|
||||
center,
|
||||
innerRadius,
|
||||
outerRadius,
|
||||
startAngle,
|
||||
endAngle,
|
||||
segments,
|
||||
ColorAlpha(Color.Black, 0.4f)
|
||||
);
|
||||
}
|
||||
if (drawCircleLines)
|
||||
{
|
||||
DrawCircleSectorLines(
|
||||
center,
|
||||
outerRadius,
|
||||
startAngle,
|
||||
endAngle,
|
||||
segments,
|
||||
ColorAlpha(Color.Black, 0.4f)
|
||||
);
|
||||
}
|
||||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
/*startAngle = GuiSliderBar(new Rectangle( 600, 40, 120, 20 ), "StartAngle", startAngle, -450, 450, true);
|
||||
endAngle = GuiSliderBar(new Rectangle( 600, 70, 120, 20 ), "EndAngle", endAngle, -450, 450, true);
|
||||
|
||||
innerRadius = GuiSliderBar(new Rectangle( 600, 140, 120, 20 ), "InnerRadius", innerRadius, 0, 100, true);
|
||||
outerRadius = GuiSliderBar(new Rectangle( 600, 170, 120, 20 ), "OuterRadius", outerRadius, 0, 200, true);
|
||||
|
||||
segments = GuiSliderBar(new Rectangle( 600, 240, 120, 20 ), "Segments", segments, 0, 100, true);
|
||||
|
||||
drawRing = GuiCheckBox(new Rectangle( 600, 320, 20, 20 ), "Draw Ring", drawRing);
|
||||
drawRingLines = GuiCheckBox(new Rectangle( 600, 350, 20, 20 ), "Draw RingLines", drawRingLines);
|
||||
drawCircleLines = GuiCheckBox(new Rectangle( 600, 380, 20, 20 ), "Draw CircleLines", drawCircleLines);*/
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
minSegments = (int)MathF.Ceiling((endAngle - startAngle) / 90);
|
||||
Color color = (segments >= minSegments) ? Color.Maroon : Color.DarkGray;
|
||||
DrawText($"MODE: {((segments >= minSegments) ? "MANUAL" : "AUTO")}", 600, 270, 10, color);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - easings ball anim
|
||||
* raylib [shapes] example - easings ball
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.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) 2014-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -14,114 +18,138 @@ using Examples.Shared;
|
|||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public class EasingsBallAnim
|
||||
public partial class EasingsBallAnim : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Easings Ball Anim";
|
||||
|
||||
public string Title => "raylib [shapes] example - easings ball";
|
||||
|
||||
// Ball variable value to be animated with easings
|
||||
private int ballPositionX;
|
||||
private int ballRadius;
|
||||
private float ballAlpha;
|
||||
|
||||
private int state;
|
||||
private int framesCounter;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
ballPositionX = -100;
|
||||
ballRadius = 20;
|
||||
ballAlpha = 0.0f;
|
||||
|
||||
state = 0;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (state == 0) // Move ball position X with easing
|
||||
{
|
||||
framesCounter++;
|
||||
ballPositionX = (int)Easings.EaseElasticOut(framesCounter, -100, screenWidth / 2.0f + 100, 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 1;
|
||||
}
|
||||
}
|
||||
else if (state == 1) // Increase ball radius with easing
|
||||
{
|
||||
framesCounter++;
|
||||
ballRadius = (int)Easings.EaseElasticIn(framesCounter, 20, 500, 200);
|
||||
|
||||
if (framesCounter >= 200)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 2;
|
||||
}
|
||||
}
|
||||
else if (state == 2) // Change ball alpha with easing (background color blending)
|
||||
{
|
||||
framesCounter++;
|
||||
ballAlpha = Easings.EaseCubicOut(framesCounter, 0.0f, 1.0f, 200);
|
||||
|
||||
if (framesCounter >= 200)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 3;
|
||||
}
|
||||
}
|
||||
else if (state == 3) // Reset state to play again
|
||||
{
|
||||
if (IsKeyPressed(KeyboardKey.Enter))
|
||||
{
|
||||
// Reset required variables to play again
|
||||
ballPositionX = -100;
|
||||
ballRadius = 20;
|
||||
ballAlpha = 0.0f;
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.R))
|
||||
{
|
||||
framesCounter = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
if (state >= 2)
|
||||
{
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, Color.Green);
|
||||
}
|
||||
|
||||
DrawCircle(ballPositionX, 200, ballRadius, Fade(Color.Red, 1.0f - ballAlpha));
|
||||
|
||||
if (state == 3)
|
||||
{
|
||||
DrawText("PRESS [ENTER] TO PLAY AGAIN!", 240, 200, 20, Color.Black);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings ball");
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings ball anim");
|
||||
|
||||
// Ball variable value to be animated with easings
|
||||
int ballPositionX = -100;
|
||||
int ballRadius = 20;
|
||||
float ballAlpha = 0.0f;
|
||||
|
||||
int state = 0;
|
||||
int framesCounter = 0;
|
||||
|
||||
SetTargetFPS(60);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new EasingsBallAnim();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (state == 0) // Move ball position X with easing
|
||||
{
|
||||
framesCounter += 1;
|
||||
ballPositionX = (int)Easings.EaseElasticOut(framesCounter, -100, screenWidth / 2 + 100, 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 1;
|
||||
}
|
||||
}
|
||||
// Increase ball radius with easing
|
||||
else if (state == 1)
|
||||
{
|
||||
framesCounter += 1;
|
||||
ballRadius = (int)Easings.EaseElasticIn(framesCounter, 20, 500, 200);
|
||||
|
||||
if (framesCounter >= 200)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 2;
|
||||
}
|
||||
}
|
||||
// Change ball alpha with easing (background color blending)
|
||||
else if (state == 2)
|
||||
{
|
||||
framesCounter += 1;
|
||||
ballAlpha = Easings.EaseCubicOut(framesCounter, 0.0f, 1.0f, 200);
|
||||
|
||||
if (framesCounter >= 200)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 3;
|
||||
}
|
||||
}
|
||||
// Reset state to play again
|
||||
else if (state == 3)
|
||||
{
|
||||
if (IsKeyPressed(KeyboardKey.Enter))
|
||||
{
|
||||
// Reset required variables to play again
|
||||
ballPositionX = -100;
|
||||
ballRadius = 20;
|
||||
ballAlpha = 0.0f;
|
||||
state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.R))
|
||||
{
|
||||
framesCounter = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
if (state >= 2)
|
||||
{
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, Color.Green);
|
||||
}
|
||||
|
||||
DrawCircle(ballPositionX, 200, ballRadius, ColorAlpha(Color.Red, 1.0f - ballAlpha));
|
||||
|
||||
if (state == 3)
|
||||
{
|
||||
DrawText("PRESS [ENTER] TO PLAY AGAIN!", 240, 200, 20, Color.Black);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - easings box anim
|
||||
* raylib [shapes] example - easings box
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.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) 2014-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -15,129 +19,152 @@ using Examples.Shared;
|
|||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public class EasingsBoxAnim
|
||||
public partial class EasingsBoxAnim : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Easings Box Anim";
|
||||
|
||||
public string Title => "raylib [shapes] example - easings box";
|
||||
|
||||
// Box variables to be animated with easings
|
||||
private Rectangle rec;
|
||||
private float rotation;
|
||||
private float alpha;
|
||||
|
||||
private int state;
|
||||
private int framesCounter;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
rec = new(GetScreenWidth() / 2.0f, -100, 100, 100);
|
||||
rotation = 0.0f;
|
||||
alpha = 1.0f;
|
||||
|
||||
state = 0;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
switch (state)
|
||||
{
|
||||
case 0: // Move box down to center of screen
|
||||
framesCounter++;
|
||||
|
||||
// NOTE: Remember that 3rd parameter of easing function refers to
|
||||
// desired value variation, do not confuse it with expected final value!
|
||||
rec.Y = Easings.EaseElasticOut(framesCounter, -100, GetScreenHeight() / 2.0f + 100, 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 1;
|
||||
}
|
||||
break;
|
||||
case 1: // Scale box to an horizontal bar
|
||||
framesCounter++;
|
||||
rec.Height = Easings.EaseBounceOut(framesCounter, 100, -90, 120);
|
||||
rec.Width = Easings.EaseBounceOut(framesCounter, 100, GetScreenWidth(), 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 2;
|
||||
}
|
||||
break;
|
||||
case 2: // Rotate horizontal bar rectangle
|
||||
framesCounter++;
|
||||
rotation = Easings.EaseQuadOut(framesCounter, 0.0f, 270.0f, 240);
|
||||
|
||||
if (framesCounter >= 240)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 3;
|
||||
}
|
||||
break;
|
||||
case 3: // Increase bar size to fill all screen
|
||||
framesCounter++;
|
||||
rec.Height = Easings.EaseCircOut(framesCounter, 10, GetScreenWidth(), 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 4;
|
||||
}
|
||||
break;
|
||||
case 4: // Fade out animation
|
||||
framesCounter++;
|
||||
alpha = Easings.EaseSineOut(framesCounter, 1.0f, -1.0f, 160);
|
||||
|
||||
if (framesCounter >= 160)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 5;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Reset animation at any moment
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
rec = new Rectangle(GetScreenWidth() / 2.0f, -100, 100, 100);
|
||||
rotation = 0.0f;
|
||||
alpha = 1.0f;
|
||||
state = 0;
|
||||
framesCounter = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawRectanglePro(
|
||||
rec,
|
||||
new Vector2(rec.Width / 2, rec.Height / 2),
|
||||
rotation,
|
||||
Fade(Color.Black, alpha)
|
||||
);
|
||||
DrawText("PRESS [SPACE] TO RESET BOX ANIMATION!", 10, GetScreenHeight() - 25, 20, Color.LightGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings box");
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings box anim");
|
||||
|
||||
// Box variables to be animated with easings
|
||||
Rectangle rec = new(GetScreenWidth() / 2, -100, 100, 100);
|
||||
float rotation = 0.0f;
|
||||
float alpha = 1.0f;
|
||||
|
||||
int state = 0;
|
||||
int framesCounter = 0;
|
||||
|
||||
SetTargetFPS(60);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new EasingsBoxAnim();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
switch (state)
|
||||
{
|
||||
// Move box down to center of screen
|
||||
case 0:
|
||||
framesCounter += 1;
|
||||
|
||||
// NOTE: Remember that 3rd parameter of easing function refers to
|
||||
// desired value variation, do not confuse it with expected final value!
|
||||
rec.Y = Easings.EaseElasticOut(framesCounter, -100, GetScreenHeight() / 2 + 100, 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 1;
|
||||
}
|
||||
break;
|
||||
// Scale box to an horizontal bar
|
||||
case 1:
|
||||
framesCounter += 1;
|
||||
rec.Height = Easings.EaseBounceOut(framesCounter, 100, -90, 120);
|
||||
rec.Width = Easings.EaseBounceOut(framesCounter, 100, GetScreenWidth(), 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 2;
|
||||
}
|
||||
break;
|
||||
// Rotate horizontal bar rectangle
|
||||
case 2:
|
||||
framesCounter += 1;
|
||||
rotation = Easings.EaseQuadOut(framesCounter, 0.0f, 270.0f, 240);
|
||||
|
||||
if (framesCounter >= 240)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 3;
|
||||
}
|
||||
break;
|
||||
// Increase bar size to fill all screen
|
||||
case 3:
|
||||
framesCounter += 1;
|
||||
rec.Height = Easings.EaseCircOut(framesCounter, 10, GetScreenWidth(), 120);
|
||||
|
||||
if (framesCounter >= 120)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 4;
|
||||
}
|
||||
break;
|
||||
// Fade out animation
|
||||
case 4:
|
||||
framesCounter++;
|
||||
alpha = Easings.EaseSineOut(framesCounter, 1.0f, -1.0f, 160);
|
||||
|
||||
if (framesCounter >= 160)
|
||||
{
|
||||
framesCounter = 0;
|
||||
state = 5;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Reset animation at any moment
|
||||
if (IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
rec = new Rectangle(GetScreenWidth() / 2, -100, 100, 100);
|
||||
rotation = 0.0f;
|
||||
alpha = 1.0f;
|
||||
state = 0;
|
||||
framesCounter = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawRectanglePro(
|
||||
rec,
|
||||
new Vector2(rec.Width / 2, rec.Height / 2),
|
||||
rotation,
|
||||
ColorAlpha(Color.Black, alpha)
|
||||
);
|
||||
DrawText("PRESS [SPACE] TO RESET BOX ANIMATION!", 10, GetScreenHeight() - 25, 20, Color.LightGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - easings rectangle array
|
||||
* raylib [shapes] example - easings rectangles
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* NOTE: This example requires 'easings.h' library, provided on raylib/src. Just copy
|
||||
* the library to same directory as example or make sure it's available on include path.
|
||||
* the library to same directory as example or make sure it's available on include path
|
||||
*
|
||||
* This example has been created using raylib 2.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example originally created with raylib 2.0, last time updated with raylib 2.5
|
||||
*
|
||||
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
|
||||
* 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) 2014-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -18,8 +22,11 @@ using Examples.Shared;
|
|||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public class EasingsRectangleArray
|
||||
public partial class EasingsRectangleArray : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public const int RecsWidth = 50;
|
||||
public const int RecsHeight = 50;
|
||||
public const int MaxRecsX = 800 / RecsWidth;
|
||||
|
|
@ -28,112 +35,133 @@ public class EasingsRectangleArray
|
|||
// At 60 fps = 4 seconds
|
||||
public const int PlayTimeInFrames = 240;
|
||||
|
||||
public static int Main()
|
||||
public string Name => "Shapes / Easings Rectangle Array";
|
||||
|
||||
public string Title => "raylib [shapes] example - easings rectangles";
|
||||
|
||||
private Rectangle[] recs;
|
||||
private float rotation;
|
||||
private int framesCounter;
|
||||
private int state; // Rectangles animation state: 0-Playing, 1-Finished
|
||||
|
||||
public void Init()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
recs = new Rectangle[MaxRecsX * MaxRecsY];
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings rectangle array");
|
||||
|
||||
Rectangle[] recs = new Rectangle[MaxRecsX * MaxRecsY];
|
||||
|
||||
for (int y = 0; y < MaxRecsY; y++)
|
||||
for (var y = 0; y < MaxRecsY; y++)
|
||||
{
|
||||
for (int x = 0; x < MaxRecsX; x++)
|
||||
for (var x = 0; x < MaxRecsX; x++)
|
||||
{
|
||||
recs[y * MaxRecsX + x].X = RecsWidth / 2 + RecsWidth * x;
|
||||
recs[y * MaxRecsX + x].Y = RecsHeight / 2 + RecsHeight * y;
|
||||
recs[y * MaxRecsX + x].X = RecsWidth / 2.0f + RecsWidth * x;
|
||||
recs[y * MaxRecsX + x].Y = RecsHeight / 2.0f + RecsHeight * y;
|
||||
recs[y * MaxRecsX + x].Width = RecsWidth;
|
||||
recs[y * MaxRecsX + x].Height = RecsHeight;
|
||||
}
|
||||
}
|
||||
|
||||
float rotation = 0.0f;
|
||||
int framesCounter = 0;
|
||||
rotation = 0.0f;
|
||||
framesCounter = 0;
|
||||
state = 0;
|
||||
}
|
||||
|
||||
// Rectangles animation state: 0-Playing, 1-Finished
|
||||
int state = 0;
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (state == 0)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
SetTargetFPS(60);
|
||||
for (var i = 0; i < MaxRecsX * MaxRecsY; i++)
|
||||
{
|
||||
recs[i].Height = Easings.EaseCircOut(framesCounter, RecsHeight, -RecsHeight, PlayTimeInFrames);
|
||||
recs[i].Width = Easings.EaseCircOut(framesCounter, RecsWidth, -RecsWidth, PlayTimeInFrames);
|
||||
|
||||
if (recs[i].Height < 0)
|
||||
{
|
||||
recs[i].Height = 0;
|
||||
}
|
||||
if (recs[i].Width < 0)
|
||||
{
|
||||
recs[i].Width = 0;
|
||||
}
|
||||
|
||||
// Finish playing
|
||||
if ((recs[i].Height == 0) && (recs[i].Width == 0))
|
||||
{
|
||||
state = 1;
|
||||
}
|
||||
rotation = Easings.EaseLinearIn(framesCounter, 0.0f, 360.0f, PlayTimeInFrames);
|
||||
}
|
||||
}
|
||||
else if ((state == 1) && IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
// When animation has finished, press space to restart
|
||||
framesCounter = 0;
|
||||
|
||||
for (var i = 0; i < MaxRecsX * MaxRecsY; i++)
|
||||
{
|
||||
recs[i].Height = RecsHeight;
|
||||
recs[i].Width = RecsWidth;
|
||||
}
|
||||
|
||||
state = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
if (state == 0)
|
||||
{
|
||||
for (var i = 0; i < MaxRecsX * MaxRecsY; i++)
|
||||
{
|
||||
DrawRectanglePro(
|
||||
recs[i],
|
||||
new Vector2(recs[i].Width / 2, recs[i].Height / 2),
|
||||
rotation,
|
||||
Color.Red
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (state == 1)
|
||||
{
|
||||
DrawText("PRESS [SPACE] TO PLAY AGAIN!", 240, 200, 20, Color.Gray);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings rectangles");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new EasingsRectangleArray();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (state == 0)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
for (int i = 0; i < MaxRecsX * MaxRecsY; i++)
|
||||
{
|
||||
recs[i].Height = Easings.EaseCircOut(framesCounter, RecsHeight, -RecsHeight, PlayTimeInFrames);
|
||||
recs[i].Width = Easings.EaseCircOut(framesCounter, RecsWidth, -RecsWidth, PlayTimeInFrames);
|
||||
|
||||
if (recs[i].Height < 0)
|
||||
{
|
||||
recs[i].Height = 0;
|
||||
}
|
||||
if (recs[i].Width < 0)
|
||||
{
|
||||
recs[i].Width = 0;
|
||||
}
|
||||
|
||||
// Finish playing
|
||||
if ((recs[i].Height == 0) && (recs[i].Width == 0))
|
||||
{
|
||||
state = 1;
|
||||
}
|
||||
rotation = Easings.EaseLinearIn(framesCounter, 0.0f, 360.0f, PlayTimeInFrames);
|
||||
}
|
||||
}
|
||||
else if ((state == 1) && IsKeyPressed(KeyboardKey.Space))
|
||||
{
|
||||
// When animation has finished, press space to restart
|
||||
framesCounter = 0;
|
||||
|
||||
for (int i = 0; i < MaxRecsX * MaxRecsY; i++)
|
||||
{
|
||||
recs[i].Height = RecsHeight;
|
||||
recs[i].Width = RecsWidth;
|
||||
}
|
||||
|
||||
state = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
if (state == 0)
|
||||
{
|
||||
for (int i = 0; i < MaxRecsX * MaxRecsY; i++)
|
||||
{
|
||||
DrawRectanglePro(
|
||||
recs[i],
|
||||
new Vector2(recs[i].Width / 2, recs[i].Height / 2),
|
||||
rotation,
|
||||
Color.Red
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (state == 1)
|
||||
{
|
||||
DrawText("PRESS [SPACE] TO PLAY AGAIN!", 240, 200, 20, Color.Gray);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
230
Examples/Shapes/EasingsTestbed.cs
Normal file
230
Examples/Shapes/EasingsTestbed.cs
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - easings testbed
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Juan Miguel López (@flashback-fx) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* 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) 2019-2025 Juan Miguel López (@flashback-fx) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Examples.Shared;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public partial class EasingsTestbed : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
private const int FONT_SIZE = 20;
|
||||
|
||||
private const float D_STEP = 20.0f;
|
||||
private const float D_STEP_FINE = 2.0f;
|
||||
private const float D_MIN = 1.0f;
|
||||
private const float D_MAX = 10000.0f;
|
||||
|
||||
public string Name => "Shapes / Easings Testbed";
|
||||
|
||||
public string Title => "raylib [shapes] example - easings testbed";
|
||||
|
||||
// Easing types
|
||||
private const int EASE_LINEAR_NONE = 0;
|
||||
private const int NUM_EASING_TYPES = 27;
|
||||
private const int EASING_NONE = NUM_EASING_TYPES;
|
||||
|
||||
// NoEase function, used when "no easing" is selected for any axis
|
||||
// It just ignores all parameters besides b
|
||||
private static float NoEase(float t, float b, float c, float d)
|
||||
{
|
||||
// Hack to avoid compiler warning (about unused variables)
|
||||
float burn = t + b + c + d;
|
||||
d += burn;
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
// Easing functions reference data
|
||||
private string[] easingNames;
|
||||
private Func<float, float, float, float, float>[] easingFuncs;
|
||||
|
||||
private Vector2 ballPosition;
|
||||
private float t; // Current time (in any unit measure, but same unit as duration)
|
||||
private float d; // Total time it should take to complete (duration)
|
||||
private bool paused;
|
||||
private bool boundedT; // If true, t will stop when d >= td, otherwise t will keep adding td to its value every loop
|
||||
|
||||
private int easingX; // Easing selected for x axis
|
||||
private int easingY; // Easing selected for y axis
|
||||
|
||||
public void Init()
|
||||
{
|
||||
easingNames = new string[]
|
||||
{
|
||||
"EaseLinearNone", "EaseLinearIn", "EaseLinearOut", "EaseLinearInOut",
|
||||
"EaseSineIn", "EaseSineOut", "EaseSineInOut",
|
||||
"EaseCircIn", "EaseCircOut", "EaseCircInOut",
|
||||
"EaseCubicIn", "EaseCubicOut", "EaseCubicInOut",
|
||||
"EaseQuadIn", "EaseQuadOut", "EaseQuadInOut",
|
||||
"EaseExpoIn", "EaseExpoOut", "EaseExpoInOut",
|
||||
"EaseBackIn", "EaseBackOut", "EaseBackInOut",
|
||||
"EaseBounceOut", "EaseBounceIn", "EaseBounceInOut",
|
||||
"EaseElasticIn", "EaseElasticOut", "EaseElasticInOut",
|
||||
"None",
|
||||
};
|
||||
|
||||
easingFuncs = new Func<float, float, float, float, float>[]
|
||||
{
|
||||
Easings.EaseLinearNone, Easings.EaseLinearIn, Easings.EaseLinearOut, Easings.EaseLinearInOut,
|
||||
Easings.EaseSineIn, Easings.EaseSineOut, Easings.EaseSineInOut,
|
||||
Easings.EaseCircIn, Easings.EaseCircOut, Easings.EaseCircInOut,
|
||||
Easings.EaseCubicIn, Easings.EaseCubicOut, Easings.EaseCubicInOut,
|
||||
Easings.EaseQuadIn, Easings.EaseQuadOut, Easings.EaseQuadInOut,
|
||||
Easings.EaseExpoIn, Easings.EaseExpoOut, Easings.EaseExpoInOut,
|
||||
Easings.EaseBackIn, Easings.EaseBackOut, Easings.EaseBackInOut,
|
||||
Easings.EaseBounceOut, Easings.EaseBounceIn, Easings.EaseBounceInOut,
|
||||
Easings.EaseElasticIn, Easings.EaseElasticOut, Easings.EaseElasticInOut,
|
||||
NoEase,
|
||||
};
|
||||
|
||||
ballPosition = new Vector2(100.0f, 100.0f);
|
||||
|
||||
t = 0.0f;
|
||||
d = 300.0f;
|
||||
paused = true;
|
||||
boundedT = true;
|
||||
|
||||
easingX = EASING_NONE;
|
||||
easingY = EASING_NONE;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KeyboardKey.T)) boundedT = !boundedT;
|
||||
|
||||
// Choose easing for the X axis
|
||||
if (IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
easingX++;
|
||||
|
||||
if (easingX > EASING_NONE) easingX = 0;
|
||||
}
|
||||
else if (IsKeyPressed(KeyboardKey.Left))
|
||||
{
|
||||
if (easingX == 0) easingX = EASING_NONE;
|
||||
else easingX--;
|
||||
}
|
||||
|
||||
// Choose easing for the Y axis
|
||||
if (IsKeyPressed(KeyboardKey.Down))
|
||||
{
|
||||
easingY++;
|
||||
|
||||
if (easingY > EASING_NONE) easingY = 0;
|
||||
}
|
||||
else if (IsKeyPressed(KeyboardKey.Up))
|
||||
{
|
||||
if (easingY == 0) easingY = EASING_NONE;
|
||||
else easingY--;
|
||||
}
|
||||
|
||||
// Change d (duration) value
|
||||
if (IsKeyPressed(KeyboardKey.W) && (d < D_MAX - D_STEP)) d += D_STEP;
|
||||
else if (IsKeyPressed(KeyboardKey.Q) && (d > D_MIN + D_STEP)) d -= D_STEP;
|
||||
|
||||
if (IsKeyDown(KeyboardKey.S) && (d < D_MAX - D_STEP_FINE)) d += D_STEP_FINE;
|
||||
else if (IsKeyDown(KeyboardKey.A) && (d > D_MIN + D_STEP_FINE)) d -= D_STEP_FINE;
|
||||
|
||||
// Play, pause and restart controls
|
||||
if (IsKeyPressed(KeyboardKey.Space) || IsKeyPressed(KeyboardKey.T) ||
|
||||
IsKeyPressed(KeyboardKey.Right) || IsKeyPressed(KeyboardKey.Left) ||
|
||||
IsKeyPressed(KeyboardKey.Down) || IsKeyPressed(KeyboardKey.Up) ||
|
||||
IsKeyPressed(KeyboardKey.W) || IsKeyPressed(KeyboardKey.Q) ||
|
||||
IsKeyDown(KeyboardKey.S) || IsKeyDown(KeyboardKey.A) ||
|
||||
(IsKeyPressed(KeyboardKey.Enter) && (boundedT == true) && (t >= d)))
|
||||
{
|
||||
t = 0.0f;
|
||||
ballPosition.X = 100.0f;
|
||||
ballPosition.Y = 100.0f;
|
||||
paused = true;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.Enter)) paused = !paused;
|
||||
|
||||
// Movement computation
|
||||
if (!paused && ((boundedT && t < d) || !boundedT))
|
||||
{
|
||||
ballPosition.X = easingFuncs[easingX](t, 100.0f, 700.0f - 170.0f, d);
|
||||
ballPosition.Y = easingFuncs[easingY](t, 100.0f, 400.0f - 170.0f, d);
|
||||
t += 1.0f;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw information text
|
||||
DrawText($"Easing x: {easingNames[easingX]}", 20, FONT_SIZE, FONT_SIZE, Color.LightGray);
|
||||
DrawText($"Easing y: {easingNames[easingY]}", 20, FONT_SIZE * 2, FONT_SIZE, Color.LightGray);
|
||||
DrawText($"t ({(boundedT == true ? 'b' : 'u')}) = {t:F2} d = {d:F2}", 20, FONT_SIZE * 3, FONT_SIZE, Color.LightGray);
|
||||
|
||||
// Draw instructions text
|
||||
DrawText("Use ENTER to play or pause movement, use SPACE to restart", 20, GetScreenHeight() - FONT_SIZE * 2, FONT_SIZE, Color.LightGray);
|
||||
DrawText("Use Q and W or A and S keys to change duration", 20, GetScreenHeight() - FONT_SIZE * 3, FONT_SIZE, Color.LightGray);
|
||||
DrawText("Use LEFT or RIGHT keys to choose easing for the x axis", 20, GetScreenHeight() - FONT_SIZE * 4, FONT_SIZE, Color.LightGray);
|
||||
DrawText("Use UP or DOWN keys to choose easing for the y axis", 20, GetScreenHeight() - FONT_SIZE * 5, FONT_SIZE, Color.LightGray);
|
||||
|
||||
// Draw ball
|
||||
DrawCircleV(ballPosition, 16.0f, Color.Maroon);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - easings testbed");
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new EasingsTestbed();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
195
Examples/Shapes/EllipseCollision.cs
Normal file
195
Examples/Shapes/EllipseCollision.cs
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - ellipse collision
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 5.5
|
||||
*
|
||||
* Example contributed by Ziya (@Monjaris)
|
||||
*
|
||||
* 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) 2025 Ziya (@Monjaris)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public partial class EllipseCollision : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Ellipse Collision";
|
||||
|
||||
public string Title => "raylib [shapes] example - collision ellipses";
|
||||
|
||||
private Vector2 ellipseACenter;
|
||||
private float ellipseARx;
|
||||
private float ellipseARy;
|
||||
|
||||
private Vector2 ellipseBCenter;
|
||||
private float ellipseBRx;
|
||||
private float ellipseBRy;
|
||||
|
||||
// 0 = controlling A, 1 = controlling B
|
||||
private int controlled;
|
||||
|
||||
// Check if point is inside ellipse
|
||||
private static bool CheckCollisionPointEllipse(Vector2 point, Vector2 center, float rx, float ry)
|
||||
{
|
||||
float dx = (point.X - center.X) / rx;
|
||||
float dy = (point.Y - center.Y) / ry;
|
||||
return (dx * dx + dy * dy) <= 1.0f;
|
||||
}
|
||||
|
||||
// Check if two ellipses collide
|
||||
// Uses radial boundary distance in the direction between centers — scales correctly with radii
|
||||
private static bool CheckCollisionEllipses(Vector2 c1, float rx1, float ry1, Vector2 c2, float rx2, float ry2)
|
||||
{
|
||||
float dx = c2.X - c1.X;
|
||||
float dy = c2.Y - c1.Y;
|
||||
float dist = MathF.Sqrt(dx * dx + dy * dy);
|
||||
|
||||
// Ellipses are on top of each other
|
||||
if (dist == 0.0f)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
float theta = MathF.Atan2(dy, dx);
|
||||
float cosT = MathF.Cos(theta);
|
||||
float sinT = MathF.Sin(theta);
|
||||
|
||||
// Radial distance from center to ellipse boundary in direction theta
|
||||
// r(theta) = (rx * ry) / sqrt((ry*cos)^2 + (rx*sin)^2)
|
||||
float r1 = (rx1 * ry1) / MathF.Sqrt((ry1 * cosT) * (ry1 * cosT) + (rx1 * sinT) * (rx1 * sinT));
|
||||
float r2 = (rx2 * ry2) / MathF.Sqrt((ry2 * cosT) * (ry2 * cosT) + (rx2 * sinT) * (rx2 * sinT));
|
||||
|
||||
return dist <= (r1 + r2);
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
ellipseACenter = new((float)screenWidth / 4, (float)screenHeight / 2);
|
||||
ellipseARx = 120.0f;
|
||||
ellipseARy = 70.0f;
|
||||
|
||||
ellipseBCenter = new((float)screenWidth * 3 / 4, (float)screenHeight / 2);
|
||||
ellipseBRx = 90.0f;
|
||||
ellipseBRy = 140.0f;
|
||||
|
||||
// 0 = controlling A, 1 = controlling B
|
||||
controlled = 0;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KeyboardKey.A))
|
||||
{
|
||||
controlled = 0;
|
||||
}
|
||||
if (IsKeyPressed(KeyboardKey.B))
|
||||
{
|
||||
controlled = 1;
|
||||
}
|
||||
|
||||
if (controlled == 0)
|
||||
{
|
||||
ellipseACenter = GetMousePosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
ellipseBCenter = GetMousePosition();
|
||||
}
|
||||
|
||||
bool ellipsesCollide = CheckCollisionEllipses(
|
||||
ellipseACenter, ellipseARx, ellipseARy,
|
||||
ellipseBCenter, ellipseBRx, ellipseBRy
|
||||
);
|
||||
|
||||
bool mouseInA = CheckCollisionPointEllipse(GetMousePosition(), ellipseACenter, ellipseARx, ellipseARy);
|
||||
bool mouseInB = CheckCollisionPointEllipse(GetMousePosition(), ellipseBCenter, ellipseBRx, ellipseBRy);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawEllipse((int)ellipseACenter.X, (int)ellipseACenter.Y, ellipseARx, ellipseARy, ellipsesCollide ? Color.Red : Color.Blue);
|
||||
|
||||
DrawEllipse((int)ellipseBCenter.X, (int)ellipseBCenter.Y, ellipseBRx, ellipseBRy, ellipsesCollide ? Color.Red : Color.Green);
|
||||
|
||||
DrawEllipseLines((int)ellipseACenter.X, (int)ellipseACenter.Y, ellipseARx, ellipseARy, Color.White);
|
||||
|
||||
DrawEllipseLines((int)ellipseBCenter.X, (int)ellipseBCenter.Y, ellipseBRx, ellipseBRy, Color.White);
|
||||
|
||||
DrawCircleV(ellipseACenter, 4, Color.White);
|
||||
DrawCircleV(ellipseBCenter, 4, Color.White);
|
||||
|
||||
if (ellipsesCollide)
|
||||
{
|
||||
DrawText("ELLIPSES COLLIDE", screenWidth / 2 - 120, 40, 28, Color.Red);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText("NO COLLISION", screenWidth / 2 - 80, 40, 28, Color.DarkGray);
|
||||
}
|
||||
|
||||
DrawText(controlled == 0 ? "Controlling: A" : "Controlling: B", 20, screenHeight - 40, 20, Color.Yellow);
|
||||
|
||||
if (mouseInA && controlled != 0)
|
||||
{
|
||||
DrawText("Mouse inside ellipse A", 20, screenHeight - 70, 20, Color.Blue);
|
||||
}
|
||||
if (mouseInB && controlled != 1)
|
||||
{
|
||||
DrawText("Mouse inside ellipse B", 20, screenHeight - 70, 20, Color.Green);
|
||||
}
|
||||
|
||||
DrawText("Press [A] or [B] to switch control", 20, 20, 20, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - collision ellipses");
|
||||
SetTargetFPS(60);
|
||||
|
||||
var game = new EllipseCollision();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,10 +2,14 @@
|
|||
*
|
||||
* raylib [shapes] example - following eyes
|
||||
*
|
||||
* This example has been created using raylib 2.5 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 2.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) 2013-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -16,92 +20,127 @@ using static Raylib_cs.Raylib;
|
|||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public class FollowingEyes
|
||||
public partial class FollowingEyes : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Following Eyes";
|
||||
|
||||
public string Title => "raylib [shapes] example - following eyes";
|
||||
|
||||
private Vector2 scleraLeftPosition;
|
||||
private Vector2 scleraRightPosition;
|
||||
private float scleraRadius;
|
||||
|
||||
private Vector2 irisLeftPosition;
|
||||
private Vector2 irisRightPosition;
|
||||
private float irisRadius;
|
||||
|
||||
private float angle;
|
||||
private float dx, dy, dxx, dyy;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
scleraLeftPosition = new(GetScreenWidth() / 2.0f - 100.0f, GetScreenHeight() / 2.0f);
|
||||
scleraRightPosition = new(GetScreenWidth() / 2.0f + 100.0f, GetScreenHeight() / 2.0f);
|
||||
scleraRadius = 80;
|
||||
|
||||
irisLeftPosition = new(GetScreenWidth() / 2.0f - 100.0f, GetScreenHeight() / 2.0f);
|
||||
irisRightPosition = new(GetScreenWidth() / 2.0f + 100.0f, GetScreenHeight() / 2.0f);
|
||||
irisRadius = 24;
|
||||
|
||||
angle = 0.0f;
|
||||
dx = 0.0f;
|
||||
dy = 0.0f;
|
||||
dxx = 0.0f;
|
||||
dyy = 0.0f;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
irisLeftPosition = GetMousePosition();
|
||||
irisRightPosition = GetMousePosition();
|
||||
|
||||
// Check not inside the left eye sclera
|
||||
if (!CheckCollisionPointCircle(irisLeftPosition, scleraLeftPosition, scleraRadius - irisRadius))
|
||||
{
|
||||
dx = irisLeftPosition.X - scleraLeftPosition.X;
|
||||
dy = irisLeftPosition.Y - scleraLeftPosition.Y;
|
||||
|
||||
angle = MathF.Atan2(dy, dx);
|
||||
|
||||
dxx = (scleraRadius - irisRadius) * MathF.Cos(angle);
|
||||
dyy = (scleraRadius - irisRadius) * MathF.Sin(angle);
|
||||
|
||||
irisLeftPosition.X = scleraLeftPosition.X + dxx;
|
||||
irisLeftPosition.Y = scleraLeftPosition.Y + dyy;
|
||||
}
|
||||
|
||||
// Check not inside the right eye sclera
|
||||
if (!CheckCollisionPointCircle(irisRightPosition, scleraRightPosition, scleraRadius - irisRadius))
|
||||
{
|
||||
dx = irisRightPosition.X - scleraRightPosition.X;
|
||||
dy = irisRightPosition.Y - scleraRightPosition.Y;
|
||||
|
||||
angle = MathF.Atan2(dy, dx);
|
||||
|
||||
dxx = (scleraRadius - irisRadius) * MathF.Cos(angle);
|
||||
dyy = (scleraRadius - irisRadius) * MathF.Sin(angle);
|
||||
|
||||
irisRightPosition.X = scleraRightPosition.X + dxx;
|
||||
irisRightPosition.Y = scleraRightPosition.Y + dyy;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawCircleV(scleraLeftPosition, scleraRadius, Color.LightGray);
|
||||
DrawCircleV(irisLeftPosition, irisRadius, Color.Brown);
|
||||
DrawCircleV(irisLeftPosition, 10, Color.Black);
|
||||
|
||||
DrawCircleV(scleraRightPosition, scleraRadius, Color.LightGray);
|
||||
DrawCircleV(irisRightPosition, irisRadius, Color.DarkGreen);
|
||||
DrawCircleV(irisRightPosition, 10, Color.Black);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - following eyes");
|
||||
|
||||
Vector2 scleraLeftPosition = new(GetScreenWidth() / 2 - 100, GetScreenHeight() / 2);
|
||||
Vector2 scleraRightPosition = new(GetScreenWidth() / 2 + 100, GetScreenHeight() / 2);
|
||||
float scleraRadius = 80;
|
||||
|
||||
Vector2 irisLeftPosition = new(GetScreenWidth() / 2 - 100, GetScreenHeight() / 2);
|
||||
Vector2 irisRightPosition = new(GetScreenWidth() / 2 + 100, GetScreenHeight() / 2);
|
||||
float irisRadius = 24;
|
||||
|
||||
float angle = 0.0f;
|
||||
float dx = 0.0f, dy = 0.0f, dxx = 0.0f, dyy = 0.0f;
|
||||
|
||||
SetTargetFPS(60);
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new FollowingEyes();
|
||||
game.Init();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
irisLeftPosition = GetMousePosition();
|
||||
irisRightPosition = GetMousePosition();
|
||||
|
||||
// Check not inside the left eye sclera
|
||||
if (!CheckCollisionPointCircle(irisLeftPosition, scleraLeftPosition, scleraRadius - 20))
|
||||
{
|
||||
dx = irisLeftPosition.X - scleraLeftPosition.X;
|
||||
dy = irisLeftPosition.Y - scleraLeftPosition.Y;
|
||||
|
||||
angle = MathF.Atan2(dy, dx);
|
||||
|
||||
dxx = (scleraRadius - irisRadius) * MathF.Cos(angle);
|
||||
dyy = (scleraRadius - irisRadius) * MathF.Sin(angle);
|
||||
|
||||
irisLeftPosition.X = scleraLeftPosition.X + dxx;
|
||||
irisLeftPosition.Y = scleraLeftPosition.Y + dyy;
|
||||
}
|
||||
|
||||
// Check not inside the right eye sclera
|
||||
if (!CheckCollisionPointCircle(irisRightPosition, scleraRightPosition, scleraRadius - 20))
|
||||
{
|
||||
dx = irisRightPosition.X - scleraRightPosition.X;
|
||||
dy = irisRightPosition.Y - scleraRightPosition.Y;
|
||||
|
||||
angle = MathF.Atan2(dy, dx);
|
||||
|
||||
dxx = (scleraRadius - irisRadius) * MathF.Cos(angle);
|
||||
dyy = (scleraRadius - irisRadius) * MathF.Sin(angle);
|
||||
|
||||
irisRightPosition.X = scleraRightPosition.X + dxx;
|
||||
irisRightPosition.Y = scleraRightPosition.Y + dyy;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawCircleV(scleraLeftPosition, scleraRadius, Color.LightGray);
|
||||
DrawCircleV(irisLeftPosition, irisRadius, Color.Brown);
|
||||
DrawCircleV(irisLeftPosition, 10, Color.Black);
|
||||
|
||||
DrawCircleV(scleraRightPosition, scleraRadius, Color.LightGray);
|
||||
DrawCircleV(irisRightPosition, irisRadius, Color.DarkGreen);
|
||||
DrawCircleV(irisRightPosition, 10, Color.Black);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
game.Update();
|
||||
}
|
||||
|
||||
game.Unload();
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
270
Examples/Shapes/HilbertCurve.cs
Normal file
270
Examples/Shapes/HilbertCurve.cs
Normal file
|
|
@ -0,0 +1,270 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shapes] example - hilbert curve
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||
*
|
||||
* Example contributed by Hamza RAHAL (@hmz-rhl) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* 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) 2025 Hamza RAHAL (@hmz-rhl)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Shapes;
|
||||
|
||||
public partial class HilbertCurve : IExample
|
||||
{
|
||||
private const int screenWidth = 800;
|
||||
private const int screenHeight = 450;
|
||||
|
||||
public string Name => "Shapes / Hilbert Curve";
|
||||
|
||||
public string Title => "raylib [shapes] example - hilbert curve";
|
||||
|
||||
private int order;
|
||||
private float size;
|
||||
private int strokeCount;
|
||||
private Vector2[] hilbertPath;
|
||||
|
||||
private int prevOrder;
|
||||
private int prevSize; // NOTE: Size from slider is float but for comparison we use int
|
||||
private int counter;
|
||||
private float thick;
|
||||
private bool animate;
|
||||
|
||||
public void Init()
|
||||
{
|
||||
order = 2;
|
||||
size = (float)GetScreenHeight();
|
||||
strokeCount = 0;
|
||||
hilbertPath = LoadHilbertPath(order, size, out strokeCount);
|
||||
|
||||
prevOrder = order;
|
||||
prevSize = (int)size;
|
||||
counter = 0;
|
||||
thick = 2.0f;
|
||||
animate = true;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Check if order or size have changed to regenerate
|
||||
// NOTE: Size from slider is float but for comparison we use int
|
||||
if ((prevOrder != order) || (prevSize != (int)size))
|
||||
{
|
||||
hilbertPath = LoadHilbertPath(order, size, out strokeCount);
|
||||
|
||||
if (animate) counter = 0;
|
||||
else counter = strokeCount;
|
||||
|
||||
prevOrder = order;
|
||||
prevSize = (int)size;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//--------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
if (counter < strokeCount)
|
||||
{
|
||||
// Draw Hilbert path animation, one stroke every frame
|
||||
for (int i = 1; i <= counter; i++)
|
||||
{
|
||||
DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i / strokeCount) * 360.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
counter += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw full Hilbert path
|
||||
for (int i = 1; i < strokeCount; i++)
|
||||
{
|
||||
DrawLineEx(hilbertPath[i], hilbertPath[i - 1], thick, ColorFromHSV(((float)i / strokeCount) * 360.0f, 1.0f, 1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw UI (minimal raygui-like controls, raygui is not bound in raylib-cs)
|
||||
GuiCheckBox(new Rectangle(450, 50, 20, 20), "ANIMATE GENERATION ON CHANGE", ref animate);
|
||||
GuiSpinner(new Rectangle(585, 100, 180, 30), "HILBERT CURVE ORDER: ", ref order, 2, 8);
|
||||
GuiSlider(new Rectangle(524, 150, 240, 24), "THICKNESS: ", null, ref thick, 1.0f, 10.0f);
|
||||
GuiSlider(new Rectangle(524, 190, 240, 24), "TOTAL SIZE: ", null, ref size, 10.0f, GetScreenHeight() * 1.5f);
|
||||
|
||||
EndDrawing();
|
||||
//--------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//------------------------------------------------------------------------------------
|
||||
// Load the whole Hilbert Path (including each U and their link)
|
||||
private static Vector2[] LoadHilbertPath(int order, float size, out int strokeCount)
|
||||
{
|
||||
int N = 1 << order;
|
||||
float len = size / N;
|
||||
strokeCount = N * N;
|
||||
|
||||
Vector2[] hilbertPath = new Vector2[strokeCount];
|
||||
|
||||
for (int i = 0; i < strokeCount; i++)
|
||||
{
|
||||
hilbertPath[i] = ComputeHilbertStep(order, i);
|
||||
hilbertPath[i].X = hilbertPath[i].X * len + len / 2.0f;
|
||||
hilbertPath[i].Y = hilbertPath[i].Y * len + len / 2.0f;
|
||||
}
|
||||
|
||||
return hilbertPath;
|
||||
}
|
||||
|
||||
// Compute Hilbert path U positions
|
||||
private static Vector2 ComputeHilbertStep(int order, int index)
|
||||
{
|
||||
// Hilbert points base pattern
|
||||
Vector2[] hilbertPoints = new Vector2[4]
|
||||
{
|
||||
new Vector2(0, 0),
|
||||
new Vector2(0, 1),
|
||||
new Vector2(1, 1),
|
||||
new Vector2(1, 0),
|
||||
};
|
||||
|
||||
int hilbertIndex = index & 3;
|
||||
Vector2 vect = hilbertPoints[hilbertIndex];
|
||||
float temp = 0.0f;
|
||||
int len = 0;
|
||||
|
||||
for (int j = 1; j < order; j++)
|
||||
{
|
||||
index = index >> 2;
|
||||
hilbertIndex = index & 3;
|
||||
len = 1 << j;
|
||||
|
||||
switch (hilbertIndex)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
temp = vect.X;
|
||||
vect.X = vect.Y;
|
||||
vect.Y = temp;
|
||||
} break;
|
||||
case 2:
|
||||
{
|
||||
vect.X += len;
|
||||
vect.Y += len;
|
||||
} break;
|
||||
case 1: vect.Y += len; break;
|
||||
case 3:
|
||||
{
|
||||
temp = len - 1 - vect.X;
|
||||
vect.X = 2 * len - 1 - vect.Y;
|
||||
vect.Y = temp;
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
return vect;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Minimal raygui-like widgets (plain raylib re-implementation)
|
||||
//----------------------------------------------------------------------------------
|
||||
private static void GuiCheckBox(Rectangle bounds, string text, ref bool active)
|
||||
{
|
||||
Vector2 mouse = GetMousePosition();
|
||||
bool hover = CheckCollisionPointRec(mouse, bounds);
|
||||
if (hover && IsMouseButtonPressed(MouseButton.Left)) active = !active;
|
||||
|
||||
DrawRectangleLinesEx(bounds, 1, hover ? Color.DarkBlue : Color.Gray);
|
||||
if (active) DrawRectangle((int)bounds.X + 4, (int)bounds.Y + 4, (int)bounds.Width - 8, (int)bounds.Height - 8, Color.DarkGray);
|
||||
if (text != null) DrawText(text, (int)(bounds.X + bounds.Width + 8), (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
}
|
||||
|
||||
private static void GuiSpinner(Rectangle bounds, string text, ref int value, int minValue, int maxValue)
|
||||
{
|
||||
Vector2 mouse = GetMousePosition();
|
||||
Rectangle left = new Rectangle(bounds.X, bounds.Y, bounds.Height, bounds.Height);
|
||||
Rectangle right = new Rectangle(bounds.X + bounds.Width - bounds.Height, bounds.Y, bounds.Height, bounds.Height);
|
||||
Rectangle mid = new Rectangle(bounds.X + bounds.Height, bounds.Y, bounds.Width - 2 * bounds.Height, bounds.Height);
|
||||
|
||||
if (CheckCollisionPointRec(mouse, left) && IsMouseButtonPressed(MouseButton.Left) && value > minValue) value--;
|
||||
if (CheckCollisionPointRec(mouse, right) && IsMouseButtonPressed(MouseButton.Left) && value < maxValue) value++;
|
||||
|
||||
DrawRectangleRec(mid, Color.RayWhite);
|
||||
DrawRectangleLinesEx(mid, 1, Color.Gray);
|
||||
DrawRectangleRec(left, Color.LightGray);
|
||||
DrawRectangleLinesEx(left, 1, Color.Gray);
|
||||
DrawRectangleRec(right, Color.LightGray);
|
||||
DrawRectangleLinesEx(right, 1, Color.Gray);
|
||||
DrawText("-", (int)(left.X + left.Width / 2 - 2), (int)(left.Y + left.Height / 2 - 5), 10, Color.DarkGray);
|
||||
DrawText("+", (int)(right.X + right.Width / 2 - 3), (int)(right.Y + right.Height / 2 - 5), 10, Color.DarkGray);
|
||||
string vs = value.ToString();
|
||||
DrawText(vs, (int)(mid.X + mid.Width / 2 - MeasureText(vs, 10) / 2), (int)(mid.Y + mid.Height / 2 - 5), 10, Color.DarkGray);
|
||||
if (text != null) DrawText(text, (int)bounds.X - MeasureText(text, 10) - 5, (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
}
|
||||
|
||||
private static void GuiSlider(Rectangle bounds, string textLeft, string textRight, ref float value, float minValue, float maxValue)
|
||||
{
|
||||
Vector2 mouse = GetMousePosition();
|
||||
bool hover = CheckCollisionPointRec(mouse, bounds);
|
||||
if (hover && IsMouseButtonDown(MouseButton.Left))
|
||||
{
|
||||
value = minValue + ((mouse.X - bounds.X) / bounds.Width) * (maxValue - minValue);
|
||||
if (value < minValue) value = minValue;
|
||||
if (value > maxValue) value = maxValue;
|
||||
}
|
||||
|
||||
DrawRectangleRec(bounds, Color.LightGray);
|
||||
float pct = (value - minValue) / (maxValue - minValue);
|
||||
float handleX = bounds.X + pct * bounds.Width;
|
||||
DrawRectangle((int)(handleX - 5), (int)bounds.Y, 10, (int)bounds.Height, Color.DarkGray);
|
||||
DrawRectangleLinesEx(bounds, 1, Color.Gray);
|
||||
if (textLeft != null) DrawText(textLeft, (int)bounds.X - MeasureText(textLeft, 10) - 5, (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
if (textRight != null) DrawText(textRight, (int)(bounds.X + bounds.Width + 5), (int)(bounds.Y + bounds.Height / 2 - 5), 10, Color.DarkGray);
|
||||
}
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - hilbert curve");
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
var game = new HilbertCurve();
|
||||
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;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue