Skip to content

1. NoPhysicsLibrary

ArEss edited this page Jul 25, 2023 · 36 revisions

First Steps

The core class of this API is NoPhysicsLibrary. It is important to create in order to use the functionalities it provides.

First and foremost, read the Library ReadMe or the Home Page of this wiki and include No Physics Library into your code. Next, add the library's header in the desired script, as seen below:

#include "NoPhysicsLibrary.h"

After you've included the header file, verify that you can build the program and troubleshoot any issues.

It is now time to create the main variable, NoPhysicsLibrary. This variable contains all of the logic required for effective library iteration. If we were to draw a parallel between traditional Physics Libraries such as Box2D, the NoPhysicsLibrary variable would be the "world" where the physics are stepped.

You can make as many NoPhysicsLibrary instances as you wish, but it is best to limit yourself to one and reuse it. It is strongly advised to dynamically allocate the variable like follows:

NoPhysicsLibrary* library = nullptr;
library = new NoPhysicsLibrary();

Remember to use the delete keyword at the end of your code to dynamically deallocate it. Visit the CleanUp section for more information on how to properly erase this variable.

Having said that, let's review all the functions that the user can access within this variable:


Init

This is the first function that must be called once the NoPhysicsLibrary variable is created, otherwise an assert exception will be thrown. This function initializes the entire library.

Parameter Type Description
pixelsPerMeter float Describes how many pixels establishes a meter
return void -

Be careful to not initialize the library twice. In that case, an assert exception will be thrown.


Configure

Configure is an auxiliar method, so it do not provide any special functionality when called alone. Configure auxiliar method make sense, though, when the operator -> is added after it:

library->Configure()->

This method serves as a wrapper for a large number of other functions that share a common unique point. In this situation, their common goal is to configure various parts of the library. Go to the Library Config section to learn more about how to setup the library.

Parameter Type Description

| | return | const LibraryConfig* | Returns the configuration options inside |


SetPhysicsPreset

With this function, the user can set "library-defined" physic presets, to make the configuration of the world more agile. It does not allow "user-defined" physic presets, but it is not considered required at this stage of the library. It could be considered as a future feature if the community asks for it.

Parameter Type Description
preset PhysicsPreset Enum Determines which parameters to configure depending on the enum chosen
return void -

The internal parameters that this function modifies are: the global friction, the global gravity and the global restitution. All this parameters can be individually modified. Check Library Config for more information about what are those parameters and how to modify them individually.

Right now, it is under maintenance, because it only offers two possibilities:

PhysicsPreset Friction Gravity Restitution Description
NO_PHYSIC_PRESET (0, 0) (0, 0) (0, 0) Sets physics parameters to null
DEFAULT_PHYSICS_PRESET (0.5, 0) (0, 9.8) (0, 0) Sets classic platforming parameters

CreateBody

CreateBody is an auxiliar method, so it do not provide any special functionality when called alone. CreateBody auxiliar method make sense, though, when the operator -> is added after it:

library->CreateBody({})->

This method serves as a wrapper for a large number of other functions that share a common unique point. In this situation, their common goal is to create distinct body types. Go to the Body Creation section to learn more about how to create bodies.

This function has two overload possibilities:

Overload 1:

Parameter Type Description
rectangle PhysRect Defines the rectangle of the body which wants to be created
return const CreateBody* Returns the body creation options inside

Overload 2:

Parameter Type Description
x float Defines the top-left x position of the body rectangle
y float Defines the top-left y position of the body rectangle
width float Defines the width from left to right of the body rectangle
height float Defines the width from top to bottom of the body rectangle
return const CreateBody* Returns the body creation options inside

DestroyBody

Once you've created different bodies throughout the world, this method is in charge of erasing them. It has 3 different overloads, where two of them delete one specific body, and the other allows to delete all bodies of a kind.

Overload 1 (single):

Parameter Type Description
body Body* Asks for the body pointer to be deleted
return bool Returns whether the body has be deleted or not

Overload 2 (single):

Parameter Type Description
id PhysID Asks for the ID of the body to be deleted
return bool Returns whether the body has be deleted or not

Overload 3 (all-of-a-kind):

Parameter Type Description
clas BodyClass Asks for the body class to be completely erased
return bool Returns whether all bodies has been deleted or not

It is vital to note that in order to destroy a body during the library's update state, a pointer to it, or at least its PhysID variable, must be kept. Also, do not use this function to clear out the library of all the bodies that have been generated. More advice on how to correctly wipe the library can be found in the CleanUp section.


SetScenarioPreset

With this function, the user can automatically generate "library-defined" scenarios, to make the world building more agile. It does not allow "user-defined" scenario presets, but it is not considered required at this stage of the library. It could be considered as a future feature if the community asks for it.

Parameter Type Description
preset ScenarioPreset Enum Determines the built structure in the world
windowSize PhysVec Determines the width/height of the scenario. Input the size of your game's window
scenarioBodies std::vector<StaticBody*>* If it is not null, it assigns any StaticBodies created on the scenario to the vector (if the user requires them)
return void -

