Getting Started¶
Nova Physics is a lightweight 2D rigid body physics engine. It is designed with game development in mind. It is written in portable C with no dependencies other than the standard library, meaning anyone can easily write a binding for their favored programming language.
Nova Physics is, and always will be, free and open-source.
Hello World¶
After installing (you can follow installing), you are ready for your first Nova Physics program, where a ball free falls onto a ground and we print its coordinates every step.
1#include <stdio.h>
2#include "novaphysics/novaphysics.h"
3
4
5int main() {
6 // Create an empty simulation space
7 nvSpace *space = nvSpace_new();
8
9
10 /* Create a ground body with a rectangle shape. */
11
12 // The initializer struct is used to set basic properties of a body before creation.
13 // Making the motion type static means the body will never move under simulation.
14 nvRigidBodyInitializer body_init = nvRigidBodyInitializer_default;
15 body_init.type = nvRigidBodyType_STATIC;
16 body_init.position = NV_VECTOR2(0.0, 20.0); // NV_VECTOR2 is a utility macro to quickly initialize vectors.
17 body_init.material = nvMaterial_CONCRETE; // You can initialize a custom material as well.
18 nvRigidBody *ground = nvRigidBody_new(body_init);
19
20 // After creating the rigid body, we have to assign a shape.
21 nvShape *ground_shape = nvBoxShape_new(10.0, 1.0, nvVector2_zero);
22 nvRigidBody_add_shape(ground, ground_shape);
23
24 // We can finally add ground body to space.
25 nvSpace_add_rigidbody(space, ground);
26
27
28 /* Now create a ball that is going to fall and bounce off the ground. */
29
30 // We can use the same initializer struct by changing the necessary fields.
31 // This time the motion type have to by dynamic so the ball can be simulated under physical forces.
32 // We also initialize a custom material with restitution 0.85, so it can bounce
33 body_init.type = nvRigidBodyType_DYNAMIC;
34 body_init.position = NV_VECTOR2(0.0, 0.0);
35 body_init.material = (nvMaterial){.density=1.0, .restitution=0.85, .friction=0.1};
36 nvRigidBody *ball = nvRigidBody_new(body_init);
37
38 // Now we assign a circle shape to our body with radius 1.0
39 nvShape *ball_shape = nvCircleShape(nvVector2_zero, 1.0);
40 nvRigidBody_add_shape(ball, ball_shape);
41
42 nvSpace_add_rigidbody(space, ground);
43
44
45 /* The scene is set up. Now we only have to simulate it! */
46
47 // This is the time step length the engine going to simulate the space in.
48 nv_float dt = 1.0 / 60.0;
49
50 // Let's simulate for 5 seconds.
51 nv_float duration = 5.0;
52
53 for (nv_float t = 0.0; t < duration; t += dt) {
54 nvVector2 position = nvRigidBody_get_position(ball);
55 nvVector2 velocity = nvRigidBody_get_linear_velocity(ball);
56
57 printf(
58 "Ball is at (%.2f, %.2f) with velocity (%.2f, %.2f) at time %.2f.\n",
59 position.x, position.y,
60 velocity.x, velocity.y,
61 t
62 );
63
64 // Advance the simulation.
65 nvSpace_step(space, dt);
66 }
67
68 // Free the space and all resources it used.
69 // Space also manages the bodies, shapes and constraints we add to it.
70 // Unless you removed them manually, in that case you have to free your bodies.
71 nvSpace_free(space);
72}
When the code is run, we can see that the ball bounces on the ground few times and then rests.