aboutsummaryrefslogtreecommitdiff
path: root/examples/physics_basic_rigidbody.c
blob: 87316a98189c529ce8972b60e39e218af75fd654 (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] example - Basic rigidbody
*
*   This example has been created using raylib 1.5 (www.raylib.com)
*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
*   NOTE:
*   Physac requires multi-threading, when InitPhysics() a second thread is created to manage
*   physics calculations. To accomplish that, physac uses pthread Win32 library that can be
*   found inside raylib/src/external/pthread directory. 
*
*   Add pthread library when compiling physac example:
*   gcc -o $(NAME_PART).exe $(FILE_NAME) $(RAYLIB_DIR)\raylib_icon -L../src/external/pthread/lib \
*   -I../src -I../src/external/pthread/include -lraylib -lglfw3 -lopengl32 -lgdi32 -lpthreadGC2 -std=c99 -Wall
*
*   Note that pthreadGC2.dll must be also copied to project directory!
*
*   Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5)
*
********************************************************************************************/

#include "raylib.h"

#define PHYSAC_IMPLEMENTATION
#include "physac.h"

#define MOVE_VELOCITY    5
#define JUMP_VELOCITY    30

int main()
{
    // Initialization
    //--------------------------------------------------------------------------------------
    int screenWidth = 800;
    int screenHeight = 450;

    InitWindow(screenWidth, screenHeight, "raylib [physac] example - basic rigidbody");
    InitPhysics((Vector2){ 0.0f, -9.81f/2 });      // Initialize physics module
    
    // Debug variables
    bool isDebug = false;
    
    // Create rectangle physic object
    PhysicBody rectangle = CreatePhysicBody((Vector2){ screenWidth*0.25f, screenHeight/2 }, 0.0f, (Vector2){ 75, 50 });
    rectangle->rigidbody.enabled = true;       // Enable physic object rigidbody behaviour
    rectangle->rigidbody.applyGravity = true;
    rectangle->rigidbody.friction = 0.1f;
    rectangle->rigidbody.bounciness = 6.0f;
    
    // Create square physic object
    PhysicBody square = CreatePhysicBody((Vector2){ screenWidth*0.75f, screenHeight/2 }, 0.0f, (Vector2){ 50, 50 });
    square->rigidbody.enabled = true;      // Enable physic object rigidbody behaviour
    square->rigidbody.applyGravity = true;
    square->rigidbody.friction = 0.1f;
    
    // Create walls physic objects
    PhysicBody floor = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight*0.95f }, 0.0f, (Vector2){ screenWidth*0.9f, 100 });
    PhysicBody leftWall = CreatePhysicBody((Vector2){ 0.0f, screenHeight/2 }, 0.0f, (Vector2){ screenWidth*0.1f, screenHeight });
    PhysicBody rightWall = CreatePhysicBody((Vector2){ screenWidth, screenHeight/2 }, 0.0f, (Vector2){ screenWidth*0.1f, screenHeight });
    PhysicBody roof = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight*0.05f }, 0.0f, (Vector2){ screenWidth*0.9f, 100 });
    
    // Create pplatform physic object
    PhysicBody platform = CreatePhysicBody((Vector2){ screenWidth/2, screenHeight*0.7f }, 0.0f, (Vector2){ screenWidth*0.25f, 20 });
    
    SetTargetFPS(60);
    //--------------------------------------------------------------------------------------

    // Main game loop
    while (!WindowShouldClose())    // Detect window close button or ESC key
    {
        // Update
        //----------------------------------------------------------------------------------        
        // Check rectangle movement inputs
        if (IsKeyPressed('W')) rectangle->rigidbody.velocity.y = JUMP_VELOCITY;
        if (IsKeyDown('A')) rectangle->rigidbody.velocity.x = -MOVE_VELOCITY;
        else if (IsKeyDown('D')) rectangle->rigidbody.velocity.x = MOVE_VELOCITY;
        
        // Check square movement inputs
        if (IsKeyDown(KEY_UP) && square->rigidbody.isGrounded) square->rigidbody.velocity.y = JUMP_VELOCITY;
        if (IsKeyDown(KEY_LEFT)) square->rigidbody.velocity.x = -MOVE_VELOCITY;
        else if (IsKeyDown(KEY_RIGHT)) square->rigidbody.velocity.x = MOVE_VELOCITY;
        
        // Check debug switch input
        if (IsKeyPressed('P')) isDebug = !isDebug;
        //----------------------------------------------------------------------------------

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

            ClearBackground(RAYWHITE);

            // Draw floor, roof and walls rectangles
            DrawRectangleRec(TransformToRectangle(floor->transform), DARKGRAY);         // Convert transform values to rectangle data type variable
            DrawRectangleRec(TransformToRectangle(leftWall->transform), DARKGRAY);
            DrawRectangleRec(TransformToRectangle(rightWall->transform), DARKGRAY);
            DrawRectangleRec(TransformToRectangle(roof->transform), DARKGRAY);
            
            // Draw middle platform rectangle
            DrawRectangleRec(TransformToRectangle(platform->transform), DARKGRAY);
            
            // Draw physic objects
            DrawRectangleRec(TransformToRectangle(rectangle->transform), RED);
            DrawRectangleRec(TransformToRectangle(square->transform), BLUE);
            
            // Draw collider lines if debug is enabled
            if (isDebug)
            {
                DrawRectangleLines(floor->collider.bounds.x, floor->collider.bounds.y, floor->collider.bounds.width, floor->collider.bounds.height, GREEN);
                DrawRectangleLines(leftWall->collider.bounds.x, leftWall->collider.bounds.y, leftWall->collider.bounds.width, leftWall->collider.bounds.height, GREEN);
                DrawRectangleLines(rightWall->collider.bounds.x, rightWall->collider.bounds.y, rightWall->collider.bounds.width, rightWall->collider.bounds.height, GREEN);
                DrawRectangleLines(roof->collider.bounds.x, roof->collider.bounds.y, roof->collider.bounds.width, roof->collider.bounds.height, GREEN);
                DrawRectangleLines(platform->collider.bounds.x, platform->collider.bounds.y, platform->collider.bounds.width, platform->collider.bounds.height, GREEN);
                DrawRectangleLines(rectangle->collider.bounds.x, rectangle->collider.bounds.y, rectangle->collider.bounds.width, rectangle->collider.bounds.height, GREEN);
                DrawRectangleLines(square->collider.bounds.x, square->collider.bounds.y, square->collider.bounds.width, square->collider.bounds.height, GREEN);
            }
            
            // Draw help message
            DrawText("Use WASD to move rectangle and ARROWS to move square", screenWidth/2 - MeasureText("Use WASD to move rectangle and ARROWS to move square", 20)/2, screenHeight*0.075f, 20, LIGHTGRAY);

            DrawFPS(10, 10);
            
        EndDrawing();
        //----------------------------------------------------------------------------------
    }

    // De-Initialization
    //--------------------------------------------------------------------------------------
    ClosePhysics();       // Unitialize physics (including all loaded objects)
    CloseWindow();        // Close window and OpenGL context
    //--------------------------------------------------------------------------------------

    return 0;
}