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;
}
|