Added severial examples. Corrected towards the correct return type and add utilities to prevent working with pointers
This commit is contained in:
parent
2a86968da0
commit
6c94ffb0cc
21 changed files with 1252 additions and 205 deletions
|
|
@ -1,21 +1,28 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Basic window
|
||||
* raylib [core] example - basic window
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Welcome to raylib!
|
||||
*
|
||||
* To test examples, just press F6 and execute raylib_compile_execute script
|
||||
* To test examples, just press F6 and execute 'raylib_compile_execute' script
|
||||
* Note that compiled executable is placed in the same folder as .c file
|
||||
*
|
||||
* To test the examples on Web, press F6 and execute 'raylib_compile_execute_web' script
|
||||
* Web version of the program is generated in the same folder as .c file
|
||||
*
|
||||
* You can find all basic examples on C:\raylib\raylib\examples folder or
|
||||
* raylib official webpage: www.raylib.com
|
||||
*
|
||||
* Enjoy using raylib. :)
|
||||
*
|
||||
* 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 originally created with raylib 1.0, last time updated with raylib 1.0
|
||||
*
|
||||
* Copyright (c) 2013-2016 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) 2013-2026 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -53,7 +60,7 @@ public class BasicWindow
|
|||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
DrawText("Congrats! You created your first window!", 190, 200, 20, Color.Maroon);
|
||||
DrawText("Congrats! You created your first window!", 190, 200, 20, Color.LightGray);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@
|
|||
*
|
||||
* raylib [core] example - 2d camera
|
||||
*
|
||||
* This example has been created using raylib 1.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) 2016 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 1.5, last time updated with raylib 3.0
|
||||
*
|
||||
* 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) 2016-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public unsafe class CustomLogging
|
|||
|
||||
// First thing we do is setting our custom logger to ensure everything raylib logs
|
||||
// will use our own logger instead of its internal one
|
||||
Raylib.SetTraceLogCallback(&LogCustom);
|
||||
SetTraceLogCallback(&LogCustom);
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - custom logging");
|
||||
|
||||
|
|
@ -79,7 +79,7 @@ public unsafe class CustomLogging
|
|||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
Raylib.SetTraceLogCallback(&Logging.LogConsole);
|
||||
SetTraceLogCallback(&Logging.LogConsole);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
129
Examples/Core/DeltaTime.cs
Normal file
129
Examples/Core/DeltaTime.cs
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
using System.Numerics;
|
||||
|
||||
namespace Examples.Core;
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - delta time
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 5.5, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Robin (@RobinsAviary) 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 Robin (@RobinsAviary)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
public class DeltaTime
|
||||
{
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - delta time");
|
||||
|
||||
int currentFps = 60;
|
||||
|
||||
Vector2 deltaCircle = new Vector2(0, (float)screenHeight / 3.0f);
|
||||
Vector2 frameCircle = new Vector2(0, (float)screenHeight * (2.0f / 3.0f));
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
const float speed = 10.0f;
|
||||
const float circleRadius = 32.0f;
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Adjust the FPS target based on the mouse wheel
|
||||
float mouseWheel = GetMouseWheelMove();
|
||||
if (mouseWheel != 0)
|
||||
{
|
||||
currentFps += (int)mouseWheel;
|
||||
if (currentFps < 0)
|
||||
{
|
||||
currentFps = 0;
|
||||
}
|
||||
SetTargetFPS(currentFps);
|
||||
}
|
||||
|
||||
// GetFrameTime() returns the time it took to draw the last frame, in seconds (usually called delta time)
|
||||
// Uses the delta time to make the circle look like it's moving at a "consistent" speed regardless of FPS
|
||||
|
||||
// Multiply by 6.0 (an arbitrary value) in order to make the speed
|
||||
// visually closer to the other circle (at 60 fps), for comparison
|
||||
deltaCircle.X += GetFrameTime() * 6.0f * speed;
|
||||
// This circle can move faster or slower visually depending on the FPS
|
||||
frameCircle.X += 0.1f * speed;
|
||||
|
||||
// If either circle is off the screen, reset it back to the start
|
||||
if (deltaCircle.X > screenWidth)
|
||||
{
|
||||
deltaCircle.X = 0;
|
||||
}
|
||||
|
||||
if (frameCircle.X > screenWidth)
|
||||
{
|
||||
frameCircle.X = 0;
|
||||
}
|
||||
|
||||
// Reset both circles positions
|
||||
if (IsKeyPressed(KeyboardKey.R))
|
||||
{
|
||||
deltaCircle.X = 0;
|
||||
frameCircle.X = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw both circles to the screen
|
||||
DrawCircleV(deltaCircle, circleRadius, Color.Red);
|
||||
DrawCircleV(frameCircle, circleRadius, Color.Blue);
|
||||
|
||||
// Draw the help text
|
||||
// Determine what help text to show depending on the current FPS target
|
||||
var fpsText = "";
|
||||
if (currentFps <= 0)
|
||||
{
|
||||
fpsText = $"FPS: unlimited ({GetFPS()})";
|
||||
}
|
||||
else
|
||||
{
|
||||
fpsText = $"FPS: {GetFPS()} (target: {currentFps})";
|
||||
}
|
||||
DrawText(fpsText, 10, 10, 20, Color.DarkGray);
|
||||
DrawText($"Frame time: {GetFrameTime():F2} ms", 10, 30, 20, Color.DarkGray);
|
||||
DrawText("Use the scroll wheel to change the fps limit, r to reset", 10, 50, 20, Color.DarkGray);
|
||||
|
||||
// Draw the text above the circles
|
||||
DrawText("FUNC: x += GetFrameTime()*speed", 10, 90, 20, Color.Red);
|
||||
DrawText("FUNC: x += speed", 10, 240, 20, Color.Blue);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +1,24 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Gamepad input
|
||||
*
|
||||
* NOTE: This example requires a Gamepad connected to the system
|
||||
* raylib is configured to work with the following gamepads:
|
||||
* - Xbox 360 Controller (Xbox 360, Xbox One)
|
||||
* - PLAYSTATION(R)3 Controller
|
||||
* Check raylib.h for buttons configuration
|
||||
*
|
||||
* This example has been created using raylib 1.6 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
*
|
||||
* raylib [core] example - input gamepad
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* NOTE: This example requires a Gamepad connected to the system
|
||||
* raylib is configured to work with the following gamepads:
|
||||
* - Xbox 360 Controller (Xbox 360, Xbox One)
|
||||
* - PLAYSTATION(R)3 Controller
|
||||
* Check raylib.h for buttons configuration
|
||||
*
|
||||
* Example originally created with raylib 1.1, 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) 2013-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
||||
using System.Numerics;
|
||||
using Raylib_cs;
|
||||
|
|
@ -25,10 +30,10 @@ public class InputGamepad
|
|||
{
|
||||
// NOTE: Gamepad name ID depends on drivers and OS
|
||||
// These are some possible names the gamepads could have.
|
||||
public const string XBOX360_LEGACY_NAME_ID = "Xbox Controller";
|
||||
public const string XBOX360_NAME_ID = "Xbox 360 Controller";
|
||||
public const string XBOX360_NAME_ID_RPI = "Microsoft X-Box 360 pad";
|
||||
public const string PS3_NAME_ID = "PLAYSTATION(R)3 Controller";
|
||||
public const string XBOX_ALIAS_1 = "xbox";
|
||||
public const string XBOX_ALIAS_2 = "x-box";
|
||||
public const string PS_ALIAS_1 = "playstation";
|
||||
public const string PS_ALIAS_2 = "sony";
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
|
|
@ -47,12 +52,32 @@ public class InputGamepad
|
|||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
int gamepad = 0;
|
||||
Rectangle vibrateButton = new Rectangle();
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// ...
|
||||
if (IsKeyPressed(KeyboardKey.Left) && gamepad > 0)
|
||||
{
|
||||
gamepad--;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.Right))
|
||||
{
|
||||
gamepad++;
|
||||
}
|
||||
|
||||
Vector2 mousePosition = GetMousePosition();
|
||||
|
||||
vibrateButton = new Rectangle(10, 70.0f + 20 * GetGamepadAxisCount(gamepad) + 20, 75, 24);
|
||||
if (IsMouseButtonPressed(MouseButton.Left) && CheckCollisionPointRec(mousePosition, vibrateButton))
|
||||
{
|
||||
SetGamepadVibration(gamepad, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
|
@ -60,50 +85,49 @@ public class InputGamepad
|
|||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
if (IsGamepadAvailable(0))
|
||||
if (IsGamepadAvailable(gamepad))
|
||||
{
|
||||
string gamepadName = GetGamepadName_(0);
|
||||
DrawText($"GP1: {gamepadName}", 10, 10, 10, Color.Black);
|
||||
string gamepadName = GetGamepadName_(gamepad);
|
||||
DrawText($"GP{gamepad}: {gamepadName}", 10, 10, 10, Color.Black);
|
||||
|
||||
if (gamepadName == XBOX360_LEGACY_NAME_ID ||
|
||||
gamepadName == XBOX360_NAME_ID ||
|
||||
gamepadName == XBOX360_NAME_ID_RPI)
|
||||
if (gamepadName.Contains(XBOX_ALIAS_1, StringComparison.OrdinalIgnoreCase)||
|
||||
gamepadName.Contains(XBOX_ALIAS_2, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
DrawTexture(texXboxPad, 0, 0, Color.DarkGray);
|
||||
|
||||
// Draw buttons: xbox home
|
||||
if (IsGamepadButtonDown(0, GamepadButton.Middle))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.Middle))
|
||||
{
|
||||
DrawCircle(394, 89, 19, Color.Red);
|
||||
}
|
||||
|
||||
// Draw buttons: basic
|
||||
if (IsGamepadButtonDown(0, GamepadButton.MiddleRight))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.MiddleRight))
|
||||
{
|
||||
DrawCircle(436, 150, 9, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.MiddleLeft))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.MiddleLeft))
|
||||
{
|
||||
DrawCircle(352, 150, 9, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.RightFaceLeft))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceLeft))
|
||||
{
|
||||
DrawCircle(501, 151, 15, Color.Blue);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.RightFaceDown))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceDown))
|
||||
{
|
||||
DrawCircle(536, 187, 15, Color.Lime);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.RightFaceRight))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceRight))
|
||||
{
|
||||
DrawCircle(572, 151, 15, Color.Maroon);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.RightFaceUp))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceUp))
|
||||
{
|
||||
DrawCircle(536, 115, 15, Color.Gold);
|
||||
}
|
||||
|
|
@ -111,33 +135,33 @@ public class InputGamepad
|
|||
// Draw buttons: d-pad
|
||||
DrawRectangle(317, 202, 19, 71, Color.Black);
|
||||
DrawRectangle(293, 228, 69, 19, Color.Black);
|
||||
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceUp))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceUp))
|
||||
{
|
||||
DrawRectangle(317, 202, 19, 26, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceDown))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceDown))
|
||||
{
|
||||
DrawRectangle(317, 202 + 45, 19, 26, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceLeft))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceLeft))
|
||||
{
|
||||
DrawRectangle(292, 228, 25, 19, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceRight))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceRight))
|
||||
{
|
||||
DrawRectangle(292 + 44, 228, 26, 19, Color.Red);
|
||||
}
|
||||
|
||||
// Draw buttons: left-right back
|
||||
if (IsGamepadButtonDown(0, GamepadButton.LeftTrigger1))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.LeftTrigger1))
|
||||
{
|
||||
DrawCircle(259, 61, 20, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.RightTrigger1))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.RightTrigger1))
|
||||
{
|
||||
DrawCircle(536, 61, 20, Color.Red);
|
||||
}
|
||||
|
|
@ -146,8 +170,8 @@ public class InputGamepad
|
|||
DrawCircle(259, 152, 39, Color.Black);
|
||||
DrawCircle(259, 152, 34, Color.LightGray);
|
||||
DrawCircle(
|
||||
259 + (int)(GetGamepadAxisMovement(0, GamepadAxis.LeftX) * 20),
|
||||
152 + (int)(GetGamepadAxisMovement(0, GamepadAxis.LeftY) * 20),
|
||||
259 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.LeftX) * 20),
|
||||
152 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.LeftY) * 20),
|
||||
25,
|
||||
Color.Black
|
||||
);
|
||||
|
|
@ -156,36 +180,36 @@ public class InputGamepad
|
|||
DrawCircle(461, 237, 38, Color.Black);
|
||||
DrawCircle(461, 237, 33, Color.LightGray);
|
||||
DrawCircle(
|
||||
461 + (int)(GetGamepadAxisMovement(0, GamepadAxis.RightX) * 20),
|
||||
237 + (int)(GetGamepadAxisMovement(0, GamepadAxis.RightY) * 20),
|
||||
461 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.RightX) * 20),
|
||||
237 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.RightY) * 20),
|
||||
25, Color.Black
|
||||
);
|
||||
|
||||
// Draw axis: left-right triggers
|
||||
float leftTriggerX = GetGamepadAxisMovement(0, GamepadAxis.LeftTrigger);
|
||||
float rightTriggerX = GetGamepadAxisMovement(0, GamepadAxis.RightTrigger);
|
||||
float leftTriggerX = GetGamepadAxisMovement(gamepad, GamepadAxis.LeftTrigger);
|
||||
float rightTriggerX = GetGamepadAxisMovement(gamepad, GamepadAxis.RightTrigger);
|
||||
DrawRectangle(170, 30, 15, 70, Color.Gray);
|
||||
DrawRectangle(604, 30, 15, 70, Color.Gray);
|
||||
DrawRectangle(170, 30, 15, (int)(((1.0f + leftTriggerX) / 2.0f) * 70), Color.Red);
|
||||
DrawRectangle(604, 30, 15, (int)(((1.0f + rightTriggerX) / 2.0f) * 70), Color.Red);
|
||||
}
|
||||
else if (gamepadName == PS3_NAME_ID)
|
||||
else if (gamepadName.Contains(PS_ALIAS_1, StringComparison.OrdinalIgnoreCase) || gamepadName.Contains(PS_ALIAS_2, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
DrawTexture(texPs3Pad, 0, 0, Color.DarkGray);
|
||||
|
||||
// Draw buttons: ps
|
||||
if (IsGamepadButtonDown(0, GamepadButton.Middle))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.Middle))
|
||||
{
|
||||
DrawCircle(396, 222, 13, Color.Red);
|
||||
}
|
||||
|
||||
// Draw buttons: basic
|
||||
if (IsGamepadButtonDown(0, GamepadButton.MiddleLeft))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.MiddleLeft))
|
||||
{
|
||||
DrawRectangle(328, 170, 32, 13, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.MiddleRight))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.MiddleRight))
|
||||
{
|
||||
DrawTriangle(
|
||||
new Vector2(436, 168),
|
||||
|
|
@ -195,22 +219,22 @@ public class InputGamepad
|
|||
);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.RightFaceUp))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceUp))
|
||||
{
|
||||
DrawCircle(557, 144, 13, Color.Lime);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.RightFaceRight))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceRight))
|
||||
{
|
||||
DrawCircle(586, 173, 13, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.RightFaceDown))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceDown))
|
||||
{
|
||||
DrawCircle(557, 203, 13, Color.Violet);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.RightFaceLeft))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.RightFaceLeft))
|
||||
{
|
||||
DrawCircle(527, 173, 13, Color.Pink);
|
||||
}
|
||||
|
|
@ -218,33 +242,33 @@ public class InputGamepad
|
|||
// Draw buttons: d-pad
|
||||
DrawRectangle(225, 132, 24, 84, Color.Black);
|
||||
DrawRectangle(195, 161, 84, 25, Color.Black);
|
||||
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceUp))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceUp))
|
||||
{
|
||||
DrawRectangle(225, 132, 24, 29, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceDown))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceDown))
|
||||
{
|
||||
DrawRectangle(225, 132 + 54, 24, 30, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceLeft))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceLeft))
|
||||
{
|
||||
DrawRectangle(195, 161, 30, 25, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.LeftFaceRight))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.LeftFaceRight))
|
||||
{
|
||||
DrawRectangle(195 + 54, 161, 30, 25, Color.Red);
|
||||
}
|
||||
|
||||
// Draw buttons: left-right back buttons
|
||||
if (IsGamepadButtonDown(0, GamepadButton.LeftTrigger1))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.LeftTrigger1))
|
||||
{
|
||||
DrawCircle(239, 82, 20, Color.Red);
|
||||
}
|
||||
|
||||
if (IsGamepadButtonDown(0, GamepadButton.RightTrigger1))
|
||||
if (IsGamepadButtonDown(gamepad, GamepadButton.RightTrigger1))
|
||||
{
|
||||
DrawCircle(557, 82, 20, Color.Red);
|
||||
}
|
||||
|
|
@ -253,8 +277,8 @@ public class InputGamepad
|
|||
DrawCircle(319, 255, 35, Color.Black);
|
||||
DrawCircle(319, 255, 31, Color.LightGray);
|
||||
DrawCircle(
|
||||
319 + (int)(GetGamepadAxisMovement(0, GamepadAxis.LeftX) * 20),
|
||||
255 + (int)(GetGamepadAxisMovement(0, GamepadAxis.LeftY) * 20),
|
||||
319 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.LeftX) * 20),
|
||||
255 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.LeftY) * 20),
|
||||
25,
|
||||
Color.Black
|
||||
);
|
||||
|
|
@ -263,15 +287,15 @@ public class InputGamepad
|
|||
DrawCircle(475, 255, 35, Color.Black);
|
||||
DrawCircle(475, 255, 31, Color.LightGray);
|
||||
DrawCircle(
|
||||
475 + (int)(GetGamepadAxisMovement(0, GamepadAxis.RightX) * 20),
|
||||
255 + (int)(GetGamepadAxisMovement(0, GamepadAxis.RightY) * 20),
|
||||
475 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.RightX) * 20),
|
||||
255 + (int)(GetGamepadAxisMovement(gamepad, GamepadAxis.RightY) * 20),
|
||||
25,
|
||||
Color.Black
|
||||
);
|
||||
|
||||
// Draw axis: left-right triggers
|
||||
float leftTriggerX = GetGamepadAxisMovement(0, GamepadAxis.LeftTrigger);
|
||||
float rightTriggerX = GetGamepadAxisMovement(0, GamepadAxis.RightTrigger);
|
||||
float leftTriggerX = GetGamepadAxisMovement(gamepad, GamepadAxis.LeftTrigger);
|
||||
float rightTriggerX = GetGamepadAxisMovement(gamepad, GamepadAxis.RightTrigger);
|
||||
DrawRectangle(169, 48, 15, 70, Color.Gray);
|
||||
DrawRectangle(611, 48, 15, 70, Color.Gray);
|
||||
DrawRectangle(169, 48, 15, (int)(((1.0f - leftTriggerX) / 2.0f) * 70), Color.Red);
|
||||
|
|
@ -283,12 +307,12 @@ public class InputGamepad
|
|||
// TODO: Draw generic gamepad
|
||||
}
|
||||
|
||||
DrawText($"DETECTED AXIS [{GetGamepadAxisCount(0)}]:", 10, 50, 10, Color.Maroon);
|
||||
DrawText($"DETECTED AXIS [{GetGamepadAxisCount(gamepad)}]:", 10, 50, 10, Color.Maroon);
|
||||
|
||||
for (int i = 0; i < GetGamepadAxisCount(0); i++)
|
||||
for (int i = 0; i < GetGamepadAxisCount(gamepad); i++)
|
||||
{
|
||||
DrawText(
|
||||
$"AXIS {i}: {GetGamepadAxisMovement(0, (GamepadAxis)i)}",
|
||||
$"AXIS {i}: {GetGamepadAxisMovement(gamepad, (GamepadAxis)i)}",
|
||||
20,
|
||||
70 + 20 * i,
|
||||
10,
|
||||
|
|
@ -296,6 +320,10 @@ public class InputGamepad
|
|||
);
|
||||
}
|
||||
|
||||
DrawRectangleRec(vibrateButton, Color.SkyBlue);
|
||||
DrawText("VIBRATE", (int)(vibrateButton.X + 14), (int)(vibrateButton.Y + 1), 10, Color.DarkGray);
|
||||
|
||||
|
||||
if (GetGamepadButtonPressed() != (int)GamepadButton.Unknown)
|
||||
{
|
||||
DrawText($"DETECTED BUTTON: {GetGamepadButtonPressed()}", 10, 430, 10, Color.Red);
|
||||
|
|
@ -307,7 +335,7 @@ public class InputGamepad
|
|||
}
|
||||
else
|
||||
{
|
||||
DrawText("GP1: NOT DETECTED", 10, 10, 10, Color.Gray);
|
||||
DrawText($"GP{gamepad}: NOT DETECTED", 10, 10, 10, Color.Gray);
|
||||
DrawTexture(texXboxPad, 0, 0, Color.LightGray);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Gestures Detection
|
||||
* raylib [core] example - input gestures
|
||||
*
|
||||
* This example has been created using raylib 1.4 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Copyright (c) 2016 Ramon Santamaria (@raysan5)
|
||||
* Example originally created with raylib 1.4, 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) 2016-2025 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -25,7 +29,7 @@ public class InputGestures
|
|||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - gestures detection");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - input gestures");
|
||||
|
||||
Vector2 touchPosition = new(0, 0);
|
||||
Rectangle touchArea = new(220, 10, screenWidth - 230, screenHeight - 20);
|
||||
|
|
|
|||
434
Examples/Core/InputGesturesTestBed.cs
Normal file
434
Examples/Core/InputGesturesTestBed.cs
Normal file
|
|
@ -0,0 +1,434 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - input gestures testbed
|
||||
*
|
||||
* Example complexity rating: [★★★☆] 3/4
|
||||
*
|
||||
* Example originally created with raylib 5.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by ubkp (@ubkp) 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) 2023-2025 ubkp (@ubkp)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
|
||||
namespace Examples.Core;
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
public class InputGesturesTestBed
|
||||
{
|
||||
public const int GESTURE_LOG_SIZE = 20;
|
||||
public const int MAX_TOUCH_COUNT = 32;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - input gestures testbed");
|
||||
|
||||
Vector2 messagePosition = new Vector2( 160, 7 );
|
||||
|
||||
// Last gesture variables definitions
|
||||
Gesture lastGesture = 0;
|
||||
Vector2 lastGesturePosition = new Vector2( 165, 130 );
|
||||
|
||||
// Gesture log variables definitions
|
||||
// NOTE: The gesture log uses an array (as an inverted circular queue) to store the performed gestures
|
||||
string[] gestureLog = new string[GESTURE_LOG_SIZE + 1];
|
||||
for (int i= 0; i < GESTURE_LOG_SIZE; i++)
|
||||
{
|
||||
gestureLog[i] = new string(new char[12]);
|
||||
}
|
||||
;
|
||||
// NOTE: The index for the inverted circular queue (moving from last to first direction, then looping around)
|
||||
int gestureLogIndex = GESTURE_LOG_SIZE;
|
||||
Gesture previousGesture = 0;
|
||||
|
||||
// Log mode values:
|
||||
// - 0 shows repeated events
|
||||
// - 1 hides repeated events
|
||||
// - 2 shows repeated events but hide hold events
|
||||
// - 3 hides repeated events and hide hold events
|
||||
int logMode = 1;
|
||||
|
||||
Color gestureColor = new Color(0, 0, 0, 255 );
|
||||
Rectangle logButton1 = new Rectangle( 53, 7, 48, 26 );
|
||||
Rectangle logButton2 = new Rectangle( 108, 7, 36, 26 );
|
||||
Vector2 gestureLogPosition = new Vector2( 10, 10 );
|
||||
|
||||
// Protractor variables definitions
|
||||
float angleLength = 90.0f;
|
||||
float currentAngleDegrees = 0.0f;
|
||||
Vector2 finalVector = new Vector2( 0.0f, 0.0f );
|
||||
Vector2 protractorPosition = new Vector2( 266.0f, 315.0f );
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Handle common gestures data
|
||||
int i, ii; // Iterators that will be reused by all for loops
|
||||
Gesture currentGesture = GetGestureDetected();
|
||||
float currentDragDegrees = GetGestureDragAngle();
|
||||
float currentPitchDegrees = GetGesturePinchAngle();
|
||||
int touchCount = GetTouchPointCount();
|
||||
|
||||
// Handle last gesture
|
||||
if ((currentGesture != 0) && ((int)currentGesture != 4) && (currentGesture != previousGesture))
|
||||
{
|
||||
lastGesture = currentGesture; // Filter the meaningful gestures (1, 2, 8 to 512) for the display
|
||||
}
|
||||
|
||||
// Handle gesture log
|
||||
if (IsMouseButtonReleased(MouseButton.Left))
|
||||
{
|
||||
if (CheckCollisionPointRec(GetMousePosition(), logButton1))
|
||||
{
|
||||
switch (logMode)
|
||||
{
|
||||
case 3: logMode = 2; break;
|
||||
case 2: logMode = 3; break;
|
||||
case 1: logMode = 0; break;
|
||||
default: logMode = 1; break;
|
||||
}
|
||||
}
|
||||
else if (CheckCollisionPointRec(GetMousePosition(), logButton2))
|
||||
{
|
||||
switch (logMode)
|
||||
{
|
||||
case 3: logMode = 1; break;
|
||||
case 2: logMode = 0; break;
|
||||
case 1: logMode = 3; break;
|
||||
default: logMode = 2; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int fillLog = 0; // Gate variable to be used to allow or not the gesture log to be filled
|
||||
if (currentGesture != 0)
|
||||
{
|
||||
if (logMode == 3) // 3 hides repeated events and hide hold events
|
||||
{
|
||||
if ((((int)currentGesture != 4) && (currentGesture != previousGesture)) || ((int)currentGesture < 3))
|
||||
{
|
||||
fillLog = 1;
|
||||
}
|
||||
}
|
||||
else if (logMode == 2) // 2 shows repeated events but hide hold events
|
||||
{
|
||||
if ((int)currentGesture != 4)
|
||||
{
|
||||
fillLog = 1;
|
||||
}
|
||||
}
|
||||
else if (logMode == 1) // 1 hides repeated events
|
||||
{
|
||||
if (currentGesture != previousGesture)
|
||||
{
|
||||
fillLog = 1;
|
||||
}
|
||||
}
|
||||
else // 0 shows repeated events
|
||||
{
|
||||
fillLog = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (fillLog > 0) // If one of the conditions from logMode was met, fill the gesture log
|
||||
{
|
||||
previousGesture = currentGesture;
|
||||
gestureColor = GetGestureColor((int)currentGesture);
|
||||
if (gestureLogIndex <= 0)
|
||||
{
|
||||
gestureLogIndex = GESTURE_LOG_SIZE;
|
||||
}
|
||||
gestureLogIndex--;
|
||||
|
||||
// Copy the gesture respective name to the gesture log array
|
||||
gestureLog[gestureLogIndex] = GetGestureName((int)currentGesture);
|
||||
}
|
||||
|
||||
// Handle protractor
|
||||
if ((int)currentGesture > 255)
|
||||
{
|
||||
currentAngleDegrees = currentPitchDegrees; // Pinch In and Pinch Out
|
||||
}
|
||||
else if ((int)currentGesture > 15)
|
||||
{
|
||||
currentAngleDegrees = currentDragDegrees; // Swipe Right, Swipe Left, Swipe Up and Swipe Down
|
||||
}
|
||||
else if (currentGesture > 0)
|
||||
{
|
||||
currentAngleDegrees = 0.0f; // Tap, Doubletap, Hold and Grab
|
||||
}
|
||||
|
||||
float currentAngleRadians =
|
||||
((currentAngleDegrees + 90.0f) * MathF.PI / 180); // Convert the current angle to Radians
|
||||
// Calculate the final vector for display
|
||||
finalVector = new Vector2(
|
||||
(angleLength * MathF.Sin(currentAngleRadians)) + protractorPosition.X,
|
||||
(angleLength * MathF.Cos(currentAngleRadians)) + protractorPosition.Y
|
||||
)
|
||||
;
|
||||
|
||||
// Handle touch and mouse pointer points
|
||||
Vector2[] touchPosition = new Vector2[MAX_TOUCH_COUNT];
|
||||
|
||||
Vector2 mousePosition = Vector2.Zero;
|
||||
if (currentGesture != Gesture.None)
|
||||
{
|
||||
if (touchCount != 0)
|
||||
{
|
||||
for (i = 0; i < touchCount; i++)
|
||||
{
|
||||
touchPosition[i] = GetTouchPosition(i); // Fill the touch positions
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mousePosition = GetMousePosition();
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//--------------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw common elements
|
||||
DrawText("*", (int)messagePosition.X + 5, (int)messagePosition.Y + 5, 10, Color.Black);
|
||||
DrawText("Example optimized for Web/HTML5\non Smartphones with Touch Screen.", (int)messagePosition.X + 15,
|
||||
(int)messagePosition.Y + 5, 10, Color.Black);
|
||||
DrawText("*", (int)messagePosition.X + 5, (int)messagePosition.Y + 35, 10, Color.Black);
|
||||
DrawText("While running on Desktop Web Browsers,\ninspect and turn on Touch Emulation.",
|
||||
(int)messagePosition.X + 15, (int)messagePosition.Y + 35, 10, Color.Black);
|
||||
|
||||
// Draw last gesture
|
||||
DrawText("Last gesture", (int)lastGesturePosition.X + 33, (int)lastGesturePosition.Y - 47, 20, Color.Black);
|
||||
DrawText("Swipe Tap Pinch Touch", (int)lastGesturePosition.X + 17,
|
||||
(int)lastGesturePosition.Y - 18, 10, Color.Black);
|
||||
DrawRectangle((int)lastGesturePosition.X + 20, (int)lastGesturePosition.Y, 20, 20,
|
||||
lastGesture == Gesture.SwipeUp ? Color.Red : Color.LightGray);
|
||||
DrawRectangle((int)lastGesturePosition.X, (int)lastGesturePosition.Y + 20, 20, 20,
|
||||
lastGesture == Gesture.SwipeLeft ? Color.Red : Color.LightGray);
|
||||
DrawRectangle((int)lastGesturePosition.X + 40, (int)lastGesturePosition.Y + 20, 20, 20,
|
||||
lastGesture == Gesture.SwipeRight ? Color.Red : Color.LightGray);
|
||||
DrawRectangle((int)lastGesturePosition.X + 20, (int)lastGesturePosition.Y + 40, 20, 20,
|
||||
lastGesture == Gesture.SwipeDown ? Color.Red : Color.LightGray);
|
||||
DrawCircle((int)lastGesturePosition.X + 80, (int)lastGesturePosition.Y + 16, 10,
|
||||
lastGesture == Gesture.Tap ? Color.Blue : Color.LightGray);
|
||||
DrawRing(new Vector2(
|
||||
lastGesturePosition.X + 103, lastGesturePosition.Y + 16
|
||||
), 6.0f, 11.0f, 0.0f, 360.0f, 0, lastGesture == Gesture.Drag ? Color.Lime : Color.LightGray);
|
||||
DrawCircle((int)lastGesturePosition.X + 80, (int)lastGesturePosition.Y + 43, 10,
|
||||
lastGesture == Gesture.DoubleTap ? Color.SkyBlue : Color.LightGray);
|
||||
DrawCircle((int)lastGesturePosition.X + 103, (int)lastGesturePosition.Y + 43, 10,
|
||||
lastGesture == Gesture.DoubleTap ? Color.SkyBlue : Color.LightGray);
|
||||
DrawTriangle(new Vector2(
|
||||
lastGesturePosition.X + 122, lastGesturePosition.Y + 16
|
||||
), new Vector2(
|
||||
lastGesturePosition.X + 137, lastGesturePosition.Y + 26
|
||||
), new Vector2(
|
||||
lastGesturePosition.X + 137, lastGesturePosition.Y + 6
|
||||
), lastGesture == Gesture.PinchOut ? Color.Orange : Color.LightGray);
|
||||
DrawTriangle(new Vector2(
|
||||
lastGesturePosition.X + 147, lastGesturePosition.Y + 6
|
||||
), new Vector2(
|
||||
lastGesturePosition.X + 147, lastGesturePosition.Y + 26
|
||||
), new Vector2(
|
||||
lastGesturePosition.X + 162, lastGesturePosition.Y + 16
|
||||
), lastGesture == Gesture.PinchOut ? Color.Orange : Color.Gray);
|
||||
DrawTriangle(new Vector2(
|
||||
lastGesturePosition.X + 125, lastGesturePosition.Y + 33
|
||||
), new Vector2(
|
||||
lastGesturePosition.X + 125, lastGesturePosition.Y + 53
|
||||
), new Vector2(
|
||||
lastGesturePosition.X + 140, lastGesturePosition.Y + 43
|
||||
), lastGesture == Gesture.PinchIn ? Color.Violet : Color.LightGray);
|
||||
DrawTriangle(new Vector2(
|
||||
lastGesturePosition.X + 144, lastGesturePosition.Y + 43
|
||||
), new Vector2(
|
||||
lastGesturePosition.X + 159, lastGesturePosition.Y + 53
|
||||
), new Vector2(
|
||||
lastGesturePosition.X + 159, lastGesturePosition.Y + 33
|
||||
), lastGesture == Gesture.PinchIn ? Color.Violet : Color.LightGray);
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
DrawCircle((int)lastGesturePosition.X + 180, (int)lastGesturePosition.Y + 7 + i * 15, 5,
|
||||
touchCount <= i ? Color.LightGray : gestureColor);
|
||||
}
|
||||
|
||||
// Draw gesture log
|
||||
DrawText("Log", (int)gestureLogPosition.X, (int)gestureLogPosition.Y, 20, Color.Black);
|
||||
|
||||
// Loop in both directions to print the gesture log array in the inverted order (and looping around if the index started somewhere in the middle)
|
||||
for (i = 0, ii = gestureLogIndex; i < GESTURE_LOG_SIZE; i++, ii = (ii + 1) % GESTURE_LOG_SIZE)
|
||||
{
|
||||
DrawText(gestureLog[ii], (int)gestureLogPosition.X, (int)gestureLogPosition.Y + 410 - i * 20, 20,
|
||||
(i == 0 ? gestureColor : Color.LightGray));
|
||||
}
|
||||
|
||||
Color logButton1Color, logButton2Color;
|
||||
switch (logMode)
|
||||
{
|
||||
case 3:
|
||||
logButton1Color = Color.Maroon;
|
||||
logButton2Color = Color.Maroon;
|
||||
break;
|
||||
case 2:
|
||||
logButton1Color = Color.Gray;
|
||||
logButton2Color = Color.Maroon;
|
||||
break;
|
||||
case 1:
|
||||
logButton1Color = Color.Maroon;
|
||||
logButton2Color = Color.Gray;
|
||||
break;
|
||||
default:
|
||||
logButton1Color = Color.Gray;
|
||||
logButton2Color = Color.Gray;
|
||||
break;
|
||||
}
|
||||
|
||||
DrawRectangleRec(logButton1, logButton1Color);
|
||||
DrawText("Hide", (int)logButton1.X + 7, (int)logButton1.Y + 3, 10, Color.White);
|
||||
DrawText("Repeat", (int)logButton1.X + 7, (int)logButton1.Y + 13, 10, Color.White);
|
||||
DrawRectangleRec(logButton2, logButton2Color);
|
||||
DrawText("Hide", (int)logButton1.X + 62, (int)logButton1.Y + 3, 10, Color.White);
|
||||
DrawText("Hold", (int)logButton1.X + 62, (int)logButton1.Y + 13, 10, Color.White);
|
||||
|
||||
// Draw protractor
|
||||
DrawText("Angle", (int)protractorPosition.X + 55, (int)protractorPosition.Y + 76, 10, Color.Black);
|
||||
|
||||
// Note: Official it's using raylibs functions for string manipulation. But in C# it will end up in an unsafe handling.
|
||||
string angleString = currentAngleDegrees.ToString("F3");
|
||||
int angleStringDot = angleString.IndexOf('.');
|
||||
string angleStringTrim = angleString.Substring(0, angleStringDot + 3);
|
||||
|
||||
DrawText(angleStringTrim, (int)protractorPosition.X + 55, (int)protractorPosition.Y + 92, 20, gestureColor);
|
||||
DrawCircleV(protractorPosition, 80.0f, Color.White);
|
||||
DrawLineEx(new Vector2(
|
||||
protractorPosition.X - 90, protractorPosition.Y
|
||||
), new Vector2(
|
||||
protractorPosition.X + 90, protractorPosition.Y
|
||||
), 3.0f, Color.LightGray);
|
||||
DrawLineEx(new Vector2(
|
||||
protractorPosition.X, protractorPosition.Y - 90
|
||||
), new Vector2(
|
||||
protractorPosition.X, protractorPosition.Y + 90
|
||||
), 3.0f, Color.LightGray);
|
||||
DrawLineEx(new Vector2(
|
||||
protractorPosition.X - 80, protractorPosition.Y - 45
|
||||
), new Vector2(
|
||||
protractorPosition.X + 80, protractorPosition.Y + 45
|
||||
), 3.0f, Color.Green);
|
||||
DrawLineEx(new Vector2(
|
||||
protractorPosition.X - 80, protractorPosition.Y + 45
|
||||
), new Vector2(
|
||||
protractorPosition.X + 80, protractorPosition.Y - 45
|
||||
), 3.0f, Color.Green);
|
||||
DrawText("0", (int)protractorPosition.X + 96, (int)protractorPosition.Y - 9, 20, Color.Black);
|
||||
DrawText("30", (int)protractorPosition.X + 74, (int)protractorPosition.Y - 68, 20, Color.Black);
|
||||
DrawText("90", (int)protractorPosition.X - 11, (int)protractorPosition.Y - 110, 20, Color.Black);
|
||||
DrawText("150", (int)protractorPosition.X - 100, (int)protractorPosition.Y - 68, 20, Color.Black);
|
||||
DrawText("180", (int)protractorPosition.X - 124, (int)protractorPosition.Y - 9, 20, Color.Black);
|
||||
DrawText("210", (int)protractorPosition.X - 100, (int)protractorPosition.Y + 50, 20, Color.Black);
|
||||
DrawText("270", (int)protractorPosition.X - 18, (int)protractorPosition.Y + 92, 20, Color.Black);
|
||||
DrawText("330", (int)protractorPosition.X + 72, (int)protractorPosition.Y + 50, 20, Color.Black);
|
||||
if (currentAngleDegrees != 0.0f)
|
||||
{
|
||||
DrawLineEx(protractorPosition, finalVector, 3.0f, gestureColor);
|
||||
}
|
||||
|
||||
// Draw touch and mouse pointer points
|
||||
if (currentGesture != Gesture.None)
|
||||
{
|
||||
if (touchCount != 0)
|
||||
{
|
||||
for (i = 0; i < touchCount; i++)
|
||||
{
|
||||
DrawCircleV(touchPosition[i], 50.0f, Fade(gestureColor, 0.5f));
|
||||
DrawCircleV(touchPosition[i], 5.0f, gestureColor);
|
||||
}
|
||||
|
||||
if (touchCount == 2)
|
||||
{
|
||||
DrawLineEx(touchPosition[0], touchPosition[1], (((int)currentGesture == 512) ? 8.0f : 12.0f),
|
||||
gestureColor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawCircleV(mousePosition, 35.0f, Fade(gestureColor, 0.5f));
|
||||
DrawCircleV(mousePosition, 5.0f, gestureColor);
|
||||
}
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//--------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static string GetGestureName(int gesture)
|
||||
{
|
||||
switch (gesture)
|
||||
{
|
||||
case 0: return "None"; break;
|
||||
case 1: return "Tap"; break;
|
||||
case 2: return "Double Tap"; break;
|
||||
case 4: return "Hold"; break;
|
||||
case 8: return "Drag"; break;
|
||||
case 16: return "Swipe Right"; break;
|
||||
case 32: return "Swipe Left"; break;
|
||||
case 64: return "Swipe Up"; break;
|
||||
case 128: return "Swipe Down"; break;
|
||||
case 256: return "Pinch In"; break;
|
||||
case 512: return "Pinch Out"; break;
|
||||
default: return "Unknown"; break;
|
||||
}
|
||||
}
|
||||
|
||||
// Get color for gesture value
|
||||
static Color GetGestureColor(int gesture)
|
||||
{
|
||||
switch (gesture)
|
||||
{
|
||||
case 0: return Color.Black; break;
|
||||
case 1: return Color.Blue; break;
|
||||
case 2: return Color.SkyBlue; break;
|
||||
case 4: return Color.Black; break;
|
||||
case 8: return Color.Lime; break;
|
||||
case 16: return Color.Red; break;
|
||||
case 32: return Color.Red; break;
|
||||
case 64: return Color.Red; break;
|
||||
case 128: return Color.Red; break;
|
||||
case 256: return Color.Violet; break;
|
||||
case 512: return Color.Orange; break;
|
||||
default: return Color.Black; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Keyboard input
|
||||
* raylib [core] example - input keys
|
||||
*
|
||||
* 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 1.0
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,19 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Mouse input
|
||||
* raylib [core] example - input mouse
|
||||
*
|
||||
* 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 5.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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
||||
using System.Numerics;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
|
|
@ -36,6 +41,19 @@ public class InputMouse
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
if (IsKeyPressed(KeyboardKey.H))
|
||||
{
|
||||
if (IsCursorHidden())
|
||||
{
|
||||
ShowCursor();
|
||||
}
|
||||
else
|
||||
{
|
||||
HideCursor();
|
||||
}
|
||||
}
|
||||
|
||||
ballPosition = GetMousePosition();
|
||||
|
||||
if (IsMouseButtonPressed(MouseButton.Left))
|
||||
|
|
@ -50,6 +68,18 @@ public class InputMouse
|
|||
{
|
||||
ballColor = Color.DarkBlue;
|
||||
}
|
||||
else if (IsMouseButtonPressed(MouseButton.Extra))
|
||||
{
|
||||
ballColor = Color.Yellow;
|
||||
}
|
||||
else if (IsMouseButtonPressed(MouseButton.Forward))
|
||||
{
|
||||
ballColor = Color.Orange;
|
||||
}
|
||||
else if (IsMouseButtonPressed(MouseButton.Back))
|
||||
{
|
||||
ballColor = Color.Beige;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
|
@ -60,6 +90,16 @@ public class InputMouse
|
|||
DrawCircleV(ballPosition, 40, ballColor);
|
||||
|
||||
DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, Color.DarkGray);
|
||||
DrawText("Press 'H' to toggle cursor visibility", 10, 30, 20, Color.DarkGray);
|
||||
|
||||
if (IsCursorHidden())
|
||||
{
|
||||
DrawText("CURSOR HIDDEN", 20, 60, 20, Color.Red);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawText("CURSOR VISIBLE", 20, 60, 20, Color.Lime);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] examples - Mouse wheel input
|
||||
* raylib [core] example - input mouse wheel
|
||||
*
|
||||
* This test has been created using raylib 1.1 (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.1, last time updated with raylib 1.3
|
||||
*
|
||||
* 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)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
@ -24,10 +28,8 @@ public class InputMouseWheel
|
|||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - input mouse wheel");
|
||||
|
||||
int boxPositionY = screenHeight / 2 - 40;
|
||||
|
||||
// Scrolling speed in pixels
|
||||
int scrollSpeed = 4;
|
||||
int boxPositionY = screenHeight/2 - 40;
|
||||
int scrollSpeed = 4; // Scrolling speed in pixels
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Input multitouch
|
||||
* raylib [core] example - input multitouch
|
||||
*
|
||||
* This example has been created using raylib 2.1 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 2.1, last time updated with raylib 2.5
|
||||
*
|
||||
* Example contributed by Berni (@Berni8k) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Copyright (c) 2019 Berni (@Berni8k) 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) 2019-2025 Berni (@Berni8k) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
|
|
|
|||
216
Examples/Core/InputVirtualControls.cs
Normal file
216
Examples/Core/InputVirtualControls.cs
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - input virtual controls
|
||||
*
|
||||
* Example complexity rating: [★★☆☆] 2/4
|
||||
*
|
||||
* Example originally created with raylib 5.0, last time updated with raylib 5.0
|
||||
*
|
||||
* Example contributed by GreenSnakeLinux (@GreenSnakeLinux),
|
||||
* reviewed by Ramon Santamaria (@raysan5), oblerion (@oblerion) and danilwhale (@danilwhale)
|
||||
*
|
||||
* 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) 2024-2025 GreenSnakeLinux (@GreenSnakeLinux) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
|
||||
namespace Examples.Core;
|
||||
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
public enum PadButton
|
||||
{
|
||||
BUTTON_NONE = -1,
|
||||
BUTTON_UP,
|
||||
BUTTON_LEFT,
|
||||
BUTTON_RIGHT,
|
||||
BUTTON_DOWN,
|
||||
BUTTON_MAX
|
||||
}
|
||||
|
||||
public class InputVirtualControls
|
||||
{
|
||||
public static int Main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - input virtual controls");
|
||||
|
||||
Vector2 padPosition = new Vector2(100, 350);
|
||||
float buttonRadius = 30;
|
||||
|
||||
Vector2[] buttonPositions =
|
||||
[
|
||||
new Vector2(
|
||||
padPosition.X,padPosition.Y - buttonRadius * 1.5f
|
||||
), // Up
|
||||
new Vector2(
|
||||
padPosition.X - buttonRadius * 1.5f, padPosition.Y
|
||||
), // Left
|
||||
new Vector2(
|
||||
padPosition.X + buttonRadius * 1.5f, padPosition.Y
|
||||
), // Right
|
||||
new Vector2(
|
||||
padPosition.X, padPosition.Y + buttonRadius * 1.5f
|
||||
) // Down
|
||||
];
|
||||
|
||||
Vector2[][] arrowTris = [
|
||||
// Up
|
||||
[
|
||||
new Vector2(
|
||||
buttonPositions[0].X, buttonPositions[0].Y - 12
|
||||
),
|
||||
new Vector2(
|
||||
buttonPositions[0].X - 9, buttonPositions[0].Y + 9
|
||||
),
|
||||
new Vector2(
|
||||
buttonPositions[0].X + 9, buttonPositions[0].Y + 9
|
||||
)
|
||||
],
|
||||
// Left
|
||||
[
|
||||
new Vector2(
|
||||
buttonPositions[1].X + 9, buttonPositions[1].Y - 9
|
||||
),
|
||||
new Vector2(
|
||||
buttonPositions[1].X - 12, buttonPositions[1].Y
|
||||
),
|
||||
new Vector2(
|
||||
buttonPositions[1].X + 9, buttonPositions[1].Y + 9
|
||||
)
|
||||
],
|
||||
// Right
|
||||
[
|
||||
new Vector2(
|
||||
buttonPositions[2].X + 12, buttonPositions[2].Y
|
||||
),
|
||||
new Vector2(
|
||||
buttonPositions[2].X - 9, buttonPositions[2].Y - 9
|
||||
),
|
||||
new Vector2(
|
||||
buttonPositions[2].X - 9, buttonPositions[2].Y + 9
|
||||
)
|
||||
],
|
||||
// Down
|
||||
[
|
||||
new Vector2(
|
||||
buttonPositions[3].X - 9, buttonPositions[3].Y - 9
|
||||
),
|
||||
new Vector2(
|
||||
buttonPositions[3].X, buttonPositions[3].Y + 12
|
||||
),
|
||||
new Vector2(
|
||||
buttonPositions[3].X + 9, buttonPositions[3].Y - 9
|
||||
)
|
||||
]
|
||||
]
|
||||
;
|
||||
|
||||
Color[] buttonLabelColors = [
|
||||
Color.Yellow, // Up
|
||||
Color.Blue, // Left
|
||||
Color.Red, // Right
|
||||
Color.Green // Down
|
||||
];
|
||||
|
||||
int pressedButton = (int)PadButton.BUTTON_NONE;
|
||||
Vector2 inputPosition = new Vector2( 0, 0 );
|
||||
|
||||
Vector2 playerPosition = new Vector2( (float)screenWidth / 2, (float)screenHeight / 2 );
|
||||
float playerSpeed = 75f;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//--------------------------------------------------------------------------
|
||||
if ((GetTouchPointCount() > 0))
|
||||
{
|
||||
inputPosition = GetTouchPosition(0); // Use touch position
|
||||
}
|
||||
else
|
||||
{
|
||||
inputPosition = GetMousePosition(); // Use mouse position
|
||||
}
|
||||
|
||||
// Reset pressed button to none
|
||||
pressedButton = (int)PadButton.BUTTON_NONE;
|
||||
|
||||
// Make sure user is pressing left mouse button if they're from desktop
|
||||
if ((GetTouchPointCount() > 0) ||
|
||||
((GetTouchPointCount() == 0) && IsMouseButtonDown(MouseButton.Left)))
|
||||
{
|
||||
// Find nearest D-Pad button to the input position
|
||||
for (int i = 0; i < (int)PadButton.BUTTON_MAX; i++)
|
||||
{
|
||||
float distX = MathF.Abs(buttonPositions[i].X - inputPosition.X);
|
||||
float distY = MathF.Abs(buttonPositions[i].Y - inputPosition.Y);
|
||||
|
||||
if ((distX + distY < buttonRadius))
|
||||
{
|
||||
pressedButton = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move player according to pressed button
|
||||
switch ((PadButton)pressedButton)
|
||||
{
|
||||
case PadButton.BUTTON_UP: playerPosition.Y -= playerSpeed * GetFrameTime(); break;
|
||||
case PadButton.BUTTON_LEFT: playerPosition.X -= playerSpeed * GetFrameTime(); break;
|
||||
case PadButton.BUTTON_RIGHT: playerPosition.X += playerSpeed * GetFrameTime(); break;
|
||||
case PadButton.BUTTON_DOWN: playerPosition.Y += playerSpeed * GetFrameTime(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
;
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//--------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(Color.RayWhite);
|
||||
|
||||
// Draw world
|
||||
DrawCircleV(playerPosition, 50, Color.Maroon);
|
||||
|
||||
// Draw GUI
|
||||
for (int i = 0; i < (int)PadButton.BUTTON_MAX; i++)
|
||||
{
|
||||
DrawCircleV(buttonPositions[i], buttonRadius, (i == pressedButton) ? Color.DarkGray : Color.Black);
|
||||
|
||||
DrawTriangle(
|
||||
arrowTris[i][0],
|
||||
arrowTris[i][1],
|
||||
arrowTris[i][2],
|
||||
buttonLabelColors[i]
|
||||
);
|
||||
}
|
||||
|
||||
DrawText("move the player with D-Pad buttons", 10, 10, 20, Color.DarkGray);
|
||||
|
||||
EndDrawing();
|
||||
//--------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +1,31 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - Load 3d model with animations and play them
|
||||
* raylib [models] example - loading iqm
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Example originally created with raylib 2.5, last time updated with raylib 3.5
|
||||
*
|
||||
* Example contributed by Culacant (@culacant) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Copyright (c) 2019 Culacant (@culacant) and Ramon Santamaria (@raysan5)
|
||||
* NOTES: To export an IQM model from blender, make sure it is not posed, the vertices need
|
||||
* to be in the same position as they would be in edit mode and the scale of the models is
|
||||
* set to 0; scaling can be set from the export menu
|
||||
*
|
||||
********************************************************************************************
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* To export a model from blender, make sure it is not posed, the vertices need to be in the
|
||||
* same position as they would be in edit mode.
|
||||
* and that the scale of your models is set to 0. Scaling can be done from the export menu.
|
||||
* Copyright (c) 2019-2025 Culacant (@culacant) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
using static Raylib_cs.Raylib;
|
||||
|
||||
namespace Examples.Models;
|
||||
|
||||
public class AnimationDemo
|
||||
public class LoadingIqm
|
||||
{
|
||||
public unsafe static int Main()
|
||||
{
|
||||
|
|
@ -36,20 +39,22 @@ public class AnimationDemo
|
|||
// Define the camera to look into our 3d world
|
||||
Camera3D camera = new();
|
||||
camera.Position = new Vector3(10.0f, 10.0f, 10.0f);
|
||||
camera.Target = new Vector3(0.0f, 0.0f, 0.0f);
|
||||
camera.Target = new Vector3(0.0f, 4.0f, 0.0f);
|
||||
camera.Up = new Vector3(0.0f, 1.0f, 0.0f);
|
||||
camera.FovY = 45.0f;
|
||||
camera.Projection = CameraProjection.Perspective;
|
||||
|
||||
Model model = LoadModel("resources/models/iqm/guy.iqm");
|
||||
Texture2D texture = LoadTexture("resources/models/iqm/guytex.png");
|
||||
Raylib.SetMaterialTexture(ref model, 0, MaterialMapIndex.Albedo, ref texture);
|
||||
|
||||
Raylib.SetMaterialTexture(ref model, 0, MaterialMapIndex.Diffuse, ref texture);
|
||||
Vector3 position = new(0.0f, 0.0f, 0.0f);
|
||||
|
||||
// Load animation data
|
||||
int animsCount = 0;
|
||||
var anims = LoadModelAnimations("resources/models/iqm/guyanim.iqm", ref animsCount);
|
||||
int animFrameCounter = 0;
|
||||
var anims = LoadModelAnimations("resources/models/iqm/guyanim.iqm");
|
||||
|
||||
// Animation playing variables
|
||||
int animIndex = 0;
|
||||
float animCurrentFrame = 0.0f;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
|
@ -59,17 +64,15 @@ public class AnimationDemo
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(ref camera, CameraMode.Free);
|
||||
UpdateCamera(ref camera, CameraMode.Orbital);
|
||||
|
||||
// Play animation when spacebar is held down
|
||||
if (IsKeyDown(KeyboardKey.Space))
|
||||
animCurrentFrame += 1.0f;
|
||||
UpdateModelAnimation(model, anims[0], animCurrentFrame);
|
||||
|
||||
if (animCurrentFrame >= anims[0].KeyFrameCount)
|
||||
{
|
||||
animFrameCounter++;
|
||||
UpdateModelAnimation(model, anims[0], animFrameCounter);
|
||||
if (animFrameCounter >= anims[0].FrameCount)
|
||||
{
|
||||
animFrameCounter = 0;
|
||||
}
|
||||
animCurrentFrame = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -89,17 +92,10 @@ public class AnimationDemo
|
|||
Color.White
|
||||
);
|
||||
|
||||
for (int i = 0; i < model.BoneCount; i++)
|
||||
{
|
||||
var framePoses = anims[0].FramePoses;
|
||||
DrawCube(framePoses[animFrameCounter][i].Translation, 0.2f, 0.2f, 0.2f, Color.Red);
|
||||
}
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
|
||||
EndMode3D();
|
||||
|
||||
DrawText("PRESS SPACE to PLAY MODEL ANIMATION", 10, 10, 20, Color.Maroon);
|
||||
DrawText($"Current animation: {anims[animIndex].NameToString()}", 10, 10, 20, Color.Maroon);
|
||||
DrawText("(c) Guy IQM 3D model by @culacant", screenWidth - 200, screenHeight - 20, 10, Color.Gray);
|
||||
|
||||
EndDrawing();
|
||||
|
|
@ -109,9 +105,7 @@ public class AnimationDemo
|
|||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture);
|
||||
|
||||
UnloadModelAnimations(anims, animsCount);
|
||||
|
||||
UnloadModelAnimations(anims);
|
||||
UnloadModel(model);
|
||||
|
||||
CloseWindow();
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using Examples.Core;
|
||||
using Examples.Shapes;
|
||||
|
|
@ -34,6 +33,9 @@ public class ExampleList
|
|||
public static ExampleInfo[] AllExamples = new[]
|
||||
{
|
||||
// Core
|
||||
new ExampleInfo("DeltaTime", DeltaTime.Main),
|
||||
new ExampleInfo("InputGesturesTestBed", InputGesturesTestBed.Main),
|
||||
new ExampleInfo("InputVirtualControls", InputVirtualControls.Main),
|
||||
new ExampleInfo("Camera2dPlatformer", Camera2dPlatformer.Main),
|
||||
new ExampleInfo("Camera2dDemo", Camera2dDemo.Main),
|
||||
new ExampleInfo("Camera3dFirstPerson", Camera3dFirstPerson.Main),
|
||||
|
|
@ -110,7 +112,7 @@ public class ExampleList
|
|||
new ExampleInfo("WritingAnim", WritingAnim.Main),
|
||||
|
||||
// Models
|
||||
new ExampleInfo("AnimationDemo", AnimationDemo.Main),
|
||||
new ExampleInfo("LoadingIqm", LoadingIqm.Main),
|
||||
new ExampleInfo("BillboardDemo", BillboardDemo.Main),
|
||||
new ExampleInfo("BoxCollisions", BoxCollisions.Main),
|
||||
new ExampleInfo("CubicmapDemo", CubicmapDemo.Main),
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 239 KiB |
|
|
@ -820,32 +820,32 @@ public static unsafe partial class Raylib
|
|||
/// <summary>Rename file (if exists)</summary>
|
||||
[LibraryImport(NativeLibName)]
|
||||
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
|
||||
public static partial CBool FileRename(sbyte* fileName, sbyte* fileRename);
|
||||
public static partial int FileRename(sbyte* fileName, sbyte* fileRename);
|
||||
|
||||
/// <summary>Remove file (if exists)</summary>
|
||||
[LibraryImport(NativeLibName)]
|
||||
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
|
||||
public static partial CBool FileRemove(sbyte* fileName);
|
||||
public static partial int FileRemove(sbyte* fileName);
|
||||
|
||||
/// <summary>Copy file from one path to another, dstPath created if it doesn't exist</summary>
|
||||
[LibraryImport(NativeLibName)]
|
||||
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
|
||||
public static partial CBool FileCopy(sbyte* srcPath, sbyte* dstPath);
|
||||
public static partial int FileCopy(sbyte* srcPath, sbyte* dstPath);
|
||||
|
||||
/// <summary>Move file from one path to another, dstPath created if it doesn't exist</summary>
|
||||
[LibraryImport(NativeLibName)]
|
||||
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
|
||||
public static partial CBool FileMove(sbyte* srcPath, sbyte* dstPath);
|
||||
public static partial int FileMove(sbyte* srcPath, sbyte* dstPath);
|
||||
|
||||
/// <summary>Replace text in an existing file</summary>
|
||||
[LibraryImport(NativeLibName)]
|
||||
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
|
||||
public static partial CBool FileTextReplace(sbyte* fileName, sbyte* search, sbyte* replacement);
|
||||
public static partial int FileTextReplace(sbyte* fileName, sbyte* search, sbyte* replacement);
|
||||
|
||||
/// <summary>Find text in existing file</summary>
|
||||
[LibraryImport(NativeLibName)]
|
||||
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
|
||||
public static partial CBool FileTextFindIndex(sbyte* fileName, sbyte* search);
|
||||
public static partial int FileTextFindIndex(sbyte* fileName, sbyte* search);
|
||||
|
||||
/// <summary>Check if file exists</summary>
|
||||
[LibraryImport(NativeLibName)]
|
||||
|
|
@ -962,7 +962,7 @@ public static unsafe partial class Raylib
|
|||
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
|
||||
public static partial FilePathList GetDirectoryFileCount(sbyte* dirPath);
|
||||
|
||||
/// <summary>Get the file count in a directory</summary>
|
||||
/// <summary>Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"</summary>
|
||||
[LibraryImport(NativeLibName)]
|
||||
[UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])]
|
||||
public static partial FilePathList GetDirectoryFileCountEx(sbyte* dirPath, sbyte* filter, CBool scanSubdirs);
|
||||
|
|
|
|||
|
|
@ -248,4 +248,6 @@ public unsafe struct Mesh
|
|||
public const int VboIdIndexIndices = 6;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,14 @@ public unsafe struct BoneInfo
|
|||
/// Bone parent
|
||||
/// </summary>
|
||||
public int Parent;
|
||||
|
||||
public string NameToString()
|
||||
{
|
||||
fixed (sbyte* name = Name)
|
||||
{
|
||||
return Utf8StringUtils.GetUTF8String(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -41,6 +49,16 @@ public unsafe struct ModelSkeleton
|
|||
/// Bones base transformation (Transform[])
|
||||
/// </summary>
|
||||
public Transform* ModelAnimPose;
|
||||
|
||||
public Span<Transform> ModelAnimPoseAsSpan()
|
||||
{
|
||||
return new Span<Transform>(ModelAnimPose, BoneCount);
|
||||
}
|
||||
|
||||
public Span<BoneInfo> BonesAsSpan()
|
||||
{
|
||||
return new Span<BoneInfo>(Bones, BoneCount);
|
||||
}
|
||||
}
|
||||
|
||||
// Note:
|
||||
|
|
@ -84,29 +102,52 @@ public unsafe struct Model
|
|||
public int* MeshMaterial;
|
||||
|
||||
/// <summary>
|
||||
/// Number of bones
|
||||
/// Skeleton for animation
|
||||
/// </summary>
|
||||
public int BoneCount;
|
||||
ModelSkeleton Skeleton;
|
||||
|
||||
//TODO: Span
|
||||
/// <summary>
|
||||
/// Bones information (skeleton, BoneInfo *)
|
||||
/// Current animation pose (Transform[])
|
||||
/// </summary>
|
||||
public BoneInfo* Bones;
|
||||
public Transform* CurrentPose;
|
||||
|
||||
//TODO: Span
|
||||
/// <summary>
|
||||
/// Bones base transformation (pose, Transform *)
|
||||
/// Bones animated transformation matrices
|
||||
/// </summary>
|
||||
public Transform* BindPose;
|
||||
public Matrix4x4* BoneMatrices;
|
||||
|
||||
public Span<Matrix4x4> BoneMatricesAsSpan()
|
||||
{
|
||||
return new Span<Matrix4x4>(BoneMatrices, Skeleton.BoneCount);
|
||||
}
|
||||
|
||||
public Span<Transform> CurrentPoseAsSpan()
|
||||
{
|
||||
return new Span<Transform>(CurrentPose, Skeleton.BoneCount);
|
||||
}
|
||||
|
||||
public Span<int> MeshMaterialAsSpan()
|
||||
{
|
||||
return new Span<int>(MeshMaterial, MeshCount);
|
||||
}
|
||||
|
||||
public Span<Mesh> MeshesAsSpan()
|
||||
{
|
||||
return new Span<Mesh>(Meshes, MeshCount);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Model animation
|
||||
/// ModelAnimation, contains a full animation sequence
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct ModelAnimation
|
||||
{
|
||||
/// <summary>
|
||||
/// Animation name (char[32])
|
||||
/// </summary>
|
||||
public fixed sbyte Name[32];
|
||||
|
||||
/// <summary>
|
||||
/// Number of bones
|
||||
/// </summary>
|
||||
|
|
@ -115,61 +156,23 @@ public unsafe struct ModelAnimation
|
|||
/// <summary>
|
||||
/// Number of animation frames
|
||||
/// </summary>
|
||||
public readonly int FrameCount;
|
||||
public readonly int KeyFrameCount;
|
||||
|
||||
/// <summary>
|
||||
/// Bones information (skeleton, BoneInfo *)
|
||||
/// Animation sequence keyframe poses [keyframe][pose]
|
||||
/// </summary>
|
||||
public readonly BoneInfo* Bones;
|
||||
public Transform* KeyframePoses;
|
||||
|
||||
/// <inheritdoc cref="Bones"/>
|
||||
public readonly ReadOnlySpan<BoneInfo> BoneInfo => new ReadOnlySpan<BoneInfo>(Bones, BoneCount);
|
||||
|
||||
/// <summary>
|
||||
/// Poses array by frame (Transform **)
|
||||
/// </summary>
|
||||
public readonly Transform** FramePoses;
|
||||
|
||||
/// <summary>
|
||||
/// Animation name (char[32])
|
||||
/// </summary>
|
||||
public fixed sbyte Name[32];
|
||||
|
||||
/// <inheritdoc cref="FramePoses"/>
|
||||
public readonly FramePosesCollection FramePosesColl => new FramePosesCollection(FramePoses, FrameCount, BoneCount);
|
||||
|
||||
public readonly struct FramePosesCollection
|
||||
public Span<Transform> KeyFramePosesAsSpan()
|
||||
{
|
||||
readonly Transform** _framePoses;
|
||||
return new Span<Transform>(KeyframePoses, KeyFrameCount);
|
||||
}
|
||||
|
||||
readonly int _frameCount;
|
||||
|
||||
readonly int _boneCount;
|
||||
|
||||
public readonly FramePoses this[int index] => new FramePoses(_framePoses[index], _boneCount);
|
||||
|
||||
public readonly Transform this[int index1, int index2] => new FramePoses(_framePoses[index1], _boneCount)[index2];
|
||||
|
||||
internal FramePosesCollection(Transform** framePoses, int frameCount, int boneCount)
|
||||
public string NameToString()
|
||||
{
|
||||
fixed (sbyte* name = Name)
|
||||
{
|
||||
this._framePoses = framePoses;
|
||||
this._frameCount = frameCount;
|
||||
this._boneCount = boneCount;
|
||||
return Utf8StringUtils.GetUTF8String(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public readonly unsafe struct FramePoses
|
||||
{
|
||||
readonly Transform* _poses;
|
||||
|
||||
readonly int _count;
|
||||
|
||||
public readonly ref Transform this[int index] => ref _poses[index];
|
||||
|
||||
internal FramePoses(Transform* poses, int count)
|
||||
{
|
||||
this._poses = poses;
|
||||
this._count = count;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1085,6 +1085,24 @@ public static unsafe partial class Raylib
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Load model animations from file</summary>
|
||||
public static Span<ModelAnimation> LoadModelAnimations(string fileName)
|
||||
{
|
||||
using AnsiBuffer str1 = fileName.ToAnsiBuffer();
|
||||
int count;
|
||||
|
||||
ModelAnimation* result = LoadModelAnimations(str1.AsPointer(), &count);
|
||||
return new Span<ModelAnimation>(result, count);
|
||||
}
|
||||
|
||||
public static void UnloadModelAnimations(Span<ModelAnimation> animations)
|
||||
{
|
||||
fixed (ModelAnimation* ptr = animations)
|
||||
{
|
||||
UnloadModelAnimations(ptr, animations.Length);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Compute mesh tangents</summary>
|
||||
public static void GenMeshTangents(ref Mesh mesh)
|
||||
{
|
||||
|
|
@ -1549,6 +1567,155 @@ public static unsafe partial class Raylib
|
|||
SaveFileText(fileBuffer.AsPointer(), textBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Rename file (if exists)</summary>
|
||||
public static int FileRename(string filename, string fileRename)
|
||||
{
|
||||
|
||||
using AnsiBuffer fileBuffer = filename.ToAnsiBuffer();
|
||||
using AnsiBuffer textBuffer = fileRename.ToAnsiBuffer();
|
||||
return FileRename(fileBuffer.AsPointer(), textBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Remove file (if exists)</summary>
|
||||
public static int FileRemove(string filename)
|
||||
{
|
||||
using AnsiBuffer fileBuffer = filename.ToAnsiBuffer();
|
||||
return FileRemove(fileBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Copy file from one path to another, dstPath created if it doesn't exist</summary>
|
||||
public static int FileCopy(string srcPath, string dstPath)
|
||||
{
|
||||
using AnsiBuffer srcBuffer = srcPath.ToAnsiBuffer();
|
||||
using AnsiBuffer dstBuffer = dstPath.ToAnsiBuffer();
|
||||
return FileCopy(srcBuffer.AsPointer(), dstBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Move file from one path to another, dstPath created if it doesn't exist</summary>
|
||||
public static int FileMove(string srcPath, string dstPath)
|
||||
{
|
||||
using AnsiBuffer srcBuffer = srcPath.ToAnsiBuffer();
|
||||
using AnsiBuffer dstBuffer = dstPath.ToAnsiBuffer();
|
||||
return FileMove(srcBuffer.AsPointer(), dstBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Replace text in an existing file</summary>
|
||||
public static int FileTextReplace(string fileName, string search, string replacement)
|
||||
{
|
||||
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
|
||||
using AnsiBuffer searchBuffer = search.ToAnsiBuffer();
|
||||
using AnsiBuffer replaceBuffer = replacement.ToAnsiBuffer();
|
||||
return FileTextReplace(fileBuffer.AsPointer(), searchBuffer.AsPointer(), replaceBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Find text in existing file</summary>
|
||||
public static int FileTextFindIndex(string fileName, string search)
|
||||
{
|
||||
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
|
||||
using AnsiBuffer searchBuffer = search.ToAnsiBuffer();
|
||||
return FileTextFindIndex(fileBuffer.AsPointer(), searchBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Check if file exists</summary>
|
||||
public static CBool FileExists(string fileName)
|
||||
{
|
||||
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
|
||||
return FileExists(fileBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Check if a directory path exists</summary>
|
||||
public static CBool DirectoryExists(string dirPath)
|
||||
{
|
||||
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
|
||||
return DirectoryExists(dirBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Get file length in bytes</summary>
|
||||
public static int GetFileLength(string fileName)
|
||||
{
|
||||
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
|
||||
return GetFileLength(fileBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Get string to extension for a filename string (includes dot: '.png')</summary>
|
||||
public static string GetFileExtension(string fileName)
|
||||
{
|
||||
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
|
||||
return new string(GetFileExtension(fileBuffer.AsPointer()));
|
||||
}
|
||||
|
||||
/// <summary>Get string to filename for a path string</summary>
|
||||
public static string GetFileName(string fileName)
|
||||
{
|
||||
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
|
||||
return new string(GetFileName(fileBuffer.AsPointer()));
|
||||
}
|
||||
|
||||
/// <summary>Get filename string without extension </summary>
|
||||
public static string GetFileNameWithoutExt(string fileName)
|
||||
{
|
||||
using AnsiBuffer fileBuffer = fileName.ToAnsiBuffer();
|
||||
return new string(GetFileNameWithoutExt(fileBuffer.AsPointer()));
|
||||
}
|
||||
|
||||
/// <summary>Get full path for a given fileName with path</summary>
|
||||
public static string GetDirectoryPath(string filePath)
|
||||
{
|
||||
using AnsiBuffer fileBuffer = filePath.ToAnsiBuffer();
|
||||
return new string(GetDirectoryPath(fileBuffer.AsPointer()));
|
||||
}
|
||||
|
||||
/// <summary>Get previous directory path for a given path</summary>
|
||||
public static string GetPrevDirectoryPath(string dirPath)
|
||||
{
|
||||
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
|
||||
return new string(GetPrevDirectoryPath(dirBuffer.AsPointer()));
|
||||
}
|
||||
|
||||
/// <summary>Get current working directory</summary>
|
||||
public static string GetWorkingDirectoryAsString()
|
||||
{
|
||||
return new string(GetWorkingDirectory());
|
||||
}
|
||||
|
||||
/// <summary>Get the directory of the running application</summary>
|
||||
public static string GetApplicationDirectoryAsString()
|
||||
{
|
||||
return new string(GetApplicationDirectory());
|
||||
}
|
||||
|
||||
/// <summary>Change working directory, return true on success</summary>
|
||||
public static CBool ChangeDirectory(string dirPath)
|
||||
{
|
||||
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
|
||||
return ChangeDirectory(dirBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Check if a given path is a file or a directory</summary>
|
||||
public static CBool IsPathFile(string path)
|
||||
{
|
||||
using AnsiBuffer pathBuffer = path.ToAnsiBuffer();
|
||||
return IsPathFile(pathBuffer.AsPointer());
|
||||
}
|
||||
|
||||
/// <summary>Load directory filepaths</summary>
|
||||
public static FilePathList LoadDirectoryFiles(string dirPath, out int count)
|
||||
{
|
||||
using AnsiBuffer dirBuffer = dirPath.ToAnsiBuffer();
|
||||
int c = 0;
|
||||
var result = LoadDirectoryFiles(dirBuffer.AsPointer(), &c);
|
||||
count = c;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"</summary>
|
||||
public static FilePathList LoadDirectoryFilesEx(string basePath, string filter, CBool scanSubDirs)
|
||||
{
|
||||
using AnsiBuffer baseBuffer = basePath.ToAnsiBuffer();
|
||||
using AnsiBuffer filterBuffer = filter.ToAnsiBuffer();
|
||||
return LoadDirectoryFilesEx(baseBuffer.AsPointer(), filterBuffer.AsPointer(), scanSubDirs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads text from a file, reads it, saves it, unloads the file, and returns the loaded text.
|
||||
/// </summary>
|
||||
|
|
@ -1569,4 +1736,5 @@ public static unsafe partial class Raylib
|
|||
center.Y = GetScreenHeight() / 2.0f;
|
||||
return center;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Raylib_cs;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,11 @@ public readonly ref struct Utf8Buffer
|
|||
return (sbyte*)_data.ToPointer();
|
||||
}
|
||||
|
||||
public unsafe byte* AsBytePointer()
|
||||
{
|
||||
return (byte*)_data.ToPointer();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Marshal.ZeroFreeCoTaskMemUTF8(_data);
|
||||
|
|
|
|||
Loading…
Reference in a new issue