Box2d hello world example

Here you can talk about anything related to BBC BASIC, not covered in another category
svein
Posts: 60
Joined: Tue 03 Apr 2018, 19:34

Box2d hello world example

Post by svein »

Looking in older folders, i found this hello world demo written by Richard 10 years ago.
I have updated procedure names and pointer sizes to make it work with the current Box2d library.
I have always struggled a bit with the relationship between the box2d output and pixels, debugdraw and the image overlay.

To make it easier (for me), i created 3 versions of the hello world demo.
1. Using only BBC graphics commands
2. Using only the debug draw interface
3. Using debugdraw and GFXlib for the image

This helped me a lot, hopefully someone else will find these demos useful too.
They work with both BB4W and BBCsdl.

Svein

Code: Select all

      REM 'BBC BASIC for Windows' implementation of the Hello Box2D example
      REM by Richard Russell, http://www.rtrussell.co.uk/, v0.0 21-Jan-2013
      REM Updated and modified by Svein Svensson Apr-2023

      REM This program creates a large ground box and a small dynamic box.
      REM Using BBC grapichs commands for the graphics.

      MODE 8 : OFF
      INSTALL @lib$+"BOX2DLIB" : PROC_b2Init

      ON CLOSE PROCcleanup : QUIT

      REM Descriptive text adapted from https://box2d.org/documentation/index.html

      REM ----------------------- Creating a World ------------------------

      REM Every Box2D program begins with the creation of a b2World object.
      REM The b2World is the physics hub that manages memory, objects, and
      REM simulation.

      REM It is easy to create a Box2D world.  First, we define the gravity:

      gravity_x = 0.0
      gravity_y = -10.0

      REM Now we create the world object:

      myWorld%% = FN_b2CreateWorld(gravity_x, gravity_y)

      REM Now we have our physics world, let's start adding some stuff to it.

      REM -------------------- Creating a Ground Box ----------------------

      REM Most Box2D simulations will have a Ground Box, which represents
      REM the floor or other surface through which objects cannot penetrate.
      REM The Ground Box is a static body; static bodies don't collide with
      REM other static bodies and are immovable.  To create the Ground Box
      REM we need to specify its position, orientation and size:

      REM Box2D works with floating point numbers and tolerances have to
      REM be used to make Box2D perform well.
      REM Box2D has been tuned to work well with moving shapes between 0.1 and 10 meters.
      REM MODE 8 = 640,512
      REM Divide window size by 100 to get a good world dimension with this window size
      REM Then multiply object positions by 100 to get pixel positions
      REM higher resolution window, say 1920*1200 may require 200 as division factor
      REM the goal is to get into the 0.1 - 10 range, or close to it.

      centre_x = 3.2     : REM 640/100/2
      centre_y = 0.0     : REM bottom of window
      angle = 0          : REM angle in radians
      half_width = 3.2   : REM 640/100/2
      half_height = 0.1  : REM visible ground, can be zero

      groundBox%% = FN_b2StaticBox(myWorld%%, centre_x, centre_y, angle, half_width, half_height)

      REM The dimensions are specified as the half-width and half-height.
      REM So in this case the ground box is 6.4 units wide (x-axis) and
      REM 0.2 units tall (y-axis).  Box2D is tuned for metres, kilograms,
      REM and seconds, so you can consider the dimensions to be in metres.

      REM Box2D generally works best when objects are the size of typical
      REM real world objects.  For example, a barrel is about 1 metre tall.
      REM Due to the limitations of floating point arithmetic, using Box2D
      REM to model glaciers or dust particles is not a good idea.

      REM -------------------- Creating a Dynamic Box ---------------------

      REM Dynamic boxes are built using the following steps:
      REM  1. Define a body with position, damping, etc.
      REM  2. Use the world object to create the body.
      REM  3. Define fixtures with a shape, friction, density, etc.
      REM  4. Create fixtures on the body.

      REM Step 1:  Define the initial position, orientation, velocity etc:

      REM MODE 8 = 640,512
      centre_x = 3.2
      centre_y = 5.12   : REM place the body at top of the window
      angle = 0.0
      velocity_x = 0.0
      velocity_y = 0.0
      velocity_a = 0.0
      damping_lin = 0.0
      damping_ang = 0.0

      REM Step 2:  Create the dynamic body using the world object:

      dynamicBody%% = FN_b2DynamicBody(myWorld%%, centre_x, centre_y, angle, \
      \              velocity_x, velocity_y, velocity_a, damping_lin, damping_ang)

      REM Step 3:  Define a fixture in the shape of a box.  Notice that
      REM          we set the density to 1.0 and the friction to 0.3:

      half_width = 0.1
      half_height = 0.1
      friction = 0.3
      restitution = 0.0
      density = 1.0

      REM Step 4.  Create and attach the fixture.  This updates the mass
      REM          of the body.  You can add as many fixtures as you like
      REM          to a body.  Each one contributes to the total mass:

      REM x,y,angle of the fixture is relative to the body's x,y,angle that the fixture is attached to.
      REM Note: you can't have a body without a fixture attached to it, (no mass)

      offx=0.0
      offy=0.0
      offangle=0.0
      myFixture%% = FN_b2BoxFixture(dynamicBody%%, offx, offy, offangle, \
      \            half_width, half_height, friction, restitution, density)

      REM That's it for initialization; we are now ready to begin simulating.

      REM --------------------- Simulating the World ----------------------

      REM We have initialized the ground box and a dynamic box.  Now we
      REM are ready to set Newton loose to do his thing.  We just have a
      REM couple more issues to consider.

      REM Box2D uses a computational algorithm called an integrator.
      REM Integrators simulate the physics equations at discrete points of
      REM time.  This goes along with the traditional game loop where we
      REM essentially have a flip book of movement on the screen.

      REM So we need to pick a time step.  Generally physics engines for
      REM games like a time step at least as fast as 60 Hz or 1/60 seconds.
      REM You can get away with larger time steps, but you will have to be
      REM more careful about setting up the definitions for your world.

      REM We also don't like the time step to change much.  A variable time
      REM step produces variable results, which makes it difficult to debug.
      REM So don't tie the time step to your frame rate (unless you really,
      REM really have to).  Without further ado, here is the time step:

      timeStep = 1/60

      REM In addition to the integrator, Box2D also uses a larger bit of code
      REM called a constraint solver.  The constraint solver solves all the
      REM constraints in the simulation, one at a time.  A single constraint
      REM can be solved perfectly.  However, when we solve one constraint,
      REM we slightly disrupt other constraints.  To get a good solution,
      REM we need to iterate over all constraints a number of times.

      REM There are two phases in the constraint solver: a velocity phase
      REM and a position phase.  In the velocity phase the solver computes
      REM the impulses necessary for the bodies to move correctly.  In the
      REM position phase the solver adjusts the positions of the bodies to
      REM reduce overlap and joint detachment.  Each phase has its own
      REM iteration count.  In addition, the position phase may exit
      REM iterations early if the errors are small.

      REM The suggested iteration count for Box2D is 8 for velocity and
      REM 3 for position.  You can tune this number to your liking, just
      REM keep in mind that this has a trade-off between speed and accuracy.
      REM Using fewer iterations increases performance but accuracy suffers.
      REM Likewise, using more iterations decreases performance but improves
      REM the quality of your simulation.  For this simple example, we don't
      REM need much iteration.  Here are our chosen iteration counts:

      velIterations% = 6
      posIterations% = 2

      REM Note that the time step and the iteration count are completely
      REM unrelated.  An iteration is not a sub-step.  One solver iteration
      REM is a single pass over all the constraints within a time step;
      REM you can have multiple passes over the constraints within a single
      REM time step.

      REM We are now ready to begin the simulation loop.  In your game the
      REM simulation loop can be merged with your game loop.  In each pass
      REM through your game loop you call PROC_b2WorldStep().  Just one call
      REM is usually enough, depending on your frame rate and your time step.

      REM Here is the simulation loop.

      @% = &20204 : REM set print to two decimals
      *REFRESH OFF

      REPEAT
        CLS
        PROC_b2WorldStep(myWorld%%, timeStep, velIterations%, posIterations%)
        PROC_b2GetBody(dynamicBody%%, xpos, ypos, angle) : REM get object position in world dimensions
        RECTANGLE FILL xpos*100*2-half_width*100*2, ypos*100*2-half_height*100*2, half_width*2*100*2 : REM the dynamic box
        LINE 0, half_height*100*2, 640*2, half_height*100*2         : REM the ground box, half_height from ground box
  
        PRINTTAB(0,0) " xpos = ";xpos; "  ypos = ";ypos;"  angle = ";DEG(angle)
  
        *REFRESH
        WAIT 1
      UNTIL FALSE

      REM The output shows the box falling and landing on the ground box.
      END

      REM When a world is destroyed, all the memory reserved for bodies,
      REM fixtures and joints is freed.  This is to improve performance
      REM and make your life easier.  However any body, fixture, or joint
      REM pointers you have will become invalid so should be zeroed:

      DEF PROCcleanup
      ON ERROR OFF
      *REFRESH ON
      myWorld%% += 0 : IF myWorld%% PROC_b2DestroyWorld(myWorld%%) : myWorld%% = 0
      PROC_b2Exit
      ENDPROC

