core_input_virtual_controls.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*******************************************************************************************
  2. *
  3. * raylib [core] example - input virtual controls
  4. *
  5. * Example complexity rating: [★★☆☆] 2/4
  6. *
  7. * Example originally created with raylib 5.0, last time updated with raylib 5.0
  8. *
  9. * Example contributed by GreenSnakeLinux (@GreenSnakeLinux),
  10. * reviewed by Ramon Santamaria (@raysan5), oblerion (@oblerion) and danilwhale (@danilwhale)
  11. *
  12. * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
  13. * BSD-like license that allows static linking with closed source software
  14. *
  15. * Copyright (c) 2024-2025 GreenSnakeLinux (@GreenSnakeLinux) and Ramon Santamaria (@raysan5)
  16. *
  17. ********************************************************************************************/
  18. #include "raylib.h"
  19. #include <math.h>
  20. typedef enum {
  21. BUTTON_NONE = -1,
  22. BUTTON_UP,
  23. BUTTON_LEFT,
  24. BUTTON_RIGHT,
  25. BUTTON_DOWN,
  26. BUTTON_MAX
  27. } PadButton;
  28. //------------------------------------------------------------------------------------
  29. // Program main entry point
  30. //------------------------------------------------------------------------------------
  31. int main(void)
  32. {
  33. // Initialization
  34. //--------------------------------------------------------------------------------------
  35. const int screenWidth = 800;
  36. const int screenHeight = 450;
  37. InitWindow(screenWidth, screenHeight, "raylib [core] example - input virtual controls");
  38. Vector2 padPosition = { 100, 350 };
  39. float buttonRadius = 30;
  40. Vector2 buttonPositions[BUTTON_MAX] = {
  41. { padPosition.x,padPosition.y - buttonRadius*1.5f }, // Up
  42. { padPosition.x - buttonRadius*1.5f, padPosition.y }, // Left
  43. { padPosition.x + buttonRadius*1.5f, padPosition.y }, // Right
  44. { padPosition.x, padPosition.y + buttonRadius*1.5f } // Down
  45. };
  46. const char *buttonLabels[BUTTON_MAX] = {
  47. "Y", // Up
  48. "X", // Left
  49. "B", // Right
  50. "A" // Down
  51. };
  52. Color buttonLabelColors[BUTTON_MAX] = {
  53. YELLOW, // Up
  54. BLUE, // Left
  55. RED, // Right
  56. GREEN // Down
  57. };
  58. int pressedButton = BUTTON_NONE;
  59. Vector2 inputPosition = { 0, 0 };
  60. Vector2 playerPosition = { (float)screenWidth/2, (float)screenHeight/2 };
  61. float playerSpeed = 75;
  62. SetTargetFPS(60);
  63. //--------------------------------------------------------------------------------------
  64. // Main game loop
  65. while (!WindowShouldClose()) // Detect window close button or ESC key
  66. {
  67. // Update
  68. //--------------------------------------------------------------------------
  69. if ((GetTouchPointCount() > 0)) inputPosition = GetTouchPosition(0); // Use touch position
  70. else inputPosition = GetMousePosition(); // Use mouse position
  71. // Reset pressed button to none
  72. pressedButton = BUTTON_NONE;
  73. // Make sure user is pressing left mouse button if they're from desktop
  74. if ((GetTouchPointCount() > 0) ||
  75. ((GetTouchPointCount() == 0) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)))
  76. {
  77. // Find nearest D-Pad button to the input position
  78. for (int i = 0; i < BUTTON_MAX; i++)
  79. {
  80. float distX = fabsf(buttonPositions[i].x - inputPosition.x);
  81. float distY = fabsf(buttonPositions[i].y - inputPosition.y);
  82. if ((distX + distY < buttonRadius))
  83. {
  84. pressedButton = i;
  85. break;
  86. }
  87. }
  88. }
  89. // Move player according to pressed button
  90. switch (pressedButton)
  91. {
  92. case BUTTON_UP: playerPosition.y -= playerSpeed*GetFrameTime(); break;
  93. case BUTTON_LEFT: playerPosition.x -= playerSpeed*GetFrameTime(); break;
  94. case BUTTON_RIGHT: playerPosition.x += playerSpeed*GetFrameTime(); break;
  95. case BUTTON_DOWN: playerPosition.y += playerSpeed*GetFrameTime(); break;
  96. default: break;
  97. };
  98. //--------------------------------------------------------------------------
  99. // Draw
  100. //--------------------------------------------------------------------------
  101. BeginDrawing();
  102. ClearBackground(RAYWHITE);
  103. // Draw world
  104. DrawCircleV(playerPosition, 50, MAROON);
  105. // Draw GUI
  106. for (int i = 0; i < BUTTON_MAX; i++)
  107. {
  108. DrawCircleV(buttonPositions[i], buttonRadius, (i == pressedButton)? DARKGRAY : BLACK);
  109. DrawText(buttonLabels[i],
  110. (int)buttonPositions[i].x - 7, (int)buttonPositions[i].y - 8,
  111. 20, buttonLabelColors[i]);
  112. }
  113. DrawText("move the player with D-Pad buttons", 10, 10, 20, DARKGRAY);
  114. EndDrawing();
  115. //--------------------------------------------------------------------------
  116. }
  117. // De-Initialization
  118. //--------------------------------------------------------------------------------------
  119. CloseWindow(); // Close window and OpenGL context
  120. //--------------------------------------------------------------------------------------
  121. return 0;
  122. }