aboutsummaryrefslogtreecommitdiff
path: root/examples/physics_rigidbody_force.c
blob: 74a88a970a4bc87a449071b64a541f9977982d9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*******************************************************************************************
*
*   raylib [physac] physics example - Rigidbody forces
*
*   This example has been created using raylib 1.4 (www.raylib.com)
*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
*   Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5)
*
********************************************************************************************/

#include "raylib.h"

#define MAX_OBJECTS           5
#define OBJECTS_OFFSET      150

#define FORCE_INTENSITY  250.0f     // Customize by user
#define FORCE_RADIUS        100     // Customize by user    

int main()
{
    // Initialization
    //--------------------------------------------------------------------------------------
    int screenWidth = 800;
    int screenHeight = 450;
    
    InitWindow(screenWidth, screenHeight, "raylib [physics] example - rigidbodies forces");

    InitPhysics(MAX_OBJECTS + 1);      // Initialize physics system with maximum physic objects
    
    // Physic Objects initialization
    Transform objects[MAX_OBJECTS];
    
    for (int i = 0; i < MAX_OBJECTS; i++)
    {
        objects[i] = (Transform){(Vector2){75 + OBJECTS_OFFSET * i, (screenHeight - 50) / 2}, 0.0f, (Vector2){50, 50}};
        AddCollider(i, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){objects[i].position.x, objects[i].position.y, objects[i].scale.x, objects[i].scale.y}, 0});
        AddRigidbody(i, (Rigidbody){true, 1.0f, (Vector2){0, 0}, (Vector2){0, 0}, false, false, true, 0.5f, 0.5f});
    }
    
    // Floor initialization 
    // 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)
    Transform floor = (Transform){(Vector2){0, screenHeight * 0.8f}, 0.0f, (Vector2){screenWidth, screenHeight * 0.2f}};
    AddCollider(MAX_OBJECTS, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0});

    bool physicsDebug = false;
    
    SetTargetFPS(60);
    //--------------------------------------------------------------------------------------

    // Main game loop
    while (!WindowShouldClose())    // Detect window close button or ESC key
    {
        // Update
        //----------------------------------------------------------------------------------
        
        // Update object physics 
        // NOTE: all physics detections and reactions are calculated in ApplyPhysics() function (You will live happier :D)
        for (int i = 0; i < MAX_OBJECTS; i++)
        {
            ApplyPhysics(i, &objects[i].position);
        }
        
        // Check foce button input
        if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
        {
            AddForceAtPosition(GetMousePosition(), FORCE_INTENSITY, FORCE_RADIUS);
        }
        
        // Check debug mode toggle button input
        if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug;
        //----------------------------------------------------------------------------------

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

            ClearBackground(RAYWHITE);
            
            // Check if debug mode is enabled
            if (physicsDebug)
            {
                // Draw every internal physics stored collider if it is active (floor included)
                for (int i = 0; i < MAX_OBJECTS; i++)
                {
                    if (GetCollider(i).enabled)
                    {
                        // Draw collider bounds
                        DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN);
                        
                        // Check if current collider is not floor
                        if (i < MAX_OBJECTS)
                        {
                            // Draw lines between mouse position and objects if they are in force range
                            if (CheckCollisionPointCircle(GetMousePosition(), (Vector2){GetCollider(i).bounds.x + GetCollider(i).bounds.width / 2, GetCollider(i).bounds.y + GetCollider(i).bounds.height / 2}, FORCE_RADIUS))
                            {
                                DrawLineV(GetMousePosition(), (Vector2){GetCollider(i).bounds.x + GetCollider(i).bounds.width / 2, GetCollider(i).bounds.y + GetCollider(i).bounds.height / 2}, RED);
                            }
                        }
                    }
                }
                
                // Draw radius circle
                DrawCircleLines(GetMousePosition().x, GetMousePosition().y, FORCE_RADIUS, RED);
            }
            else
            {
                // Draw objects
                for (int i = 0; i < MAX_OBJECTS; i++)
                {
                    DrawRectangleRec((Rectangle){objects[i].position.x, objects[i].position.y, objects[i].scale.x, objects[i].scale.y}, GRAY);
                }
                
                // Draw floor
                DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK);
            }
            
                        
            // Draw help messages
            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);
            DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY);

        EndDrawing();
        //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    UnloadPhysics();      // Unload physic objects
    
    CloseWindow();        // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
}