Code: Select all

      REM 'BBC BASIC for Windows' implementation of the Hello Box2D example
      REM by Richard Russell, http://www.rtrussell.co.uk/, v0.0 21-Jan-2013
      REM Updated and modified by Svein Svensson Apr-2023

      REM This program creates a large ground box at an angle and a small dynamic box.
      REM Using the Debug Draw Interface for the graphics.

      MODE 8 : OFF
      INSTALL @lib$+"BOX2DLIB" : PROC_b2Init
      INSTALL @lib$+"box2ddbg"

      ON CLOSE PROCcleanup : QUIT

      REM Descriptive text adapted from https://box2d.org/documentation/index.html

      REM ----------------------- Creating a World ------------------------

      REM Every Box2D program begins with the creation of a b2World object.
      REM The b2World is the physics hub that manages memory, objects, and
      REM simulation.

      REM It is easy to create a Box2D world.  First, we define the gravity:

      gravity_x = 0.0
      gravity_y = -10.0

      REM Now we create the world object:

      myWorld%% = FN_b2CreateWorld(gravity_x, gravity_y)

      REM init debugdraw
      scale = 100
      PROC_b2DebugInit(myWorld%%, %01011, scale)

      REM Now we have our physics world, let's start adding some stuff to it.

      REM -------------------- Creating a Ground Box ----------------------

      REM Most Box2D simulations will have a Ground Box, which represents
      REM the floor or other surface through which objects cannot penetrate.
      REM The Ground Box is a static body; static bodies don't collide with
      REM other static bodies and are immovable.  To create the Ground Box
      REM we need to specify its position, orientation and size:

      REM Box2D works with floating point numbers and tolerances have to
      REM be used to make Box2D perform well.
      REM Box2D has been tuned to work well with moving shapes between 0.1 and 10 meters.
      REM MODE 8 = 640,512
      REM Divide window size by 100 to get a good world dimension with this window size
      REM Then multiply object positions by 100 to get pixel positions
      REM higher resolution window, say 1920*1200 may require 200 as division factor
      REM the goal is to get into the 0.1 - 10 range, or close to it.

      centre_x = 3.2     : REM 640/100/2
      centre_y = 0.0     : REM bottom of window
      angle = RAD(-8)    : REM angle in radians
      half_width = 3.2   : REM 640/100/2
      half_height = 0.1  : REM visible ground, can be zero

      groundBox%% = FN_b2StaticBox(myWorld%%, centre_x, centre_y, angle, half_width, half_height)

      REM The dimensions are specified as the half-width and half-height.
      REM So in this case the ground box is 6.4 units wide (x-axis) and
      REM 0.2 units tall (y-axis).  Box2D is tuned for metres, kilograms,
      REM and seconds, so you can consider the dimensions to be in metres.

      REM Box2D generally works best when objects are the size of typical
      REM real world objects.  For example, a barrel is about 1 metre tall.
      REM Due to the limitations of floating point arithmetic, using Box2D
      REM to model glaciers or dust particles is not a good idea.

      REM -------------------- Creating a Dynamic Box ---------------------

      REM Dynamic boxes are built using the following steps:
      REM  1. Define a body with position, damping, etc.
      REM  2. Use the world object to create the body.
      REM  3. Define fixtures with a shape, friction, density, etc.
      REM  4. Create fixtures on the body.

      REM Step 1:  Define the initial position, orientation, velocity etc:

      REM MODE 8 = 640,512
      centre_x = 3.2
      centre_y = 5.12   : REM place the body at top of the window
      angle = 0.0
      velocity_x = 0.0
      velocity_y = 0.0
      velocity_a = 0.0
      damping_lin = 0.0
      damping_ang = 0.0

      REM Step 2:  Create the dynamic body using the world object:

      dynamicBody%% = FN_b2DynamicBody(myWorld%%, centre_x, centre_y, angle, \
      \              velocity_x, velocity_y, velocity_a, damping_lin, damping_ang)

      REM Step 3:  Define a fixture in the shape of a box.  Notice that
      REM          we set the density to 1.0 and the friction to 0.3:

      half_width = 0.1
      half_height = 0.1
      friction = 0.3
      restitution = 0.0
      density = 1.0

      REM Step 4.  Create and attach the fixture.  This updates the mass
      REM          of the body.  You can add as many fixtures as you like
      REM          to a body.  Each one contributes to the total mass:

      REM x,y,angle of the fixture is relative to the body's x,y,angle the fixture is attached to.
      REM Note: you can't have a body without a fixture attached to it, (no mass)

      offx=0.0
      offy=0.0
      offangle=0.0
      myFixture%% = FN_b2BoxFixture(dynamicBody%%, offx, offy, offangle, \
      \            half_width, half_height, friction, restitution, density)

      REM That's it for initialization; we are now ready to begin simulating.

      REM --------------------- Simulating the World ----------------------

      REM We have initialized the ground box and a dynamic box.  Now we
      REM are ready to set Newton loose to do his thing.  We just have a
      REM couple more issues to consider.

      REM Box2D uses a computational algorithm called an integrator.
      REM Integrators simulate the physics equations at discrete points of
      REM time.  This goes along with the traditional game loop where we
      REM essentially have a flip book of movement on the screen.

      REM So we need to pick a time step.  Generally physics engines for
      REM games like a time step at least as fast as 60 Hz or 1/60 seconds.
      REM You can get away with larger time steps, but you will have to be
      REM more careful about setting up the definitions for your world.

      REM We also don't like the time step to change much.  A variable time
      REM step produces variable results, which makes it difficult to debug.
      REM So don't tie the time step to your frame rate (unless you really,
      REM really have to).  Without further ado, here is the time step:

      timeStep = 1/60

      REM In addition to the integrator, Box2D also uses a larger bit of code
      REM called a constraint solver.  The constraint solver solves all the
      REM constraints in the simulation, one at a time.  A single constraint
      REM can be solved perfectly.  However, when we solve one constraint,
      REM we slightly disrupt other constraints.  To get a good solution,
      REM we need to iterate over all constraints a number of times.

      REM There are two phases in the constraint solver: a velocity phase
      REM and a position phase.  In the velocity phase the solver computes
      REM the impulses necessary for the bodies to move correctly.  In the
      REM position phase the solver adjusts the positions of the bodies to
      REM reduce overlap and joint detachment.  Each phase has its own
      REM iteration count.  In addition, the position phase may exit
      REM iterations early if the errors are small.

      REM The suggested iteration count for Box2D is 8 for velocity and
      REM 3 for position.  You can tune this number to your liking, just
      REM keep in mind that this has a trade-off between speed and accuracy.
      REM Using fewer iterations increases performance but accuracy suffers.
      REM Likewise, using more iterations decreases performance but improves
      REM the quality of your simulation.  For this simple example, we don't
      REM need much iteration.  Here are our chosen iteration counts:

      velIterations% = 6
      posIterations% = 2

      REM Note that the time step and the iteration count are completely
      REM unrelated.  An iteration is not a sub-step.  One solver iteration
      REM is a single pass over all the constraints within a time step;
      REM you can have multiple passes over the constraints within a single
      REM time step.

      REM We are now ready to begin the simulation loop.  In your game the
      REM simulation loop can be merged with your game loop.  In each pass
      REM through your game loop you call PROC_b2WorldStep().  Just one call
      REM is usually enough, depending on your frame rate and your time step.

      REM Here is the simulation loop.

      @% = &20204 : REM set print to two decimals
      *REFRESH OFF

      REPEAT
        CLS
        PROC_b2WorldStep(myWorld%%, timeStep, velIterations%, posIterations%)
        PROC_b2GetBody(dynamicBody%%, xpos, ypos, angle) : REM get object position in world dimensions
        PROC_b2DebugDraw(myWorld%%) : REM draw all objects
  
        PRINTTAB(0,0) " xpos = ";xpos; "  ypos = ";ypos;"  angle = ";DEG(angle)
  
        *REFRESH
        WAIT 1
      UNTIL FALSE

      REM The output shows the box falling and sliding on the ground box.
      REM The colour of the box turns grey when it is no longer affected by forces
      END

      REM When a world is destroyed, all the memory reserved for bodies,
      REM fixtures and joints is freed.  This is to improve performance
      REM and make your life easier.  However any body, fixture, or joint
      REM pointers you have will become invalid so should be zeroed:

      DEF PROCcleanup
      ON ERROR OFF
      *REFRESH ON
      myWorld%% += 0 : IF myWorld%% PROC_b2DestroyWorld(myWorld%%) : myWorld%% = 0
      PROC_b2DebugExit
      PROC_b2Exit
      ENDPROC

