core_input_virtual_controls.c 5.2 KB

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