Watch
2
0
Fork
You've already forked raylib-cs
0
raylib-cs/Examples/Shapes/EasingsTestbed.cs

230 lines
8.6 KiB
C#

/*******************************************************************************************
*
* 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;
}
}