This function only creates StaticBody's to generate a scenario. By creating a std::vector before calling the function, the user can modify the given scenario. Look at this example:

#include "NoPhysicsLibrary.h"
#include "StaticBody.h"

std::vector<StaticBody*> scenario;
library->SetScenarioPreset(ScenarioPreset::LIMITS_SCENARIO_PRESET, PhysVec(1920, 1080), &scenario);
StaticBody* scenarioWall = scenario[0];
scenario.clear();

library->DestroyBody(scenarioWall);

In this code example, we see how the library generates a prefabricated scenario. Then, the function returns the vector of bodies that make up that scenario. Finally, the pointer to the first body is grabbed, to finally destroy it. With this, we would acquire the "LIMITS_SCENARIO_PRESET" scenario without the first static body.

Actually, this function is under revision to augment the amount of prefabricated scenario presets. This are the ones featured now:

ScenarioPreset Description Image
LIMITS_SCENARIO_PRESET Generates a scenario with limits on the window borders ?
PLATFORMER_SCENARIO_PRESET Sets the limit scenario plus various platforms to jump around ?
WALLJUMP_SCENARIO_PRESET Sets the limit scenario plus various vertical platforms to test wall jumps ?
CORRIDOR_SCENARIO_PRESET Sets a long corridor with limits ?

ReturnScenarioRect

The goal of this function is to accelerate the placement of a GasBody across the entire scenario. This function returns the rectangle that contains all of the previously generated bodies by doing specific calculations. Consider the following example:

// Body created at x = 10, y = 10, width = 10, height = 10
// Body created at x = 20, y = 30, width = 10, height = 30

library->ReturnScenarioRect(); // would return a rectangle at x = 10, y = 10, width = 20, height = 50

// Body created at x = 0, y = 0, width = 5, height = 5

library->ReturnScenarioRect(); // would return a rectangle at x = 0, y = 0, width = 30, height = 60

As you can see above, any rectangle constructed after calling the ReturnScenarioRect function will not be considered. Even though this function appears to have a fairly particular purpose, its applications are limitless if you are creative.

Parameter Type Description
return PhysRect The rectangle that englobes all bodies

LoadSound

The user can use this function to load an audio file into the library. The following formats are permitted:

  • WAV
  • MP3
  • FLAC
  • OGG
Parameter Type Description
path const char* Defines the path to the audio file to be loaded
return bool Returns whether the file could be loaded or not

IMPORTANT: All loaded audio inherits an ID, which is the order in which it is loaded. As an example, consider the PlaySound function:

library->LoadSound("A.wav"); // ID = 0
library->LoadSound("B.wav"); // ID = 1
library->LoadSound("C.wav"); // ID = 2

body->PlaySound(0); -> Referencing A.wav
body->PlaySound(1); -> Referencing B.wav
body->PlaySound(2); -> Referencing C.wav


Update

This is the library's core function, which steps through all of the physics, acoustics, and audio logic. It must be put in a constant iteration scope so that each frame is only called once.

It should be noted that this function uses all of the information passed to the library prior to its call. Consider the following scenario:

// bodyA->ApplyForce(-10,   0);
// bodyB->ApplyForce(  0,  10);

library->Update(dt);

// bodyC->ApplyForce(  0, -10);

The library will update the forces of bodyA and bodyB at this code iteration, however the force of bodyC will be operated in the following frame update.

Parameter Type Description
dt const float Defines the delta time of the application
return void -

It is highly recommended to implement an own-build delta time system, to feed accurate information to the Update function. However, if you do not have the delta time variable in your code, you can hardcode the value of "dt" by inputting the following division: 1 / frameRate, as follows:

const float frameRate = 60; // In case your code runs at 60 fps

library->Update(1/frameRate);

Note that this is a bad practice, and you should always have the delta time variable calculated each iteration. The physics must always be running at the application speed.


PausePhysics

This function let the user stop the physics iteration, leaving the scenario completely stopped.

Parameter Type Description
pause bool Defines wether the physics are paused or not
return void -

CleanUp

The major application of this function is to totally remove the world inside the NoPhysicsLibrary variable. After that, if the use of that variable is required, the user must call the Init function once more. It is important to note that this function deletes all data from every body generated, thus after calling it, you will be unable to retrieve information from any pointers you may have stored. Consider the following example:

bodyA->ID(); // you can access it

library->CleanUp();

bodyA->ID(); // accessing invalid data

Apart from destroying the bodies, the CleanUp function deletes all of the library's internal data. This means that the user must never erase any pointer to a body saved directly in their code by using the "delete" keyword. If it is necessary to delete a body, the DestroyBody function must be used.

Parameter Type Description
return void -

Get

Get is an auxiliar method, so it do not provide any special functionality when called alone. Get auxiliar method make sense, though, when the operator -> is added after it:

library->Get()->

This method serves as a wrapper for a large number of other functions that share a common unique point. In this situation, their common goal is to retrieve information of the library to the user. Go to the Get Data section to learn more about what data can be retrieved.

Overload 1:

Parameter Type Description
return const GetData* Returns the get data options inside