Code: Select all

      REM 'BBC BASIC for Windows' implementation of the Hello Box2D example
      REM by Richard Russell, http://www.rtrussell.co.uk/, v0.0 21-Jan-2013
      REM Updated and modified by Svein Svensson Apr-2023

      REM This program creates a large ground box with two walls and a small bouncing rubber dynamic box.
      REM Using the Debug Draw Interface and the GFX library for the image.

      MODE 8 : OFF
      INSTALL @lib$+"BOX2DLIB" : PROC_b2Init
      INSTALL @lib$+"box2dgfx"
      INSTALL @lib$+"box2ddbg"

      ON CLOSE PROCcleanup : QUIT

      REM Descriptive text adapted from https://box2d.org/documentation/index.html

      REM ----------------------- Creating a World ------------------------

      REM Every Box2D program begins with the creation of a b2World object.
      REM The b2World is the physics hub that manages memory, objects, and
      REM simulation.

      REM It is easy to create a Box2D world.  First, we define the gravity:

      gravity_x = 0.0
      gravity_y = -10.0

      REM Now we create the world object:

      myWorld%% = FN_b2CreateWorld(gravity_x, gravity_y)

      REM init debugdraw
      scale = 100
      PROC_b2DebugInit(myWorld%%, %01011, scale)

      REM Now we have our physics world, let's start adding some stuff to it.

      REM -------------------- Creating a Ground Box ----------------------

      REM Most Box2D simulations will have a Ground Box, which represents
      REM the floor or other surface through which objects cannot penetrate.
      REM The Ground Box is a static body; static bodies don't collide with
      REM other static bodies and are immovable.  To create the Ground Box
      REM we need to specify its position, orientation and size:

      REM Box2D works with floating point numbers and tolerances have to
      REM be used to make Box2D perform well.
      REM Box2D has been tuned to work well with moving shapes between 0.1 and 10 meters.
      REM MODE 8 = 640,512
      REM Divide window size by 100 to get a good world dimension with this window size
      REM Then multiply object positions by 100 to get pixel positions
      REM higher resolution window, say 1920*1200 may require 200 as division factor
      REM the goal is to get into the 0.1 - 10 range, or close to it.

      centre_x = 3.2     : REM 640/100/2
      centre_y = 0.0     : REM bottom of window
      angle = 0          : REM angle in radians
      half_width = 3.2   : REM 640/100/2
      half_height = 0.1  : REM visible ground, can be zero

      groundBox%% = FN_b2StaticBox(myWorld%%, centre_x, centre_y, angle, half_width, half_height)

      REM x,y,angle are relative to groundbox x,y,angle
      offx=3.2           : REM 640/100/2
      offy=2.56          : REM 512/100/2
      offangle=0.0
      half_width = 0.05
      half_height = 2.56 : REM 512/100/2
      friction = 0.5
      restitution = 0.0
      density = 1.0

      REM create left and right wall to prevent the rubber crate from bouncing off screen
      wl%% = FN_b2BoxFixture(groundBox%%, -offx, offy, offangle,  half_width, half_height, friction, restitution, density)
      wr%% = FN_b2BoxFixture(groundBox%%, offx, offy, offangle,  half_width, half_height, friction, restitution, density)

      REM The dimensions are specified as the half-width and half-height.
      REM So in this case the ground box is 6.4 units wide (x-axis) and
      REM 0.2 units tall (y-axis).  Box2D is tuned for metres, kilograms,
      REM and seconds, so you can consider the dimensions to be in metres.

      REM Box2D generally works best when objects are the size of typical
      REM real world objects.  For example, a barrel is about 1 metre tall.
      REM Due to the limitations of floating point arithmetic, using Box2D
      REM to model glaciers or dust particles is not a good idea.

      REM -------------------- Creating a Dynamic Box ---------------------

      REM Dynamic boxes are built using the following steps:
      REM  1. Define a body with position, damping, etc.
      REM  2. Use the world object to create the body.
      REM  3. Define fixtures with a shape, friction, density, etc.
      REM  4. Create fixtures on the body.

      REM Step 1:  Define the initial position, orientation, velocity etc:

      REM MODE 8 = 640,512
      centre_x = 3.2
      centre_y = 5.12   : REM place the body at top of the window
      angle = RAD(30)   : REM tilt the body
      velocity_x = 0.0
      velocity_y = 0.0
      velocity_a = 0.0
      damping_lin = 0.0
      damping_ang = 0.0

      REM Step 2:  Create the dynamic body using the world object:

      dynamicBody%% = FN_b2DynamicBody(myWorld%%, centre_x, centre_y, angle, \
      \              velocity_x, velocity_y, velocity_a, damping_lin, damping_ang)

      REM Step 3:  Define a fixture in the shape of a box.  Notice that
      REM          we set the density to 1.0 and the friction to 0.3:

      half_width = 0.1
      half_height = 0.1
      friction = 0.3
      restitution = 0.75 : REM rubber box
      density = 1.0

      REM Step 4.  Create and attach the fixture.  This updates the mass
      REM          of the body.  You can add as many fixtures as you like
      REM          to a body.  Each one contributes to the total mass:

      REM x,y,angle of the fixture is relative to the body's x,y,angle that the fixture is attached to.
      REM Note: you can't have a body without a fixture attached to it, (no mass)

      offx=0.0
      offy=0.0
      offangle=0.0
      myFixture%% = FN_b2BoxFixture(dynamicBody%%, offx, offy, offangle, \
      \            half_width, half_height, friction, restitution, density)

      REM init gfx
      Width% = 640
      Height% = 512
      PROC_gfxInit(gfx{}, Width%, Height%, scale)

      REM To find the scale multiplier for the image:
      REM 1. find the image size in pixels
      REM 2. find the size of the fixture attached to the body, here 0.2 world units
      REM 3. multiply 0.2 by your chosen window_division_factor, here 100
      REM 4. divide pixelsize by fixturesize*window_division_factor = 32/20 = 1.6 and 24/20 = 1.2
      IF INKEY$(-256) = "W" THEN
        REM BB4W does not have crate.png, using a substitute
        PROC_gfxLoad(crate{}, @lib$+"../examples/games/.Graphics/24.bmp", scale*1.2) : REM 24*24
        PROC_gfxMultiply(crate{})
      ELSE
        REM load the crate.png
        PROC_gfxLoad(crate{}, @lib$+"../examples/physics/crate32a.png", scale*1.6)  : REM 32*32
      ENDIF

      PROC_b2UserDataBody(dynamicBody%%, crate{}) : REM attach the image to the body

      REM That's it for initialization; we are now ready to begin simulating.

      REM --------------------- Simulating the World ----------------------

      REM We have initialized the ground box and a dynamic box.  Now we
      REM are ready to set Newton loose to do his thing.  We just have a
      REM couple more issues to consider.

      REM Box2D uses a computational algorithm called an integrator.
      REM Integrators simulate the physics equations at discrete points of
      REM time.  This goes along with the traditional game loop where we
      REM essentially have a flip book of movement on the screen.

      REM So we need to pick a time step.  Generally physics engines for
      REM games like a time step at least as fast as 60 Hz or 1/60 seconds.
      REM You can get away with larger time steps, but you will have to be
      REM more careful about setting up the definitions for your world.

      REM We also don't like the time step to change much.  A variable time
      REM step produces variable results, which makes it difficult to debug.
      REM So don't tie the time step to your frame rate (unless you really,
      REM really have to).  Without further ado, here is the time step:

      timeStep = 1/60

      REM In addition to the integrator, Box2D also uses a larger bit of code
      REM called a constraint solver.  The constraint solver solves all the
      REM constraints in the simulation, one at a time.  A single constraint
      REM can be solved perfectly.  However, when we solve one constraint,
      REM we slightly disrupt other constraints.  To get a good solution,
      REM we need to iterate over all constraints a number of times.

      REM There are two phases in the constraint solver: a velocity phase
      REM and a position phase.  In the velocity phase the solver computes
      REM the impulses necessary for the bodies to move correctly.  In the
      REM position phase the solver adjusts the positions of the bodies to
      REM reduce overlap and joint detachment.  Each phase has its own
      REM iteration count.  In addition, the position phase may exit
      REM iterations early if the errors are small.

      REM The suggested iteration count for Box2D is 8 for velocity and
      REM 3 for position.  You can tune this number to your liking, just
      REM keep in mind that this has a trade-off between speed and accuracy.
      REM Using fewer iterations increases performance but accuracy suffers.
      REM Likewise, using more iterations decreases performance but improves
      REM the quality of your simulation.  For this simple example, we don't
      REM need much iteration.  Here are our chosen iteration counts:

      velIterations% = 6
      posIterations% = 2

      REM Note that the time step and the iteration count are completely
      REM unrelated.  An iteration is not a sub-step.  One solver iteration
      REM is a single pass over all the constraints within a time step;
      REM you can have multiple passes over the constraints within a single
      REM time step.

      REM We are now ready to begin the simulation loop.  In your game the
      REM simulation loop can be merged with your game loop.  In each pass
      REM through your game loop you call PROC_b2WorldStep().  Just one call
      REM is usually enough, depending on your frame rate and your time step.

      REM Here is the simulation loop.

      @% = &20204 : REM set print to two decimals
      *REFRESH OFF

      REPEAT
        CLS
        PROC_b2WorldStep(myWorld%%, timeStep, velIterations%, posIterations%)
        PROC_b2GetBody(dynamicBody%%, xpos, ypos, angle) : REM get object position in world dimensions
        PROC_b2DebugDraw(myWorld%%) : REM draw ground and walls
        PROC_gfxRender(gfx{}, myWorld%%) : REM display the crate.png
  
        PRINTTAB(1,0) " xpos = ";xpos; "  ypos = ";ypos;"  angle = ";DEG(angle)
  
        *REFRESH
        WAIT 1
      UNTIL FALSE

      REM The output shows the box falling and bouncing off the ground box.
      END

      REM When a world is destroyed, all the memory reserved for bodies,
      REM fixtures and joints is freed.  This is to improve performance
      REM and make your life easier.  However any body, fixture, or joint
      REM pointers you have will become invalid so should be zeroed:

      DEF PROCcleanup
      ON ERROR OFF
      *REFRESH ON
      myWorld%% += 0 : IF myWorld%% PROC_b2DestroyWorld(myWorld%%) : myWorld%% = 0
      PROC_b2DebugExit
      IF INKEY$(-256) <> "W" THEN PROC_gfxExit
      PROC_b2Exit
      ENDPROC
