core_input_virtual_controls.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*******************************************************************************************
  2. *
  3. * raylib [core] example - input virtual controls
  4. *
  5. * Example originally created with raylib 5.0, last time updated with raylib 5.0
  6. *
  7. * Example create by GreenSnakeLinux (@GreenSnakeLinux),
  8. * lighter by oblerion (@oblerion) and
  9. * reviewed by Ramon Santamaria (@raysan5) and
  10. * improved by 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 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. {
  42. { padPosition.x,padPosition.y - buttonRadius*1.5f }, // Up
  43. { padPosition.x - buttonRadius*1.5f, padPosition.y }, // Left
  44. { padPosition.x + buttonRadius*1.5f, padPosition.y }, // Right
  45. { padPosition.x, padPosition.y + buttonRadius*1.5f } // Down
  46. };
  47. const char *buttonLabels[BUTTON_MAX] =
  48. {
  49. "Y", // Up
  50. "X", // Left
  51. "B", // Right
  52. "A" // Down
  53. };
  54. Color buttonLabelColors[BUTTON_MAX] =
  55. {
  56. YELLOW, // Up
  57. BLUE, // Left
  58. RED, // Right
  59. GREEN // Down
  60. };
  61. int pressedButton = BUTTON_NONE;
  62. Vector2 inputPosition = { 0, 0 };
  63. Vector2 playerPosition = { (float)screenWidth/2, (float)screenHeight/2 };
  64. float playerSpeed = 75;
  65. SetTargetFPS(60);
  66. //--------------------------------------------------------------------------------------
  67. // Main game loop
  68. while (!WindowShouldClose()) // Detect window close button or ESC key
  69. {
  70. // Update
  71. //--------------------------------------------------------------------------
  72. if ((GetTouchPointCount() > 0))
  73. {
  74. // Use touch position
  75. inputPosition = GetTouchPosition(0);
  76. }
  77. else
  78. {
  79. // Use mouse position
  80. inputPosition = GetMousePosition();
  81. }
  82. // Reset pressed button to none
  83. pressedButton = BUTTON_NONE;
  84. // Make sure user is pressing left mouse button if they're from desktop
  85. if ((GetTouchPointCount() > 0) || ((GetTouchPointCount() == 0) && IsMouseButtonDown(MOUSE_BUTTON_LEFT)))
  86. {
  87. // Find nearest D-Pad button to the input position
  88. for (int i = 0; i < BUTTON_MAX; i++)
  89. {
  90. float distX = fabsf(buttonPositions[i].x - inputPosition.x);
  91. float distY = fabsf(buttonPositions[i].y - inputPosition.y);
  92. if ((distX + distY < buttonRadius))
  93. {
  94. pressedButton = i;
  95. break;
  96. }
  97. }
  98. }
  99. // Move player according to pressed button
  100. switch (pressedButton)
  101. {
  102. case BUTTON_UP: playerPosition.y -= playerSpeed*GetFrameTime(); break;
  103. case BUTTON_LEFT: playerPosition.x -= playerSpeed*GetFrameTime(); break;
  104. case BUTTON_RIGHT: playerPosition.x += playerSpeed*GetFrameTime(); break;
  105. case BUTTON_DOWN: playerPosition.y += playerSpeed*GetFrameTime(); break;
  106. default: break;
  107. };
  108. //--------------------------------------------------------------------------
  109. // Draw
  110. //--------------------------------------------------------------------------
  111. BeginDrawing();
  112. ClearBackground(RAYWHITE);
  113. // Draw world
  114. DrawCircleV(playerPosition, 50, MAROON);
  115. // Draw GUI
  116. for (int i = 0; i < BUTTON_MAX; i++)
  117. {
  118. DrawCircleV(buttonPositions[i], buttonRadius, (i == pressedButton)? DARKGRAY : BLACK);
  119. DrawText(buttonLabels[i],
  120. (int)buttonPositions[i].x - 7, (int)buttonPositions[i].y - 8,
  121. 20, buttonLabelColors[i]);
  122. }
  123. DrawText("move the player with D-Pad buttons", 10, 10, 20, DARKGRAY);
  124. EndDrawing();
  125. //--------------------------------------------------------------------------
  126. }
  127. // De-Initialization
  128. //--------------------------------------------------------------------------------------
  129. CloseWindow(); // Close window and OpenGL context
  130. //--------------------------------------------------------------------------------------
  131. return 0;
  132. }