From e683fe88b9ab0fde76521a0367cdff4c229ac60c Mon Sep 17 00:00:00 2001 From: victorfisac Date: Mon, 21 Dec 2015 21:12:35 +0100 Subject: Added physics engine-module and example - Added new physics engine-module with four new data types: Physics, Transform, Rigidbody and Collider. This library contains functions to apply physics calculations to a position vector calculating collisions automatically. - Fixed some writing mistakes of lighting module. --- examples/physics_basic_rigidbody.c | 144 +++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 examples/physics_basic_rigidbody.c (limited to 'examples/physics_basic_rigidbody.c') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c new file mode 100644 index 00000000..2f3fffbc --- /dev/null +++ b/examples/physics_basic_rigidbody.c @@ -0,0 +1,144 @@ +/******************************************************************************************* +* +* raylib [physics] example - Basic rigidbody +* +* Welcome to raylib! +* +* To test examples, just press F6 and execute raylib_compile_execute script +* Note that compiled executable is placed in the same folder as .c file +* +* You can find all basic examples on C:\raylib\raylib\examples folder or +* raylib official webpage: www.raylib.com +* +* Enjoy using raylib. :) +* +* This example has been created using raylib 1.3 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#define OBJECT_SIZE 50 +#define PLAYER_INDEX 0 + +int main() +{ + // Initialization + //-------------------------------------------------------------------------------------- + int screenWidth = 800; + int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [physics] example - basic rigidbody"); + SetTargetFPS(60); // Enable v-sync + InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) + + // Physics initialization + Physics worldPhysics = {true, false, (Vector2){0, -9.81f}}; + + // Set internal physics settings + SetPhysics(worldPhysics); + + // Object initialization + Transform player = (Transform){(Vector2){(screenWidth - OBJECT_SIZE) / 2, (screenHeight - OBJECT_SIZE) / 2}, 0.0f, (Vector2){OBJECT_SIZE, OBJECT_SIZE}}; + AddCollider(PLAYER_INDEX, (Collider){true, RectangleCollider, (Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, 0}); + AddRigidbody(PLAYER_INDEX, (Rigidbody){true, 1.0f, (Vector2){0, 0}, (Vector2){0, 0}, false, false, true, 0.5f, 1.0f}); + + // 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(PLAYER_INDEX + 1, (Collider){true, RectangleCollider, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0}); + + // Object properties initialization + float moveSpeed = 6.0f; + float jumpForce = 4.5f; + //-------------------------------------------------------------------------------------- + + // 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) + ApplyPhysics(PLAYER_INDEX, &player.position); + + // Check jump button input + if(IsKeyDown(KEY_SPACE) && GetRigidbody(PLAYER_INDEX).isGrounded) + { + // Reset object Y velocity to avoid double jumping cases but keep the same X velocity that it already has + SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){GetRigidbody(PLAYER_INDEX).velocity.x, 0}); + + // Add jumping force in Y axis + AddRigidbodyForce(PLAYER_INDEX, (Vector2){0, jumpForce}); + } + + // Check movement buttons input + if(IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) + { + // Set rigidbody velocity in X based on moveSpeed value and apply the same Y velocity that it already has + SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){moveSpeed, GetRigidbody(PLAYER_INDEX).velocity.y}); + } + else if(IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) + { + // Set rigidbody velocity in X based on moveSpeed negative value and apply the same Y velocity that it already has + SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){-moveSpeed, GetRigidbody(PLAYER_INDEX).velocity.y}); + } + + // Check debug mode toggle button input + if(IsKeyPressed(KEY_P)) + { + // Update program physics value + worldPhysics.debug = !worldPhysics.debug; + + // Update internal physics value + SetPhysics(worldPhysics); + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + // Draw information + DrawText("Use LEFT / RIGHT to MOVE and SPACE to JUMP", (screenWidth - MeasureText("Use LEFT / RIGHT to MOVE and SPACE to JUMP", 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); + + // Check if debug mode is enabled + if(worldPhysics.debug) + { + // Draw every internal physics stored collider if it is active + for(int i = 0; i < 2; i++) + { + if(GetCollider(i).enabled) + { + DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN); + } + } + + } + else + { + // Draw player + DrawRectangleRec((Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, GRAY); + + // Draw floor + DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK); + } + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file -- cgit v1.2.3 From 6608c5a8a7be1ad0f94dc643ec0537338f6829de Mon Sep 17 00:00:00 2001 From: victorfisac Date: Sun, 3 Jan 2016 17:54:06 +0100 Subject: Fixed physics basic example example name --- examples/physics_basic_rigidbody.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples/physics_basic_rigidbody.c') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 2f3fffbc..17d6564f 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -1,6 +1,6 @@ /******************************************************************************************* * -* raylib [physics] example - Basic rigidbody +* raylib [physac] physics example - Basic rigidbody * * Welcome to raylib! * -- cgit v1.2.3 From c5663ca015e550ab8e2a43c10fa72db0aab7cac8 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Wed, 20 Jan 2016 19:09:48 +0100 Subject: Some formatting tweaks --- examples/physics_basic_rigidbody.c | 24 +++++++++++++----------- examples/physics_rigidbody_force.c | 37 ++++++++++++++++++++----------------- src/physac.c | 6 +++--- src/physac.h | 3 ++- src/raylib.h | 8 ++++---- 5 files changed, 42 insertions(+), 36 deletions(-) (limited to 'examples/physics_basic_rigidbody.c') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index 17d6564f..b82fe638 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -32,28 +32,30 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physics] example - basic rigidbody"); - SetTargetFPS(60); // Enable v-sync + InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) // Physics initialization - Physics worldPhysics = {true, false, (Vector2){0, -9.81f}}; + Physics worldPhysics = { true, false, (Vector2){ 0, -9.81f } }; // Set internal physics settings SetPhysics(worldPhysics); // Object initialization Transform player = (Transform){(Vector2){(screenWidth - OBJECT_SIZE) / 2, (screenHeight - OBJECT_SIZE) / 2}, 0.0f, (Vector2){OBJECT_SIZE, OBJECT_SIZE}}; - AddCollider(PLAYER_INDEX, (Collider){true, RectangleCollider, (Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, 0}); + AddCollider(PLAYER_INDEX, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, 0}); AddRigidbody(PLAYER_INDEX, (Rigidbody){true, 1.0f, (Vector2){0, 0}, (Vector2){0, 0}, false, false, true, 0.5f, 1.0f}); // 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(PLAYER_INDEX + 1, (Collider){true, RectangleCollider, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0}); + AddCollider(PLAYER_INDEX + 1, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0}); // Object properties initialization float moveSpeed = 6.0f; - float jumpForce = 4.5f; + float jumpForce = 5.0f; + + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -67,7 +69,7 @@ int main() ApplyPhysics(PLAYER_INDEX, &player.position); // Check jump button input - if(IsKeyDown(KEY_SPACE) && GetRigidbody(PLAYER_INDEX).isGrounded) + if (IsKeyDown(KEY_SPACE) && GetRigidbody(PLAYER_INDEX).isGrounded) { // Reset object Y velocity to avoid double jumping cases but keep the same X velocity that it already has SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){GetRigidbody(PLAYER_INDEX).velocity.x, 0}); @@ -77,12 +79,12 @@ int main() } // Check movement buttons input - if(IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) + if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) { // Set rigidbody velocity in X based on moveSpeed value and apply the same Y velocity that it already has SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){moveSpeed, GetRigidbody(PLAYER_INDEX).velocity.y}); } - else if(IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) + else if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) { // Set rigidbody velocity in X based on moveSpeed negative value and apply the same Y velocity that it already has SetRigidbodyVelocity(PLAYER_INDEX, (Vector2){-moveSpeed, GetRigidbody(PLAYER_INDEX).velocity.y}); @@ -110,12 +112,12 @@ int main() DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY); // Check if debug mode is enabled - if(worldPhysics.debug) + if (worldPhysics.debug) { // Draw every internal physics stored collider if it is active - for(int i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) { - if(GetCollider(i).enabled) + if (GetCollider(i).enabled) { DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN); } diff --git a/examples/physics_rigidbody_force.c b/examples/physics_rigidbody_force.c index 726e7c67..3ac560c5 100644 --- a/examples/physics_rigidbody_force.c +++ b/examples/physics_rigidbody_force.c @@ -11,11 +11,11 @@ #include "raylib.h" -#define MAX_OBJECTS 5 -#define OBJECTS_OFFSET 150 +#define MAX_OBJECTS 5 +#define OBJECTS_OFFSET 150 -#define FORCE_INTENSITY 250.0f // Customize by user -#define FORCE_RADIUS 100 // Customize by user +#define FORCE_INTENSITY 250.0f // Customize by user +#define FORCE_RADIUS 100 // Customize by user int main() { @@ -25,7 +25,7 @@ int main() int screenHeight = 450; InitWindow(screenWidth, screenHeight, "raylib [physics] example - rigidbodies forces"); - SetTargetFPS(60); // Enable v-sync + InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) // Physics initialization @@ -36,17 +36,20 @@ int main() // Objects initialization Transform objects[MAX_OBJECTS]; - for(int i = 0; i < MAX_OBJECTS; i++) + + 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, RectangleCollider, (Rectangle){objects[i].position.x, objects[i].position.y, objects[i].scale.x, objects[i].scale.y}, 0}); + 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, RectangleCollider, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0}); + AddCollider(MAX_OBJECTS, (Collider){true, COLLIDER_RECTANGLE, (Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, 0}); + + SetTargetFPS(60); //-------------------------------------------------------------------------------------- // Main game loop @@ -57,19 +60,19 @@ int main() // 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++) + for (int i = 0; i < MAX_OBJECTS; i++) { ApplyPhysics(i, &objects[i].position); } // Check foce button input - if(IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) + if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) { AddForceAtPosition(GetMousePosition(), FORCE_INTENSITY, FORCE_RADIUS); } // Check debug mode toggle button input - if(IsKeyPressed(KEY_P)) + if (IsKeyPressed(KEY_P)) { // Update program physics value worldPhysics.debug = !worldPhysics.debug; @@ -86,21 +89,21 @@ int main() ClearBackground(RAYWHITE); // Check if debug mode is enabled - if(worldPhysics.debug) + if (worldPhysics.debug) { // Draw every internal physics stored collider if it is active (floor included) - for(int i = 0; i < MAX_OBJECTS + 1; i++) + for (int i = 0; i < MAX_OBJECTS + 1; i++) { - if(GetCollider(i).enabled) + 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) + 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)) + 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); } @@ -114,7 +117,7 @@ int main() else { // Draw objects - for(int i = 0; i < MAX_OBJECTS; i++) + 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); } diff --git a/src/physac.c b/src/physac.c index 6e3b6e61..6dfdbb49 100644 --- a/src/physac.c +++ b/src/physac.c @@ -183,9 +183,9 @@ void ApplyPhysics(int index, Vector2 *position) { if (colliders[index].enabled && colliders[j].enabled) { - if (colliders[index].type == RectangleCollider) + if (colliders[index].type == COLLIDER_RECTANGLE) { - if (colliders[j].type == RectangleCollider) + if (colliders[j].type == COLLIDER_RECTANGLE) { if (CheckCollisionRecs(colliders[index].bounds, colliders[j].bounds)) { @@ -207,7 +207,7 @@ void ApplyPhysics(int index, Vector2 *position) } else { - if (colliders[j].type == RectangleCollider) + if (colliders[j].type == COLLIDER_RECTANGLE) { if (CheckCollisionCircleRec((Vector2){colliders[index].bounds.x, colliders[index].bounds.y}, colliders[index].radius, colliders[j].bounds)) { diff --git a/src/physac.h b/src/physac.h index 558673ef..a1501ee3 100644 --- a/src/physac.h +++ b/src/physac.h @@ -32,7 +32,8 @@ //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- -typedef enum { RectangleCollider, CircleCollider } ColliderType; +// Collider types +typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType; // Physics struct typedef struct Physics { diff --git a/src/raylib.h b/src/raylib.h index 0a768fe4..5798d907 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -463,12 +463,12 @@ typedef struct { typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; // Collider types -typedef enum { RectangleCollider, CircleCollider } ColliderType; +typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType; // Physics struct typedef struct Physics { bool enabled; - bool debug; // Should be used by programmer for testing purposes + bool debug; // Should be used by programmer for testing purposes Vector2 gravity; } Physics; @@ -496,8 +496,8 @@ typedef struct Rigidbody { typedef struct Collider { bool enabled; ColliderType type; - Rectangle bounds; // Just used for RectangleCollider type - int radius; // Just used for CircleCollider type + Rectangle bounds; // Used for COLLIDER_RECTANGLE and COLLIDER_CAPSULE + int radius; // Used for COLLIDER_CIRCLE and COLLIDER_CAPSULE } Collider; #ifdef __cplusplus -- cgit v1.2.3 From ed1906440560d5b6b6e2cb1c1927e53b28e302db Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 13 Feb 2016 17:09:53 +0100 Subject: Reviewed physics module A deeper revision required, not clear enough for the user Key: Create a PhysicObjects pool --- examples/physics_basic_rigidbody.c | 44 +++++++-------------------- examples/physics_rigidbody_force.c | 33 ++++++++------------- src/physac.c | 61 ++++++++++++++++++++++---------------- src/physac.h | 11 ++----- src/raylib.h | 13 ++------ 5 files changed, 64 insertions(+), 98 deletions(-) (limited to 'examples/physics_basic_rigidbody.c') diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c index b82fe638..6c354eb7 100644 --- a/examples/physics_basic_rigidbody.c +++ b/examples/physics_basic_rigidbody.c @@ -2,20 +2,10 @@ * * raylib [physac] physics example - Basic rigidbody * -* Welcome to raylib! -* -* To test examples, just press F6 and execute raylib_compile_execute script -* Note that compiled executable is placed in the same folder as .c file -* -* You can find all basic examples on C:\raylib\raylib\examples folder or -* raylib official webpage: www.raylib.com -* -* Enjoy using raylib. :) -* -* This example has been created using raylib 1.3 (www.raylib.com) +* 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) 2015 Ramon Santamaria (@raysan5) +* Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -33,13 +23,7 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [physics] example - basic rigidbody"); - InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) - - // Physics initialization - Physics worldPhysics = { true, false, (Vector2){ 0, -9.81f } }; - - // Set internal physics settings - SetPhysics(worldPhysics); + InitPhysics(3); // Initialize physics system with maximum physic objects // Object initialization Transform player = (Transform){(Vector2){(screenWidth - OBJECT_SIZE) / 2, (screenHeight - OBJECT_SIZE) / 2}, 0.0f, (Vector2){OBJECT_SIZE, OBJECT_SIZE}}; @@ -55,6 +39,8 @@ int main() float moveSpeed = 6.0f; float jumpForce = 5.0f; + bool physicsDebug = false; + SetTargetFPS(60); //-------------------------------------------------------------------------------------- @@ -91,14 +77,7 @@ int main() } // Check debug mode toggle button input - if(IsKeyPressed(KEY_P)) - { - // Update program physics value - worldPhysics.debug = !worldPhysics.debug; - - // Update internal physics value - SetPhysics(worldPhysics); - } + if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug; //---------------------------------------------------------------------------------- // Draw @@ -112,7 +91,7 @@ int main() DrawText("Use P to switch DEBUG MODE", (screenWidth - MeasureText("Use P to switch DEBUG MODE", 20)) / 2, screenHeight * 0.3f, 20, LIGHTGRAY); // Check if debug mode is enabled - if (worldPhysics.debug) + if (physicsDebug) { // Draw every internal physics stored collider if it is active for (int i = 0; i < 2; i++) @@ -122,14 +101,11 @@ int main() DrawRectangleLines(GetCollider(i).bounds.x, GetCollider(i).bounds.y, GetCollider(i).bounds.width, GetCollider(i).bounds.height, GREEN); } } - } else { - // Draw player + // Draw player and floor DrawRectangleRec((Rectangle){player.position.x, player.position.y, player.scale.x, player.scale.y}, GRAY); - - // Draw floor DrawRectangleRec((Rectangle){floor.position.x, floor.position.y, floor.scale.x, floor.scale.y}, BLACK); } @@ -138,7 +114,9 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- + UnloadPhysics(); // Unload physic objects + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/physics_rigidbody_force.c b/examples/physics_rigidbody_force.c index 3ac560c5..74a88a97 100644 --- a/examples/physics_rigidbody_force.c +++ b/examples/physics_rigidbody_force.c @@ -2,10 +2,10 @@ * * raylib [physac] physics example - Rigidbody forces * -* This example has been created using raylib 1.3 (www.raylib.com) +* 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) 2014 Ramon Santamaria (@raysan5) +* Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -26,15 +26,9 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [physics] example - rigidbodies forces"); - InitPhysics(); // Initialize internal physics values (max rigidbodies/colliders available: 1024) + InitPhysics(MAX_OBJECTS + 1); // Initialize physics system with maximum physic objects - // Physics initialization - Physics worldPhysics = {true, false, (Vector2){0, -9.81f}}; - - // Set internal physics settings - SetPhysics(worldPhysics); - - // Objects initialization + // Physic Objects initialization Transform objects[MAX_OBJECTS]; for (int i = 0; i < MAX_OBJECTS; i++) @@ -49,6 +43,8 @@ int main() 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); //-------------------------------------------------------------------------------------- @@ -72,14 +68,7 @@ int main() } // Check debug mode toggle button input - if (IsKeyPressed(KEY_P)) - { - // Update program physics value - worldPhysics.debug = !worldPhysics.debug; - - // Update internal physics value - SetPhysics(worldPhysics); - } + if (IsKeyPressed(KEY_P)) physicsDebug = !physicsDebug; //---------------------------------------------------------------------------------- // Draw @@ -89,10 +78,10 @@ int main() ClearBackground(RAYWHITE); // Check if debug mode is enabled - if (worldPhysics.debug) + if (physicsDebug) { // Draw every internal physics stored collider if it is active (floor included) - for (int i = 0; i < MAX_OBJECTS + 1; i++) + for (int i = 0; i < MAX_OBJECTS; i++) { if (GetCollider(i).enabled) { @@ -136,7 +125,9 @@ int main() } // De-Initialization - //-------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------- + UnloadPhysics(); // Unload physic objects + CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/src/physac.c b/src/physac.c index 891f0123..4c50dd41 100644 --- a/src/physac.c +++ b/src/physac.c @@ -30,13 +30,12 @@ #endif #include -#include +#include // Required for: malloc(), free() //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -#define MAX_ELEMENTS 1024 // Stored rigidbodies and colliders array length -#define DECIMAL_FIX 0.26f // Decimal margin for collision checks (avoid rigidbodies shake) +#define DECIMAL_FIX 0.26f // Decimal margin for collision checks (avoid rigidbodies shake) //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -46,10 +45,13 @@ //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -static Physics physics; -static Collider colliders[MAX_ELEMENTS]; -static Rigidbody rigidbodies[MAX_ELEMENTS]; -static bool collisionChecker = false; +static Collider *colliders; // Colliders array, dynamically allocated at runtime +static Rigidbody *rigidbodies; // Rigitbody array, dynamically allocated at runtime +static bool collisionChecker; + +static int maxElements; // Max physic elements to compute +static bool enabled; // Physics enabled? (true by default) +static Vector2 gravity; // Gravity value used for physic calculations //---------------------------------------------------------------------------------- // Module specific Functions Declarations @@ -61,30 +63,39 @@ static void Vector2Normalize(Vector2 *vector); //---------------------------------------------------------------------------------- // Module Functions Definitions //---------------------------------------------------------------------------------- -void InitPhysics(void) -{ - for (int i = 0; i < MAX_ELEMENTS; i++) +void InitPhysics(int maxPhysicElements) +{ + maxElements = maxPhysicElements; + + colliders = (Collider *)malloc(maxElements*sizeof(Collider)); + rigidbodies = (Rigidbody *)malloc(maxElements*sizeof(Rigidbody)); + + for (int i = 0; i < maxElements; i++) { + colliders[i].enabled = false; + colliders[i].bounds = (Rectangle){ 0, 0, 0, 0 }; + colliders[i].radius = 0; + rigidbodies[i].enabled = false; rigidbodies[i].mass = 0.0f; - rigidbodies[i].velocity = (Vector2){0, 0}; - rigidbodies[i].acceleration = (Vector2){0, 0}; + rigidbodies[i].velocity = (Vector2){ 0.0f, 0.0f }; + rigidbodies[i].acceleration = (Vector2){ 0.0f, 0.0f }; rigidbodies[i].isGrounded = false; rigidbodies[i].isContact = false; rigidbodies[i].friction = 0.0f; - - colliders[i].enabled = false; - colliders[i].bounds = (Rectangle){0, 0, 0, 0}; - colliders[i].radius = 0; } + + collisionChecker = false; + enabled = true; + + // NOTE: To get better results, gravity needs to be 1:10 from original parameter + gravity = (Vector2){ 0.0f, -9.81f/10.0f }; // By default, standard gravity } -void SetPhysics(Physics settings) +void UnloadPhysics() { - physics = settings; - - // To get good results, gravity needs to be 1:10 from original parameter - physics.gravity = (Vector2){physics.gravity.x / 10, physics.gravity.y / 10}; + free(colliders); + free(rigidbodies); } void AddCollider(int index, Collider collider) @@ -159,8 +170,8 @@ void ApplyPhysics(int index, Vector2 *position) } // Apply gravity - rigidbodies[index].velocity.y += physics.gravity.y; - rigidbodies[index].velocity.x += physics.gravity.x; + rigidbodies[index].velocity.y += gravity.y; + rigidbodies[index].velocity.x += gravity.x; // Apply acceleration rigidbodies[index].velocity.y += rigidbodies[index].acceleration.y; @@ -177,7 +188,7 @@ void ApplyPhysics(int index, Vector2 *position) // Check collision with other colliders collisionChecker = false; rigidbodies[index].isContact = false; - for (int j = 0; j < MAX_ELEMENTS; j++) + for (int j = 0; j < maxElements; j++) { if (index != j) { @@ -269,7 +280,7 @@ void AddRigidbodyForce(int index, Vector2 force) void AddForceAtPosition(Vector2 position, float intensity, float radius) { - for(int i = 0; i < MAX_ELEMENTS; i++) + for(int i = 0; i < maxElements; i++) { if(rigidbodies[i].enabled) { diff --git a/src/physac.h b/src/physac.h index 12209987..9e1b0b88 100644 --- a/src/physac.h +++ b/src/physac.h @@ -35,13 +35,6 @@ // Collider types typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType; -// Physics struct -typedef struct Physics { - bool enabled; - bool debug; // Should be used by programmer for testing purposes - Vector2 gravity; -} Physics; - // Transform struct typedef struct Transform { Vector2 position; @@ -77,8 +70,8 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- // Module Functions Declarations //---------------------------------------------------------------------------------- -void InitPhysics(void); // Initialize all internal physics values -void SetPhysics(Physics settings); // Set physics settings values using Physics data type to overwrite internal physics settings +void InitPhysics(int maxPhysicElements); // Initialize all internal physics values +void UnloadPhysics(); // Unload physic elements arrays void AddRigidbody(int index, Rigidbody rigidbody); // Initialize a new rigidbody with parameters to internal index slot void AddCollider(int index, Collider collider); // Initialize a new Collider with parameters to internal index slot diff --git a/src/raylib.h b/src/raylib.h index c2067a0e..43819b14 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -466,13 +466,6 @@ typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERS // Collider types typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE, COLLIDER_CAPSULE } ColliderType; -// Physics struct -typedef struct Physics { - bool enabled; - bool debug; // Should be used by programmer for testing purposes - Vector2 gravity; -} Physics; - // Transform struct typedef struct Transform { Vector2 position; @@ -808,10 +801,10 @@ void SetShaderMap(Shader *shader, int mapLocation, Texture2D texture, int textur void SetBlendMode(int mode); // Set blending mode (alpha, additive, multiplied) //---------------------------------------------------------------------------------- -// Physics System Functions (engine-module: physics) +// Physics System Functions (engine-module: physac) //---------------------------------------------------------------------------------- -void InitPhysics(void); // Initialize all internal physics values -void SetPhysics(Physics settings); // Set physics settings values using Physics data type to overwrite internal physics settings +void InitPhysics(int maxPhysicElements); // Initialize all internal physics values +void UnloadPhysics(); // Unload physic elements arrays void AddRigidbody(int index, Rigidbody rigidbody); // Initialize a new rigidbody with parameters to internal index slot void AddCollider(int index, Collider collider); // Initialize a new Collider with parameters to internal index slot -- cgit v1.2.3