Overview

The Quorum 2D Physics Engine is meant to make basic forces and the interaction of objects in our games simpler to implement. In this tutorial, we will learn how to turn on physics and apply gravity. If you need a refresher on making 2D games, be sure to review the other Games and Media tutorials on the Reference page before beginning this tutorial. The code provided at the end of this tutorial will load a blue box onto the game screen which will be in the air above a green box representing the ground. Then the blue box will fall, increasing in speed as it approaches the ground. A lot of this code will be familiar to the Drawing in 2D tutorial, because we still need to create shapes and add them to the screen.

Physics Flags

Our first step in using physics is to turn it on. We do this by setting the global physics flag in the CreateGame action.

EnablePhysics2D(true)

With the physics engine, there are additional properties that can be set for each item we add to the screen. Most importantly, when we want to use the Physics engine for an object, there is a flag that needs to be set to true: EnablePhysics. These are set in the same way that position or color is set, for example:

itemName:EnablePhysics(true)

After we turn physics on, we need to tell the engine more information about the item. There are two ways to do this part, but we will focus on only one for this tutorial. All Item2D objects now have physics properties stored in a PhysicsProperties2D object. We can access most of these properties through new actions in the Item2D class. The properties include friction, linear velocity, and others. We will cover more of these properties in further tutorials, but for this gravity game, we need responsiveness.

Responsiveness

Responsiveness describes how this item interacts with other items on the screen. There are three levels of responsiveness: Responsive, NonResponsive, and Unmovable.

Responsive

An object set to be responsive can be affected by forces like gravity or forces resulting from a collision. A player controlled character, for example, might be responsive. We can set an item to be responsive like this:

itemName:SetResponsive()

NonResponsive

A nonresponsive object will not respond to forces, but can be moved programmatically. A moving platform might be nonresponsive so that it can be moved in the program without responding to gravity or collisions. We can move the platform using "itemName:Move()", for example. Note that using Move() with responsive items will bypass collisions and gravity for them as well. We can set an item to be nonresponsive like this:

itemName:SetNonResponsive()

Unmovable

An unmovable object will not respond to forces and cannot be moved. This is the perfect option for the ground, as it should not fall from gravity, be pushed by collisions, or be moved in the program after being set in place. Note that if the position of an Unmovable object is changed in Update() or anytime after being set initially, the object will move on screen, but the physics will act as if the object remains in its original position. Unmovable is a physics property, so it only affects the physics of the object and not how it appears on screen. We can set an item to be unmovable like this:

itemName:SetUnmovable()

In this tutorial, we will use two of these levels of responsiveness: Unmovable and Responsive. The ground will be Unmovable. The box on the other hand, should be Responsive because we want gravity and collision forces to act on it: stopping it when it hits the ground. Finally, we need to tell the computer the impact of gravity.

Gravity

Like the global physics flag, we need to set gravity in the CreateGame() action. There are two ways to set gravity, both with the same handy action. Here, we will focus on one of these ways. The next tutorial about forces will cover the other. The action to set gravity is:

number X = 0
number Y = -100
SetGravity2D( X , Y )

When we set gravity, the X and Y coordinates will correspond to the direction and amount of change per second. For gravity, we want a force pulling down vertically (set Y to a negative number), and no pull horizontally (set X to 0). Because the engine has to convert pixels to metric measurements, sometimes we may need to try a few different force values for gravity to make sure it looks right.

Code

Here is a zip file containing this code in a Quorum project. Read through, then use the following code to discover gravity.

use Libraries.Game.Game
use Libraries.Game.Graphics.Drawable
use Libraries.Game.Graphics.Color
use Libraries.Interface.Events.CollisionListener2D
use Libraries.Interface.Events.CollisionEvent2D
use Libraries.Sound.Audio

class Main is Game, CollisionListener2D
   Drawable ground
   Drawable box
   Audio fallSound
   Audio boomSound
   Color color

   action Main
       StartGame()
   end

   action CreateGame
   /*
       This flag enables 2 dimensional physics for the game. Make sure to set 
       this when you want to add physics.
   */
       EnablePhysics2D(true)

       ground:SetName("Ground")
       ground:LoadFilledRectangle(GetScreenWidth(), 50)
       ground:SetColor(color:Green())
       Add(ground)
   /*
       We must enable physics for each Item2D object that will interact 
       with other Item2D objects.
   */
       ground:EnablePhysics(true)
   /*
       Neither gravity, collision, nor any programmatic method should be able 
       to move the ground; its responsiveness needs to be set to unmovable.
   */
       ground:SetUnmovable()

       box:SetName("Box")
       box:LoadFilledRectangle(150, 100)
       box:SetColor(color:Blue())
       box:SetPosition((GetScreenWidth() - box:GetWidth()) / 2, GetScreenHeight() - box:GetHeight())
       Add(box)
       box:EnablePhysics(true)
   /*
       The box is responds to gravity and impact with the ground, so we will 
       set to be responsive. 
   */
       box:SetResponsive()
   /*
       Finally, we set gravity 
       (This is an approximation of actual gravity)
   */
       SetGravity2D(0, -100)

       fallSound:Load("media/Fall.ogg")
       boomSound:Load("media/Boom.ogg")
       fallSound:Play()

       AddCollisionListener(me)
   end

   action BeginCollision(CollisionEvent2D event)
       fallSound:Pause()
       boomSound:SetVolume(0.4)
       boomSound:Play()
   end
end

Next Tutorial

In the next tutorial, we will discuss Force and Velocity, which describes how to add forces and velocity to a 2D game.