Getting Started with 2D Physics in Godot
Explore Godot’s physics engines to create dynamic games. Learn collision handling, add sound effects, and build engaging gameplay where luck and skill intersect! By Ken Lee.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Getting Started with 2D Physics in Godot
35 mins
- Get Started
- File Overview
- Main Scene
- Understanding 2D Physics Engine
- Understanding Different Physics Nodes
- Create a RigidBody2D node
- The Marble Scene
- About the PhysicsMaterial
- Friction and Rough
- Bounce and Absorbent
- Setting the PhysicsMaterial properties
- Gravity Setting
- Add the appearance
- Define the Collision Shape
- Spawning the Marble
- Creating the Marble Property
- Instantiate the Marble Node
- Limit the Spawn Location
- Adding the Score Logic
- Define the Score Triggers
- Handling the Score Signal
- Adding the StaticBody2D pegs
- Creating the Peg Scene
- Pegs Placement
- Setting Up the Snap Tool
- Position Pegs Using Snap Tools
- Fixing the Marble Stuck at the Peg
- Making a Complete Game Flow
- Marble Count Deduction
- Game Over Handing
- Sound and Background Music
- Adding Sound Effects for Pegs:
- Adding Background Music
- Where to Go From Here?
Bounce and Absorbent
The bounce value determines how much speed a node retains after a collision. It ranges from 0 to 1, where 1 means the node maintains its original speed, 0 means it stops entirely, and values between 0 and 1 mean it retains some of its original speed.
This demonstration shows the behaviours of different bounce settings.
The Absorbent property makes the bounce value behave differently. When this property is enabled, the node will absorb the bounce value of another node, resulting in a smaller final bounce value.
Below is a demonstration of different the absorbent and bounce settings.
Here’s the comparsion of the final bound values of the bounce and absorbent settings used in the demonstration.
Now that you understand the PhysicsMaterial settings, you can configure them for the marble to ensure it falls and stops upon hitting the bottom boundary.
Setting the PhysicsMaterial properties
Initially, the RigidBody2D node doesn’t have a PhysicsMaterial property, so you’ll need to add it.
Open the Inspector, click on the Physics Material Override dropdown menu and select New PhysicsMaterial.
Then, configure it with the following settings:
After the configuration, it’ll look like this:
Gravity Setting
Gravity plays an important role in the physics simulation. It controls how fast the node falls and in which direction.
There are two places to set the gravity. The global setting is in the project setting and the individual setting is in the RigidBody2D node.
First, take a look of the global setting. Open the Project Setting dialog by selecting Project ▸ Project Settings in the menu. Then, select the General tab. You’ll see the Default Gravity and Default Gravity Vector properties at the Physics ▸ 2D section.
The Default Gravity defines how many pixels move per second. The Default Gravity Vector defines the direction of the gravity.
In the RigidBody2D node, you’ll find the Gravity Scale located directly below the Physics Material Override property.
The Gravity Scale controls the percentage of the global gravity affecting the node. With a value of 1, the node experiences the full force of gravity, while a value of 0 means it is completely unaffected by gravity.
The following demonstration illustrates how different Gravity Scale values impact the behavior of the physics node:
Add the appearance
After setting up the physics elements, create a visual appearance for the marble so players can see it. Use a Sprite2D node to achieve this.
Right-click the root node and select Add Child Node. From the list of node types, choose Sprite2D.
With the Sprite2D node selected, drag the texture from sprites/marble.svg in the FileSystem
dock to the Texture property in the Inspector.
Adjust the scale property in the Transform group to 0.4 for proper sizing.
Define the Collision Shape
Adding a collision shape is an important step when creating a physics node. It defines the area that the physics engine uses to detect collisions. Without it, the node won’t have any physics interaction.
Due to the importance of the collision shape, Godot will display a warning sign on the RigidBody2D node if it doesn’t have a collision shape.
To define the collision shape, right-click on the RigidBody2D node and select Add Child Node. Then, choose CollisionShape2D from the list of node types.
Once you’ve added the CollisionShape2D node, set its Shape to CircleShape2D. Also, set its Radius to 40 pixels to match the size of the marble sprite.
Now, your first physics node is ready. It’s time to test it and use it in your game.
Spawning the Marble
To use the physics node you’ve created, you need to write a logic to spawn it in the game.
Creating the Marble Property
First, you need to create a property in the MainScene script to associate the marble scene you’ve created.
Open main_scene.gd and add this code statement after extends Node2D
.
@export var marble : PackedScene
The @export keyword makes the property named Marble visible in the Inspector tab and allows you to assign the Marble scene to it.
Now, you can drag marble.tscn to the Marble property in the Inspector to associate the marble scene with the main_scene script.
This is a common technique in Godot game development to spawn nodes at runtime. Similar use cases include spawning enemies and bullets.
Instantiate the Marble Node
Now, you can access to the Marble property in the main_scene script. You’ll use it to instantiate the marble node at runtime.
Back to the main_scene script, add a new function called _spawn_marble(_position)
.
func _spawn_marble(_position):
#1
var marble_instance = marble.instantiate()
#2
marble_instance.position = _position
marble_instance.name = "marble"
#3
add_child(marble_instance)
Here, you:
- Create the marble instance.
- Define the position and name of the instance
- Add the marble instance in the main scene.
Next, You still need to connect it to the player input. To do so, you’ll use the Input Map feature in Godot.
Select Project ▸ Project Settings in the menu to open the Project Setting dialog. Now select the Input Map tab.
Focus on the Add New Action box. Type in click_action and click Add. This creates a new custom action, which is your player control.
After you’ve created click_action, the action item will appear in the Action list. Click on the + button to the right of click_action. Then, do a >Left Mouse Click in the Listening for input box.
Click Okay to confirm the binding between Left Mouse Click and the click_action action.
Now, add the logic of click_action. Open main_scene.gd and navigate to the _process(delta)
method. Add the following code inside:
func _process(delta):
#1
if Input.is_action_just_pressed("click_action"):
#2
var mouse_position = get_viewport().get_mouse_position()
#3
_spawn_marble(mouse_position)
Here’s what the code does:
- Check if the click_action action has been triggered.
- Get the position of the latest mouse click.
- Invoke
_spawn_marble
to spawn the marble at the mouse position.
Now, run and test the game by pressing Cmd+R on Mac or Ctrl+R on Windows.
You can try clicking anywhere on the game board to spawn the marble after the game starts.
Great! You’ve learn how to spawn a physics node in the game.