Hated Moron

Re: Box2d hello world example

Post by Hated Moron »

svein wrote: Sun 09 Apr 2023, 21:29 Looking in older folders, i found this hello world demo written by Richard 10 years ago.
Needless to say, I had completely forgotten that this existed! The question arises: where should it be put so that there is an improved chance that it will be discovered by somebody wanting to experiment with the physics engine? Should it be supplied with BBC BASIC as an example program? Should be at the website? Should there be a 'sticky' post here containing it? Or what?
To make it easier (for me), i created 3 versions of the hello world demo.
1. Using only BBC graphics commands
2. Using only the debug draw interface
3. Using debugdraw and GFXlib for the image
I would add that the Debug Draw graphics are anti-aliased, so they are relatively slow (usually unimportant for debug purposes) but do show the position and orientation of objects very precisely, to sub-pixel resolution. This can be helpful when trying to make adjustments or analyse behaviour. Commonly, pressing D in the example programs displays the Debug Draw graphics.

Also don't forget the box2dgfx library (supplied with both BB4W and BBCSDL), which allows you to associate an image (BMP, JPG, PNG, GIF etc.) with each object, and then draw the whole lot - at their correct positions and orientations - in one call. This can make the conversion of a Box2D debug demo into a fully-rendered photo-realistic representation almost trivial. See examples like bbclock.bbc, dangle.bbc and dunebuggy.bbc.

