physics_rigidbody_force.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*******************************************************************************************
  2. *
  3. * raylib [physac] physics example - Rigidbody forces
  4. *
  5. * This example has been created using raylib 1.4 (www.raylib.com)
  6. * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
  7. *
  8. * Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5)
  9. *
  10. ********************************************************************************************/
  11. #include "raylib.h"
  12. #define MAX_OBJECTS 5
  13. #define OBJECTS_OFFSET 150
  14. #define FORCE_INTENSITY 250.0f // Customize by user
  15. #define FORCE_RADIUS 100 // Customize by user
  16. int main()
  17. {
  18. // Initialization
  19. //--------------------------------------------------------------------------------------
  20. int screenWidth = 800;
  21. int screenHeight = 450;
  22. InitWindow(screenWidth, screenHeight, "raylib [physics] example - rigidbodies forces");
  23. InitPhysics(MAX_OBJECTS + 1); // Initialize physics system with maximum physic objects
  24. // Physic Objects initialization
  25. Transform objects[MAX_OBJECTS];
  26. for (int i = 0; i < MAX_OBJECTS; i++)
  27. {
  28. objects[i] = (Transform){(Vector2){75 + OBJECTS_OFFSET * i, (screenHeight - 50) / 2}, 0.0f, (Vector2){50, 50}};
  29. AddCollider(i, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){objects[i].position.x, objects[i].position.y, objects[i].scale.x, objects[i].scale.y}, 0});
  30. AddRigidbody(i, (Rigidbody){true, 1.0f, (Vector2){0, 0}, (Vector2){0, 0}, false, false, true, 0.5f, 0.5f});
  31. }
  32. // Floor initialization
  33. // NOTE: floor doesn't need a rigidbody because it's a static physic object, just a collider to collide with other dynamic colliders (with rigidbody)
  34. Transform floor = (Transform){(Vector2){0, screenHeight * 0.8f}, 0.0f, (Vector2){screenWidth, screenHeight * 0.2f}};
  35. AddCollider(MAX_OBJECTS, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0});
  36. bool physicsDebug = false;
  37. SetTargetFPS(60);
  38. //--------------------------------------------------------------------------------------
  39. // Main game loop
  40. while (!WindowShouldClose()) // Detect window close button or ESC key
  41. {
  42. // Update
  43. //----------------------------------------------------------------------------------
  44. // Update object physics
  45. // NOTE: all physics detections and reactions are calculated in ApplyPhysics() function (You will live happier :D)
  46. for (int i = 0; i < MAX_OBJECTS; i++)
  47. {
  48. ApplyPhysics(i, &objects[i].position);
  49. }
  50. // Check foce button input
  51. if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
  52. {
  53. AddForceAtPosition(GetMousePosition(), FORCE_INTENSITY, FORCE_RADIUS);
  54. }
  55. // Check debug mode toggle button input
  56. if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug;
  57. //----------------------------------------------------------------------------------
  58. // Draw
  59. //----------------------------------------------------------------------------------
  60. BeginDrawing();
  61. ClearBackground(RAYWHITE);
  62. // Check if debug mode is enabled
  63. if (physicsDebug)
  64. {
  65. // Draw every internal physics stored collider if it is active (floor included)
  66. for (int i = 0; i < MAX_OBJECTS; i++)
  67. {
  68. if (GetCollider(i).enabled)
  69. {
  70. // Draw collider bounds
  71. DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN);
  72. // Check if current collider is not floor
  73. if (i < MAX_OBJECTS)
  74. {
  75. // Draw lines between mouse position and objects if they are in force range
  76. if (CheckCollisionPointCircle(GetMousePosition(), (Vector2){GetCollider(i).bounds.x + GetCollider(i).bounds.width / 2, GetCollider(i).bounds.y + GetCollider(i).bounds.height / 2}, FORCE_RADIUS))
  77. {
  78. DrawLineV(GetMousePosition(), (Vector2){GetCollider(i).bounds.x + GetCollider(i).bounds.width / 2, GetCollider(i).bounds.y + GetCollider(i).bounds.height / 2}, RED);
  79. }
  80. }
  81. }
  82. }
  83. // Draw radius circle
  84. DrawCircleLines(GetMousePosition().x, GetMousePosition().y, FORCE_RADIUS, RED);
  85. }
  86. else
  87. {
  88. // Draw objects
  89. for (int i = 0; i < MAX_OBJECTS; i++)
  90. {
  91. DrawRectangleRec((Rectangle){objects[i].position.x, objects[i].position.y, objects[i].scale.x, objects[i].scale.y}, GRAY);
  92. }
  93. // Draw floor
  94. DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK);
  95. }
  96. // Draw help messages
  97. DrawText("Use LEFT MOUSE BUTTON to create a force in mouse position", (screenWidth - MeasureText("Use LEFT MOUSE BUTTON to create a force in mouse position", 20)) / 2, screenHeight * 0.20f, 20, LIGHTGRAY);
  98. DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY);
  99. EndDrawing();
  100. //----------------------------------------------------------------------------------
  101. }
  102. // De-Initialization
  103. //--------------------------------------------------------------------------------------
  104. UnloadPhysics(); // Unload physic objects
  105. CloseWindow(); // Close window and OpenGL context
  106. //--------------------------------------------------------------------------------------
  107. return 0;
  108. }