From 2820fcc29e91aac8155ffef45560070ecfc5752d Mon Sep 17 00:00:00 2001 From: danil <61111955+danilwhale@users.noreply.github.com> Date: Sun, 8 Dec 2024 09:52:09 +0200 Subject: [PATCH] [examples] improve input_virtual_controls example (#4584) --- examples/core/core_input_virtual_controls.c | 169 ++++++++++++------ examples/core/core_input_virtual_controls.png | Bin 9094 -> 1802 bytes 2 files changed, 110 insertions(+), 59 deletions(-) diff --git a/examples/core/core_input_virtual_controls.c b/examples/core/core_input_virtual_controls.c index bbbad208..76eeafee 100644 --- a/examples/core/core_input_virtual_controls.c +++ b/examples/core/core_input_virtual_controls.c @@ -6,7 +6,8 @@ * * Example create by GreenSnakeLinux (@GreenSnakeLinux), * lighter by oblerion (@oblerion) and -* reviewed by Ramon Santamaria (@raysan5) +* reviewed by Ramon Santamaria (@raysan5) and +* improved by 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 @@ -17,6 +18,16 @@ #include "raylib.h" #include + +typedef enum { + BUTTON_NONE = -1, + BUTTON_UP, + BUTTON_LEFT, + BUTTON_RIGHT, + BUTTON_DOWN, + BUTTON_MAX +} PadButton; + //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -29,24 +40,38 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [core] example - input virtual controls"); - const float dpadX = 90; - const float dpadY = 300; - const float dpadRad = 25.0f;//radius of each pad - Color dpadColor = BLUE; - int dpadKeydown = -1;//-1 if not down, else 0,1,2,3 + Vector2 padPosition = { 100, 350 }; + float buttonRadius = 30; + + Vector2 buttonPositions[BUTTON_MAX] = + { + { padPosition.x,padPosition.y - buttonRadius*1.5f }, // Up + { padPosition.x - buttonRadius*1.5f, padPosition.y }, // Left + { padPosition.x + buttonRadius*1.5f, padPosition.y }, // Right + { padPosition.x, padPosition.y + buttonRadius*1.5f } // Down + }; + + const char *buttonLabels[BUTTON_MAX] = + { + "Y", // Up + "X", // Left + "B", // Right + "A" // Down + }; - - const float dpadCollider[4][2]= // collider array with x,y position + Color buttonLabelColors[BUTTON_MAX] = { - {dpadX,dpadY-dpadRad*1.5f},//up - {dpadX-dpadRad*1.5f,dpadY},//left - {dpadX+dpadRad*1.5f,dpadY},//right - {dpadX,dpadY+dpadRad*1.5f}//down + YELLOW, // Up + BLUE, // Left + RED, // Right + GREEN // Down }; - const char dpadLabel[4]="XYBA";//label of Dpad - float playerX=100; - float playerY=100; + int pressedButton = BUTTON_NONE; + Vector2 inputPosition = { 0, 0 }; + + Vector2 playerPosition = { (float)screenWidth/2, (float)screenHeight/2 }; + float playerSpeed = 75; SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -54,63 +79,89 @@ int main(void) // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { - // Update - //-------------------------------------------------------------------------- - dpadKeydown = -1; //reset - int inputX = 0; - int inputY = 0; - if(GetTouchPointCount()>0) - {//use touch pos - inputX = GetTouchX(); - inputY = GetTouchY(); + // Update + //-------------------------------------------------------------------------- + if ((GetTouchPointCount() > 0)) + { + // Use touch position + inputPosition = GetTouchPosition(0); } else - {//use mouse pos - inputX = GetMouseX(); - inputY = GetMouseY(); + { + // Use mouse position + inputPosition = GetMousePosition(); } - for(int i=0;i<4;i++) + + // Reset pressed button to none + pressedButton = BUTTON_NONE; + + // Make sure user is pressing left mouse button if they're from desktop + if ((GetTouchPointCount() > 0) || ((GetTouchPointCount() == 0) && IsMouseButtonDown(MOUSE_BUTTON_LEFT))) { - //test distance each collider and input < radius - if( fabsf(dpadCollider[i][1]-inputY) + fabsf(dpadCollider[i][0]-inputX) < dpadRad) + // Find nearest D-Pad button to the input position + for (int i = 0; i < BUTTON_MAX; i++) { - dpadKeydown = i; - break; + float distX = fabsf(buttonPositions[i].x - inputPosition.x); + float distY = fabsf(buttonPositions[i].y - inputPosition.y); + + if ((distX + distY < buttonRadius)) + { + pressedButton = i; + break; + } } } - // move player - switch(dpadKeydown){ - case 0: playerY -= 50*GetFrameTime(); - break; - case 1: playerX -= 50*GetFrameTime(); - break; - case 2: playerX += 50*GetFrameTime(); - break; - case 3: playerY += 50*GetFrameTime(); - default:; + + // Move player according to pressed button + switch (pressedButton) + { + case BUTTON_UP: + { + playerPosition.y -= playerSpeed*GetFrameTime(); + break; + } + case BUTTON_LEFT: + { + playerPosition.x -= playerSpeed*GetFrameTime(); + break; + } + case BUTTON_RIGHT: + { + playerPosition.x += playerSpeed*GetFrameTime(); + break; + } + case BUTTON_DOWN: + { + playerPosition.y += playerSpeed*GetFrameTime(); + break; + } + default: break; }; - //-------------------------------------------------------------------------- - // Draw - //-------------------------------------------------------------------------- - BeginDrawing(); + + //-------------------------------------------------------------------------- + // Draw + //-------------------------------------------------------------------------- + BeginDrawing(); + ClearBackground(RAYWHITE); - for(int i=0;i<4;i++) + + // Draw world + DrawCircleV(playerPosition, 50, MAROON); + + // Draw GUI + for (int i = 0; i < BUTTON_MAX; i++) { - //draw all pad - DrawCircleV((Vector2) { dpadCollider[i][0], dpadCollider[i][1] }, dpadRad, dpadColor); - if(i!=dpadKeydown) - { - //draw label - DrawText(TextSubtext(dpadLabel,i,1), - (int)dpadCollider[i][0]-7, - (int)dpadCollider[i][1]-8,20,BLACK); - } + DrawCircleV(buttonPositions[i], buttonRadius, (i == pressedButton)? DARKGRAY : BLACK); + + DrawText(buttonLabels[i], + (int)buttonPositions[i].x - 7, (int)buttonPositions[i].y - 8, + 20, buttonLabelColors[i]); } - DrawRectangleRec((Rectangle) { playerX - 4, playerY - 4, 75, 28 }, RED); - DrawText("Player", (int)playerX, (int)playerY, 20, WHITE); + DrawText("move the player with D-Pad buttons", 10, 10, 20, DARKGRAY); + EndDrawing(); - //-------------------------------------------------------------------------- + //-------------------------------------------------------------------------- } // De-Initialization diff --git a/examples/core/core_input_virtual_controls.png b/examples/core/core_input_virtual_controls.png index cb1444598017b9d7ff83480f66909c8523ece519..83097a54ca46ebed8c1958e4ed7854cbbd2286a6 100644 GIT binary patch literal 1802 zcmbVMdpJ~E6hC8T@+zP+%e_WKxE0ZxyhfA4(Bm@X?laUM_s_e(Z=d~JzqR&WXRZA^=d7!<{URkTB?y8R z(P`V~I>}7;fhozAKm&ew-QV z54kb}+2MxHcJ8p5p|PQ{Z-v`J5F_ySq_gPsb&vuuh>#YJ2;l&708@J&gExlAIJ}IP z1K1cR2dRP88_d8&f{Z@|FgC^`aL{{D*pKx;Ng?3k$wLGXiEJ=Ia5v^o#WE6a%$;-z zU~I^NbLC`_Zk8JXn%`xNAei?ge?Z#S;6VlZF4MQ6?vbxPy`2eqy&Y=o#aqUjli70k zJvZ=o*ZUylUrj=ku>Q#Vl%XKesr8n#RwN`cal?d7JW3s1 zv9kBm$WC5Ey=r&#=Sou0v7BU>>0C;E^j>hOZaQUj^9;XJ6793{SO~Wc7t=N@?j!fB z9_P&`=G^~7vN-?JYJ zJsg3Xq2}mk6vr*<%)XpgW0s^}e$ktfN{;grvsHZ`zp^dKpe;d#3TgQ@Ym(BNCKNRa zy7R}50QZQp@8c+Q-~vq1*xopYanVrUv1!#j8O(%%VN!TDD)gPp_Pcy)a8{ z;2X7vO|W!kDEAfD$~ajMmM@qbmPaq>(=yF{TdXp%nmS5}k|)jIrz+B`Vd-MM=>i1o}c%RK3;IaIyA~@1uP*%es&= z3j`-H=&w-Mf`x5l$6dVu7OiSyjaip6i#G@WPJxCKZ*dmT( zKQHw3D4^>Xd*XJ*EESg^dC(I~fpG56WL!k1Ho>+p{WkQ+4=RuURUNTXm zpmK}wa}>9Xng4Wk%F4i~p^K*XNk9K3f5kgYs^*mm8>%#8V2q{PId8kY^+4ReKF!R@ literal 9094 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 H{`@}x#HYs#