The only thing to bear in mind is that the order in which objects are defined (which isn't important from the point of view of the physics) determines which image appears 'in front' and which 'behind' when multiple objects are overlapping. Of course if you use a PNG image it can have transparency, so the object can have an irregular shape.
svein
Posts: 60
Joined: Tue 03 Apr 2018, 19:34

Re: Box2d hello world example

Post by svein »

The question arises: where should it be put so that there is an improved chance that it will be discovered
If i wanted to learn/explore the Box2d stuff, i would probably start by looking at the example programs.
And if there were programs named:
Hello_world1.bbc
Hello_world2.bbc
Hello_world3.bbc.
That's where i would start.

They have a lot of text, but only the bare minimum of code to do the task.
In fact, i'm using one of them as a starter for a game idea i have.

Svein
Hated Moron

Re: Box2d hello world example

Post by Hated Moron »

svein wrote: Tue 11 Apr 2023, 05:45 If i wanted to learn/explore the Box2d stuff, i would probably start by looking at the example programs.
I could consider putting a Hello_Box2D program in the existing physics/samples sub-directory. It should fit well alongside the other little examples of different Box2D techniques.
Hated Moron

Re: Box2d hello world example

Post by Hated Moron »

Here's a suggested Hello_Box2D.bbc for possible inclusion in examples/physics/samples. It's based on your second example, but with some tidying up, some additional explanatory text, and an incompatibility with BBCSDL (a library name given in capital letters) fixed.

Code: Select all

      REM 'BBC BASIC for SDL 2.0' implementation of the Hello Box2D example
      REM by Richard Russell and Svein Svensson.  Version 1.0, April 2023.
      REM (also runs in 'BBC BASIC for Windows').

      REM This program demonstrates dropping a small dynamic box onto an
      REM inclined ground box, using the Debug Draw interface for graphics.
      REM Comments adapted from https://box2d.org/documentation/index.html

      MODE 8 : OFF
      INSTALL @lib$+"box2dlib" : PROC_b2Init
      INSTALL @lib$+"box2ddbg"

      ON ERROR PROCcleanup : IF ERR=17 CHAIN @lib$+"../examples/tools/touchide" ELSE MODE 8:REPORT:END
      ON CLOSE PROCcleanup : QUIT

      REM ----------------------- Creating a World ------------------------

      REM Every Box2D program begins with the creation of a b2World object.
      REM The b2World is the physics hub that manages memory, objects, and
      REM simulation.  Note that Box2D uses Cartesian coordinates, so the
      REM positive direction of y-coordinates is upwards, from bottom to top.
      REM Box2D uses S.I. Units: metres, kilograms and seconds.

      REM It is easy to create a Box2D world.  First, we define the gravity:

      gravity_x = 0.0
      gravity_y = -9.8 : REM 9.8 metres/second², negative for downwards

      REM Now we create the world object:

      myWorld%% = FN_b2CreateWorld(gravity_x, gravity_y)

      REM Box2D has been tuned to work well with moving objects in the size
      REM range 0.1 to 10 metres.  With a MODE 8 window (640 x 512 pixels)
      REM a scaling factor of 100 pixels/metre will give a world dimension
      REM of 6.4 x 5.1 metres, and the smallest objects should be around 10
      REM pixels across.  With a higher resolution window, say 1920 x 1200
      REM pixels, a scaling factor of 200 pixels per metre might be better.

      REM Due to the limitations of floating point arithmetic, using Box2D
      REM to model glaciers or dust particles is not a good idea!

      REM Initialise the Debug Draw interface we will use for graphics:

      scale = 100
      PROC_b2DebugInit(myWorld%%, %01011, scale)

      REM Now we have our physics world, let's start adding some stuff to it.

      REM --------------------- Creating a Ground Box ----------------------

      REM Most Box2D simulations will have a Ground Box, which represents
      REM the floor or other surface through which objects cannot penetrate.
      REM The Ground Box is a static body; static bodies don't collide with
      REM other static bodies and are immovable.  To create the Ground Box
      REM we need to specify its position, orientation and size:

      angle = RAD(7.5)   : REM angle in radians
      centre_x = 3.2     : REM 640/100/2 metres
      centre_y = centre_x * TAN(angle) : REM bottom of window
      half_width = 3.2   : REM 640/100/2 metres
      half_height = 0.1  : REM visible ground, can be zero

      groundBox%% = FN_b2StaticBox(myWorld%%, centre_x, centre_y, angle, half_width, half_height)

      REM The dimensions are specified as the half-width and half-height.
      REM So in this case the ground box is 6.4 units wide (x-axis) and
      REM 0.2 units tall (y-axis).

      REM --------------------- Creating a Dynamic Box ---------------------

      REM A Dynamic Box represents a rigid object that can move, it consists
      REM of a 'body' plus one or more 'fixtures'.  The 'body' represents
      REM the object's position, velocity, orientation and damping.  The
      REM 'fixtures' give the object a shape and a mass, they determine how
      REM it interacts with other objects, e.g. as the result of a collision

      REM Dynamic boxes are built using the following steps:
      REM  1. Define a body with position, orientation damping, etc.
      REM  2. Use the world object to create the body.
      REM  3. Define fixtures with a shape, friction, density, etc.
      REM  4. Create fixtures on the body.

      REM Step 1:  Define the initial position, orientation, velocity etc:

      REM MODE 8 = 640,512
      centre_x = 3.2
      centre_y = 5.12   : REM place the body at top of the window
      angle = 0.0
      velocity_x = 0.0
      velocity_y = 0.0
      velocity_a = 0.0
      damping_lin = 0.0
      damping_ang = 0.0

      REM Step 2:  Create the dynamic body using the world object:

      dynamicBody%% = FN_b2DynamicBody(myWorld%%, centre_x, centre_y, angle, \
      \          velocity_x, velocity_y, velocity_a, damping_lin, damping_ang)

      REM Step 3:  Define a fixture in the shape of a box.  Notice that
      REM          we set the density to 1.0 and the friction to 0.3:

      half_width = 0.1
      half_height = 0.1
      friction = 0.3
      restitution = 0.0
      density = 1.0

      REM Step 4.  Create and attach the fixture.  This updates the mass
      REM          of the body.  You can add as many fixtures as you like
      REM          to a body.  Each one contributes to the total mass:

      REM The x,y,angle of the fixture are relative to the body's x,y,angle.
      REM You can't have a body without a fixture attached to it (no mass).

      offx = 0.0
      offy = 0.0
      offangle = 0.0
      myFixture%% = FN_b2BoxFixture(dynamicBody%%, offx, offy, offangle, \
      \            half_width, half_height, friction, restitution, density)

      REM That's it for initialization; we are now ready to begin simulating.

      REM --------------------- Simulating the World ----------------------

      REM We have initialized the ground box and a dynamic box.  Now we
      REM are ready to set Newton loose to do his thing.  We just have a
      REM couple more issues to consider.

      REM Box2D uses a computational algorithm called an integrator.
      REM Integrators simulate the physics equations at discrete points of
      REM time.  This goes along with the traditional game loop where we
      REM essentially have a flip book of movement on the screen.

      REM So we need to pick a time step.  Generally physics engines for
      REM games like a time step at least as fast as 60 Hz or 1/60 seconds.
      REM You can get away with larger time steps, but you will have to be
      REM more careful about setting up the definitions for your world.

      REM We also don't like the time step to change much.  A variable time
      REM step produces variable results, which makes it difficult to debug.
      REM So don't tie the time step to your frame rate (unless you really,
      REM really have to).  Without further ado, here is the time step:

      timeStep = 1/60

      REM In addition to the integrator, Box2D uses a larger piece of code
      REM called a constraint solver.  The constraint solver solves all the
      REM constraints in the simulation, one at a time.  A single constraint
      REM can be solved perfectly.  However, when we solve one constraint,
      REM we slightly disrupt other constraints.  To get a good solution,
      REM we need to iterate over all constraints a number of times.

      REM There are two phases in the constraint solver: a velocity phase
      REM and a position phase.  In the velocity phase the solver computes
      REM the impulses necessary for the bodies to move correctly.  In the
      REM position phase the solver adjusts the positions of the bodies to
      REM reduce overlap and joint detachment.  Each phase has its own
      REM iteration count.  In addition, the position phase may exit
      REM iterations early if the errors are small.

      REM The suggested iteration count for Box2D is 8 for velocity and
      REM 3 for position.  You can tune this number to your liking, just
      REM keep in mind that this has a trade-off between speed and accuracy.
      REM Using fewer iterations increases performance but accuracy suffers.
      REM Likewise, using more iterations decreases performance but improves
      REM the quality of your simulation.  For this simple example, we don't
      REM need much iteration.  Here are our chosen iteration counts:

      velIterations% = 6
      posIterations% = 2

      REM Note that the time step and the iteration count are completely
      REM unrelated.  An iteration is not a sub-step.  One solver iteration
      REM is a single pass over all the constraints within a time step;
      REM you can have multiple passes over the constraints within a single
      REM time step.

      REM We are now ready to begin the simulation loop.  In your game the
      REM simulation loop can be merged with your game loop.  In each pass
      REM through your game loop you call PROC_b2WorldStep().  Just one call
      REM is usually enough, depending on your frame rate and your time step.

      REM Here is the simulation loop:

      @% = &20204 : REM set print to two decimals
      *REFRESH OFF

      REPEAT
        CLS
        PROC_b2WorldStep(myWorld%%, timeStep, velIterations%, posIterations%)
        PROC_b2DebugDraw(myWorld%%) : REM draw all the objects

        REM Get object position in world dimensions:
        PROC_b2GetBody(dynamicBody%%, xpos, ypos, angle)
        PRINTTAB(0,0) " xpos = ";xpos "  ypos = ";ypos "  angle = ";DEG(angle)

        *REFRESH
        WAIT 1
      UNTIL FALSE

      REM The output shows the box falling and sliding on the ground box.
      REM The box colour turns grey when it is no longer affected by forces.
      END

      REM When a world is destroyed, all the memory reserved for bodies,
      REM fixtures and joints is freed.  This is to improve performance
      REM and make your life easier.  However any body, fixture, or joint
      REM pointers you have will become invalid so should be zeroed:

      DEF PROCcleanup
      ON ERROR OFF
      *REFRESH ON
      myWorld%% += 0 : IF myWorld%% PROC_b2DestroyWorld(myWorld%%) : myWorld%% = 0
      PROC_b2DebugExit
      PROC_b2Exit
      ENDPROC
svein
Posts: 60
Joined: Tue 03 Apr 2018, 19:34

Re: Box2d hello world example

Post by svein »

some additional explanatory text
Unsurprisingly, your explanation is much better than mine.

Perhaps add an explanation how to properly scale an image to a world object ?

In my demo3 i used scale*32/20 for a box of size 0.2*0.2, but in your crates.bbc you used scale*30/32 for a box of size 0.3*0.3.
Both programs use crate32a.png.(32 pixels)
If i try to use your formula in my demo3, the size seems wrong.
I must be missing something, but what ?

Svein
Hated Moron

Re: Box2d hello world example

Post by Hated Moron »

svein wrote: Thu 13 Apr 2023, 16:40 Perhaps add an explanation how to properly scale an image to a world object ?
OK. I wasn't intending to incorporate graphics images in the Hello_Box2D example, but have now done so in order to add that explanation without it seeming out-of-context. I hope you don't feel it has made the program too complex.

Code: Select all

      REM 'BBC BASIC for SDL 2.0' implementation of the Hello Box2D example
      REM by Richard Russell and Svein Svensson.  Version 1.0, April 2023.
      REM (also runs in 'BBC BASIC for Windows').

      REM This program demonstrates dropping a small Dynamic Box onto an
      REM inclined Ground Box, using the 'Box2Dgfx' library for graphics
      REM and optionally displaying Debug Draw graphics when D is pressed.
      REM Comments adapted from https://box2d.org/documentation/index.html

      MODE 8 : OFF
      INSTALL @lib$+"box2dlib" : PROC_b2Init
      INSTALL @lib$+"box2dgfx"
      INSTALL @lib$+"box2ddbg"

      ON ERROR PROCcleanup : IF ERR=17 CHAIN @lib$+"../examples/tools/touchide" ELSE MODE 8:REPORT:END
      ON CLOSE PROCcleanup : QUIT

      REM ----------------------- Creating a World ------------------------

      REM Every Box2D program begins with the creation of a b2World object.
      REM The b2World is the physics hub that manages memory, objects, and
      REM simulation.  Note that Box2D uses Cartesian coordinates, so the
      REM positive direction of y-coordinates is upwards, from bottom to top.
      REM Box2D uses S.I. Units: metres, kilograms and seconds.

      REM It is easy to create a Box2D world.  First, we define the gravity:

      gravity_x = 0.0
      gravity_y = -9.8 : REM 9.8 metres/second², negative for downwards

      REM Now we create the world object:

      myWorld%% = FN_b2CreateWorld(gravity_x, gravity_y)

      REM Box2D has been tuned to work well with moving objects in the size
      REM range 0.1 to 10 metres.  With a MODE 8 window (640 x 512 pixels)
      REM a scaling factor of 100 pixels/metre will give a world dimension
      REM of 6.4 x 5.1 metres, and the smallest objects should be around 10
      REM pixels across.  With a higher resolution window, say 1920 x 1200
      REM pixels, a scaling factor of 200 pixels per metre might be better.

      REM Due to the limitations of floating point arithmetic, using Box2D
      REM to model glaciers or dust particles is not a good idea!

      scale = 100

      REM Initialise the Box2Dgfx and Debug Draw libraries for graphics:

      PROC_gfxInit(gfx{}, @size.x%, @size.y%, scale)
      PROC_b2DebugInit(myWorld%%, %01011, scale)

      REM Now we have our physics world, let's start adding some stuff to it.

      REM --------------------- Creating a Ground Box ----------------------

      REM Most Box2D simulations will have a Ground Box, which represents
      REM the floor or other surface through which objects cannot penetrate.
      REM The Ground Box is a static body; static bodies don't collide with
      REM other static bodies and are immovable.  To create the Ground Box
      REM we need to specify its position, orientation and size:

      angle = RAD(7.5)   : REM angle in radians
      centre_x = 3.2     : REM 640/100/2 metres
      centre_y = centre_x * TAN(angle) : REM bottom of window
      half_width = 3.2   : REM Width 6.4 metres
      half_height = 0.1  : REM Height 0.2 metres (can be zero if invisible)

      groundBox%% = FN_b2StaticBox(myWorld%%, centre_x, centre_y, angle, half_width, half_height)

      REM Load an image which will be used to draw the Ground Box.  The
      REM final parameter is a scaling factor in pixels-per-metre; since
      REM the object dimensions are 6.4 metres by 0.2 metres and the image
      REM dimensions are approximately 960 pixels by 30 pixels (visible)
      REM the appropriate scale is 150 pixels/metre.  Once the image has
      REM been loaded it is associated with the object.

      PROC_gfxLoad(strip{}, @lib$ + "../examples/physics/strip.png", 150)
      PROC_b2UserDataBody(groundBox%%, strip{})

      REM In BBC BASIC for Windows (only) the image must be pre-multiplied
      REM (i.e. the RGB channels must be multiplied by the alpha channel).
      IF INKEY$(-256) = "W" PROC_gfxMultiply(strip{})

      REM --------------------- Creating a Dynamic Box ---------------------

      REM A Dynamic Box represents a rigid object that can move, it consists
      REM of a 'body' plus one or more 'fixtures'.  The 'body' represents
      REM the object's position, velocity, orientation and damping.  The
      REM 'fixtures' give the object a shape and a mass, they determine how
      REM it interacts with other objects, e.g. as the result of a collision

      REM Dynamic boxes are built using the following steps:
      REM  1. Define a body with position, orientation damping, etc.
      REM  2. Use the world object to create the body.
      REM  3. Define fixtures with a shape, friction, density, etc.
      REM  4. Create fixtures on the body.

      REM Step 1:  Define the initial position, orientation, velocity etc:

      REM MODE 8 = 640,512
      centre_x = 3.2
      centre_y = 5.12   : REM place the body at top of the window
      angle = 0.0
      velocity_x = 0.0
      velocity_y = 0.0
      velocity_a = 0.0
      damping_lin = 0.0
      damping_ang = 0.0

      REM Step 2:  Create the dynamic body using the world object:

      dynamicBody%% = FN_b2DynamicBody(myWorld%%, centre_x, centre_y, angle, \
      \          velocity_x, velocity_y, velocity_a, damping_lin, damping_ang)

      REM Step 3:  Define a fixture in the shape of a box.  Notice that
      REM          we set the density to 1.0 and the friction to 0.3:

      half_width = 0.1
      half_height = 0.1
      friction = 0.3
      restitution = 0.0
      density = 1.0

      REM Step 4.  Create and attach the fixture.  This updates the mass
      REM          of the body.  You can add as many fixtures as you like
      REM          to a body.  Each one contributes to the total mass:

      REM The x,y,angle of the fixture are relative to the body's x,y,angle.
      REM You can't have a body without a fixture attached to it (no mass).

      offx = 0.0
      offy = 0.0
      offangle = 0.0
      myFixture%% = FN_b2BoxFixture(dynamicBody%%, offx, offy, offangle, \
      \            half_width, half_height, friction, restitution, density)

      REM Load an image which will be drawn to represent the Dynamic Box, in
      REM the same way as we did for the Ground Box.  This time the object
      REM dimensions are 0.2 by 0.2 metres and the visible image dimensions
      REM are 32 x 32 pixels so the scale factor is 160 pixels-per-metre.

      PROC_gfxLoad(crate{}, @lib$ + "../examples/physics/crate32a.png", 160)
      PROC_b2UserDataBody(dynamicBody%%, crate{})

      REM In BBC BASIC for Windows (only) the image must be pre-multiplied:
      IF INKEY$(-256) = "W" PROC_gfxMultiply(crate{})

      REM That's it for initialization; we are now ready to begin simulating.

      REM --------------------- Simulating the World ----------------------

      REM We have initialized the Ground Box and a Dynamic Box.  Now we
      REM are ready to set Newton loose to do his thing.  We just have a
      REM couple more issues to consider.

      REM Box2D uses a computational algorithm called an integrator.
      REM Integrators simulate the physics equations at discrete points of
      REM time.  This goes along with the traditional game loop where we
      REM essentially have a flip book of movement on the screen.

      REM So we need to pick a time step.  Generally physics engines for
      REM games like a time step at least as fast as 60 Hz or 1/60 seconds.
      REM You can get away with larger time steps, but you will have to be
      REM more careful about setting up the definitions for your world.

      REM We also don't like the time step to change much.  A variable time
      REM step produces variable results, which makes it difficult to debug.
      REM So don't tie the time step to your frame rate (unless you really,
      REM really have to).  Without further ado, here is the time step:

      timeStep = 1/60

      REM In addition to the integrator, Box2D uses a larger piece of code
      REM called a constraint solver.  The constraint solver solves all the
      REM constraints in the simulation, one at a time.  A single constraint
      REM can be solved perfectly.  However, when we solve one constraint,
      REM we slightly disrupt other constraints.  To get a good solution,
      REM we need to iterate over all constraints a number of times.

      REM There are two phases in the constraint solver: a velocity phase
      REM and a position phase.  In the velocity phase the solver computes
      REM the impulses necessary for the bodies to move correctly.  In the
      REM position phase the solver adjusts the positions of the bodies to
      REM reduce overlap and joint detachment.  Each phase has its own
      REM iteration count.  In addition, the position phase may exit
      REM iterations early if the errors are small.

      REM The suggested iteration count for Box2D is 8 for velocity and
      REM 3 for position.  You can tune this number to your liking, just
      REM keep in mind that this has a trade-off between speed and accuracy.
      REM Using fewer iterations increases performance but accuracy suffers.
      REM Likewise, using more iterations decreases performance but improves
      REM the quality of your simulation.  For this simple example, we don't
      REM need much iteration.  Here are our chosen iteration counts:

      velIterations% = 6
      posIterations% = 2

      REM Note that the time step and the iteration count are completely
      REM unrelated.  An iteration is not a sub-step.  One solver iteration
      REM is a single pass over all the constraints within a time step;
      REM you can have multiple passes over the constraints within a single
      REM time step.

      REM We are now ready to begin the simulation loop.  In your game the
      REM simulation loop can be merged with your game loop.  In each pass
      REM through your game loop you call PROC_b2WorldStep().  Just one call
      REM is usually enough, depending on your frame rate and your time step.

      REM Here is the simulation loop:

      @% = &20204 : REM set print to two decimals
      *REFRESH OFF

      REPEAT
        CLS
        PROC_b2WorldStep(myWorld%%, timeStep, velIterations%, posIterations%)
        PROC_gfxRender(gfx{}, myWorld%%)          : REM draw all the objects
        IF INKEY(-51) PROC_b2DebugDraw(myWorld%%) : REM Debug Draw graphics

        REM Get object position in world dimensions:
        PROC_b2GetBody(dynamicBody%%, xpos, ypos, angle)
        PRINTTAB(0,0) " xpos = ";xpos "  ypos = ";ypos "  angle = ";DEG(angle);
        PRINT "  Press the D key for Debug Draw graphics"

        *REFRESH
        WAIT 1
      UNTIL FALSE

      REM The output shows the box falling and sliding on the ground box.
      REM The box colour turns grey when it is no longer affected by forces.
      END

      REM When a world is destroyed, all the memory reserved for bodies,
      REM fixtures and joints is freed.  This is to improve performance
      REM and make your life easier.  However any body, fixture, or joint
      REM pointers you created will have become invalid:

      DEF PROCcleanup
      ON ERROR OFF
      *REFRESH ON
      myWorld%% += 0 : IF myWorld%% PROC_b2DestroyWorld(myWorld%%) : myWorld%% = 0
      PROC_b2DebugExit
      PROC_gfxExit
      PROC_b2Exit
      ENDPROC
svein
Posts: 60
Joined: Tue 03 Apr 2018, 19:34

Re: Box2d hello world example

Post by svein »

In my opinion, the various step are well explained, and relatively easy follow and understand.
I think it is a good hello_world demo.
Others might have a different opinion ?

Svein
Hated Moron

Re: Box2d hello world example

Post by Hated Moron »

svein wrote: Fri 14 Apr 2023, 08:44 I think it is a good hello_world demo.
Thanks. Does it explain why your image scaling was wrong?
svein
Posts: 60
Joined: Tue 03 Apr 2018, 19:34

Re: Box2d hello world example

Post by svein »

Does it explain why your image scaling was wrong?
Yes, the penny dropped. Thank you.

Svein