Physac redesign (3/3)

Finally, physics update is handled in main thread using steps to get
accuracy in collisions detection instead of moving it to a new thread.

Examples are finished as simple and clear as I could. Finally, physac
module is MORE simpler than in the first version, calculation everything
by the same way for both types of physic objects.

I tryed to add rotated physics a couple of times but I didn't get
anything good to get a base to improve it. Maybe for the next version...

No bugs or strange behaviours found during testing.
This commit is contained in:
victorfisac 2016-03-23 15:50:41 +01:00
parent c453ac8265
commit 60223a358b
7 changed files with 68 additions and 40 deletions

View file

@ -65,7 +65,7 @@ int main()
if (IsKeyDown('A')) rectangle->rigidbody.velocity.x = -MOVE_VELOCITY;
else if (IsKeyDown('D')) rectangle->rigidbody.velocity.x = MOVE_VELOCITY;
// Check player 2 movement inputs
// 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;
@ -80,17 +80,20 @@ int main()
ClearBackground(RAYWHITE);
// Convert transform values to rectangle data type variable
DrawRectangleRec(TransformToRectangle(floor->transform), DARKGRAY);
// 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);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before After
Before After

View file

@ -12,9 +12,12 @@
#include "raylib.h"
#include "math.h"
#define FORCE_AMOUNT 5.0f
#define FORCE_RADIUS 150
#define LINE_LENGTH 100
#define FORCE_AMOUNT 5.0f
#define FORCE_RADIUS 150
#define LINE_LENGTH 75
#define TRIANGLE_LENGTH 12
void DrawRigidbodyCircle(PhysicObject *obj, Color color);
int main()
{
@ -42,6 +45,7 @@ int main()
}
// Create circles physic objects
// NOTE: when creating circle physic objects, transform.scale must be { 0, 0 } and object radius must be defined in collider.radius and use this value to draw the circle.
PhysicObject *circles[3];
for (int i = 0; i < 3; i++)
{
@ -111,14 +115,23 @@ int main()
// Draw force radius
DrawCircleLines(mousePosition.x, mousePosition.y, FORCE_RADIUS, BLACK);
// Draw direction line
// Draw direction lines
if (CheckCollisionPointCircle((Vector2){ rectangles[i]->transform.position.x + rectangles[i]->transform.scale.x/2, rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 }, mousePosition, FORCE_RADIUS))
{
Vector2 direction = { rectangles[i]->transform.position.x + rectangles[i]->transform.scale.x/2 - mousePosition.x, rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 - mousePosition.y };
float angle = atan2l(direction.y, direction.x);
DrawLineV((Vector2){ rectangles[i]->transform.position.x + rectangles[i]->transform.scale.x/2, rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 },
(Vector2){ rectangles[i]->transform.position.x + rectangles[i]->transform.scale.x/2 + (cos(angle)*LINE_LENGTH), rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 + (sin(angle)*LINE_LENGTH) }, BLACK);
// Calculate arrow start and end positions
Vector2 startPosition = { rectangles[i]->transform.position.x + rectangles[i]->transform.scale.x/2, rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 };
Vector2 endPosition = { rectangles[i]->transform.position.x + rectangles[i]->transform.scale.x/2 + (cos(angle)*LINE_LENGTH), rectangles[i]->transform.position.y + rectangles[i]->transform.scale.y/2 + (sin(angle)*LINE_LENGTH) };
// Draw arrow line
DrawLineV(startPosition, endPosition, BLACK);
// Draw arrow triangle
DrawTriangleLines((Vector2){ endPosition.x - cos(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH, endPosition.y - sin(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH },
(Vector2){ endPosition.x + cos(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH, endPosition.y + sin(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH },
(Vector2){ endPosition.x + cos(angle)*LINE_LENGTH/TRIANGLE_LENGTH*2, endPosition.y + sin(angle)*LINE_LENGTH/TRIANGLE_LENGTH*2 }, BLACK);
}
}
@ -131,14 +144,23 @@ int main()
// Draw force radius
DrawCircleLines(mousePosition.x, mousePosition.y, FORCE_RADIUS, BLACK);
// Draw direction line
// Draw direction lines
if (CheckCollisionPointCircle((Vector2){ circles[i]->transform.position.x, circles[i]->transform.position.y }, mousePosition, FORCE_RADIUS))
{
Vector2 direction = { circles[i]->transform.position.x - mousePosition.x, circles[i]->transform.position.y - mousePosition.y };
float angle = atan2l(direction.y, direction.x);
DrawLineV((Vector2){ circles[i]->transform.position.x, circles[i]->transform.position.y },
(Vector2){ circles[i]->transform.position.x + (cos(angle)*LINE_LENGTH), circles[i]->transform.position.y + (sin(angle)*LINE_LENGTH) }, BLACK);
// Calculate arrow start and end positions
Vector2 startPosition = { circles[i]->transform.position.x, circles[i]->transform.position.y };
Vector2 endPosition = { circles[i]->transform.position.x + (cos(angle)*LINE_LENGTH), circles[i]->transform.position.y + (sin(angle)*LINE_LENGTH) };
// Draw arrow line
DrawLineV(startPosition, endPosition, BLACK);
// Draw arrow triangle
DrawTriangleLines((Vector2){ endPosition.x - cos(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH, endPosition.y - sin(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH },
(Vector2){ endPosition.x + cos(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH, endPosition.y + sin(angle + 90*DEG2RAD)*LINE_LENGTH/TRIANGLE_LENGTH },
(Vector2){ endPosition.x + cos(angle)*LINE_LENGTH/TRIANGLE_LENGTH*2, endPosition.y + sin(angle)*LINE_LENGTH/TRIANGLE_LENGTH*2 }, BLACK);
}
}

BIN
examples/physics_forces.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB