Przeglądaj źródła

Merge pull request #104 from victorfisac/develop

Physac redesign complete
pull/107/head
Ray 9 lat temu
rodzic
commit
db3dd9d200
7 zmienionych plików z 68 dodań i 40 usunięć
  1. +6
    -3
      examples/physics_basic_rigidbody.c
  2. BIN
      examples/physics_basic_rigidbody.png
  3. +31
    -9
      examples/physics_forces.c
  4. BIN
      examples/physics_forces.png
  5. +26
    -23
      src/physac.c
  6. +3
    -3
      src/physac.h
  7. +2
    -2
      src/raylib.h

+ 6
- 3
examples/physics_basic_rigidbody.c Wyświetl plik

@ -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);

BIN
examples/physics_basic_rigidbody.png Wyświetl plik

Przed Po
Szerokość: 800  |  Wysokość: 450  |  Rozmiar: 18 KiB Szerokość: 800  |  Wysokość: 450  |  Rozmiar: 15 KiB

+ 31
- 9
examples/physics_forces.c Wyświetl plik

@ -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 Wyświetl plik

Przed Po
Szerokość: 800  |  Wysokość: 450  |  Rozmiar: 18 KiB

+ 26
- 23
src/physac.c Wyświetl plik

@ -2,7 +2,7 @@
*
* [physac] raylib physics module - Basic functions to apply physics to 2D objects
*
* Copyright (c) 2015 Victor Fisac and Ramon Santamaria
* Copyright (c) 2016 Victor Fisac and Ramon Santamaria
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@ -75,10 +75,7 @@ void InitPhysics(Vector2 gravity)
void UpdatePhysics()
{
// Reset all physic objects is grounded state
for (int i = 0; i < physicObjectsCount; i++)
{
if (physicObjects[i]->rigidbody.enabled) physicObjects[i]->rigidbody.isGrounded = false;
}
for (int i = 0; i < physicObjectsCount; i++) physicObjects[i]->rigidbody.isGrounded = false;
for (int steps = 0; steps < PHYSICS_STEPS; steps++)
{
@ -537,26 +534,32 @@ void ApplyForceAtPosition(Vector2 position, float force, float radius)
{
for(int i = 0; i < physicObjectsCount; i++)
{
// Calculate direction and distance between force and physic object pposition
Vector2 distance = (Vector2){ physicObjects[i]->transform.position.x - position.x, physicObjects[i]->transform.position.y - position.y };
if(physicObjects[i]->collider.type == COLLIDER_RECTANGLE)
if(physicObjects[i]->rigidbody.enabled)
{
distance.x += physicObjects[i]->transform.scale.x/2;
distance.y += physicObjects[i]->transform.scale.y/2;
}
float distanceLength = Vector2Length(distance);
// Check if physic object is in force range
if(distanceLength <= radius)
{
// Normalize force direction
distance.x /= distanceLength;
distance.y /= -distanceLength;
// Calculate direction and distance between force and physic object pposition
Vector2 distance = (Vector2){ physicObjects[i]->transform.position.x - position.x, physicObjects[i]->transform.position.y - position.y };
if(physicObjects[i]->collider.type == COLLIDER_RECTANGLE)
{
distance.x += physicObjects[i]->transform.scale.x/2;
distance.y += physicObjects[i]->transform.scale.y/2;
}
float distanceLength = Vector2Length(distance);
// Apply force to the physic object
ApplyForce(physicObjects[i], (Vector2){ distance.x*force, distance.y*force });
// Check if physic object is in force range
if(distanceLength <= radius)
{
// Normalize force direction
distance.x /= distanceLength;
distance.y /= -distanceLength;
// Calculate final force
Vector2 finalForce = { distance.x*force, distance.y*force };
// Apply force to the physic object
ApplyForce(physicObjects[i], finalForce);
}
}
}
}

+ 3
- 3
src/physac.h Wyświetl plik

@ -2,7 +2,7 @@
*
* [physac] raylib physics module - Basic functions to apply physics to 2D objects
*
* Copyright (c) 2015 Victor Fisac and Ramon Santamaria
* Copyright (c) 2016 Victor Fisac and Ramon Santamaria
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@ -44,8 +44,8 @@ typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE } ColliderType;
typedef struct Transform {
Vector2 position;
float rotation;
Vector2 scale;
float rotation; // Radians (not used)
Vector2 scale; // Just for rectangle physic objects, for circle physic objects use collider radius and keep scale as { 0, 0 }
} Transform;
typedef struct Rigidbody {

+ 2
- 2
src/raylib.h Wyświetl plik

@ -498,8 +498,8 @@ typedef enum { COLLIDER_CIRCLE, COLLIDER_RECTANGLE } ColliderType;
typedef struct Transform {
Vector2 position;
float rotation;
Vector2 scale;
float rotation; // Radians (not used)
Vector2 scale; // Just for rectangle physic objects, for circle physic objects use collider radius and keep scale as { 0, 0 }
} Transform;
typedef struct Rigidbody {

Ładowanie…
Anuluj
Zapisz