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?
Limit the Spawn Location
At the moment, players can spawn the marble anywhere on the game board, allowing them to easily score by dropping the marble directly into the score zone.
To fix this, limit the spawn location. Modify the _spawn_marble(_position)
function to reject the spawn if the mouse position is below the drop border.
func _spawn_marble(_position):
#1
var border = $GameBoard.get_node("DropBorder")
#2
var border_rect = border.get_global_rect()
var border_y = border_rect.position.y
#3
if(_position.y >= border_y):
return
# original code
var marble_instance = marble.instantiate()
marble_instance.position = _position
marble_instance.name = "marble"
add_child(marble_instance)
Here’s the explanation of the code:
- First, you get the reference of the DropBorder in the game board
- Then you find the y position of the border.
- You skip the spawn logic if the mouse position is below the border.
Now, run to check if you can only drop the marble above the drop border.
Adding the Score Logic
The next step is to implement the score logic so players can score when the marble drops into the score zone.
To do this, you’ll add another physics node, Area2D. This node will create a score trigger area. When the marble enters the area, it will emit a signal to the main scene to increase the score.
The Area2D node doesn’t cause physics reactions but can detect collisions. It’s often used for score zones or power-up items.
Define the Score Triggers
To detect a marble drop in a score box, you need to add score triggers illustrated below:
First, open the GameBoard scene by double-clicking game_board.tscn to create the score triggers.
Add an Area2D ChildNode under the rootNode below ScoreLabel12. Rename it TriggerArea1. Set the position to (x:135, y:1040).
Next, add a CollisionShape2D child node under TriggerArea1. Set its Shape to Rectangle2D and its size to (x: 200, y: 20).
After you create the first score trigger, duplicate the TriggerArea1 twice. You’ll get TriggerArea2 and TriggerArea3. Godot automatically renames the number suffix for you. Other settings, such as CollisionShape and Size, will be the same.
Now move the new triggers to their locations corresponding to the design. Change the x position of TriggerArea2 to 360 and TriggerArea3 to 585.
The above steps complete only half of the work. The other half is to make the triggers emit a signal when the marble passes the trigger area.
First, define the score signal by adding signal score_earned(score: int)
at the beginning of game_board.gd after the extends Node2D
statement.
Then, add the following functions to emit signals with different score values:
func _on_passed_score10(body: Node2D):
score_earned.emit(10)
func _on_passed_score20(body: Node2D):
score_earned.emit(20)
Finally, link the trigger areas body_exited
signal to the above functions. Select TriggerArea1 in the Scene tab, click the Node tab and double-click body_exited signal to open the Connect a signal to a Method dialog.
After opening the dialog, click on the Pick button and select _on_passed_score10
. Finally, click on Connect button.
Connect TriggerArea2 signal to _on_passed_score20
. Also, connect TriggerArea3 signal to _on_passed_score10
using the same way.
Now, the GameBoard scene will emit signals when players earn the score. Next, you’ll handle the signals in the main scene.
Handling the Score Signal
The final step of the score logic is to handle the score signal and update the score on the user interface.
Now, open main_scene.gd and add a new variable to keep track of the total score:
var total_score = 0
In the _ready
function, set the initial score and display it on the user interface (GUI):
total_score = 0
$GUI.set_score(total_score)
Next, add a method to handle score increases:
func _on_score_earned(score):
total_score += score
$GUI.set_score(total_score)
Bind this method to the score_earned
signal of the GameBoard. Select the Gameboard Node in the Scene Tab. Then go to the Node tab and connect the score_earned
signal to the _on_score_earned
method.
Now run and test your game. When the marbles pass through the scoring triggers, the score will increase by 10 or 20 points.
Adding the StaticBody2D pegs
To make the game challenging and fun, add pegs that affect the marble’s path to the score trigger. This mechanism will encourage players to drop marbles in different locations for the best score.
To do this, pegs will have the following characteristics:
- They are stationary.
- They bounce off the marble when it hits them
Next, you’ll use another type of physics node, StaticBody2D. Remember, StaticBody2D nodes don’t move under physics simulation but can affect other physics nodes.
Now, similar to how you created the marble, create a new scene for the pegs.
Creating the Peg Scene
Create a new scene for the Peg object. Select the scenes folder in the FileSystem dock. Right-click and select Create New ▸ Scene. Configure the following in the opened dialog:
- Root Type: StaticBody2D
- Scene Name: peg.tscn
Next, select the StaticBody2D node and rename it to Peg. With the Peg node selected, configure its PhysicsMaterial as follows:
- Friction: 0
- Bounce: 1
The Friction value is set to 0 to make the marble slide off the pegs easily. The Bounce value is set to 1 to make the marble bounce off the pegs with the same speed.
Next, you need to work on the appearance as well as the collision shape of the pegs.
Right-click the Peg to open the submenu. Select Add Child Node and choose Sprite2D to create the Sprite2D node.
Drag sprites/peg_orange.svg from FileSystem dock to the Texture property in the Inspector view of the Sprite2D node.
Next, change the Scale property to 0.1 to reduce its size.
Once the appearance is set up, define the collision shape of the peg. Right-click the Peg node and select Add Child Node. Then, choose CollisionShape2D to create the node.
In the settings of the CollisionShape2D node, set the Shape property to CircleShape2D and adjust the Radius to 10 pixels to match the size of the peg.
Now that you’ve successfully created the Peg scene.
When you preview in the 2D screen. You’ll see this:
The next step is to place the pegs between the spawn location and the score triggers on the main game scene.