# Godot 101 - Part 6: Area-based Collisions

###### Tags: godottutorialgamedev

This is part 6 of “Godot 101”. In this installment, we’ll learn how to detect when two collision areas overlap, so we can make our player run around and pick up gems. If you haven’t already read through the previous parts, please start with Part 1.

Godot 101 is an introduction to the Godot game engine and how it works. If you’ve never used a game engine before, or if you’re just new to Godot, this is the place to start. If you’re new here, a quick note about this website: we’re called KidsCanCode because we teach programming and game development to kids, but if you’re an adult you’re welcome here, too. We don’t believe in dumbing-down the material for kids, and game development is hard - so it will probably be challenging no matter what your age.

You can watch a video version of this lesson here:

### Gem Scene

First, let’s create a new scene for our gem objects. The tree will look like this:

• `gem`
• `sprite`
• `collision`

We’ll use the gem image from the art folder, and a basic `RectangleShape2D` for the collision. Resize it to cover the sprite texture, and remember: don’t scale the collision shape! Use the handles to adjust the extents of your rectangle - see the previous lesson if you need help.

### Main Scene

Now we can start building our main scene. The root will just be a plain `Node` named “main”. Click the “Instance” button: and choose the player scene.

We don’t want to have to add a bunch of gem instances manually, so we’re going to do it in code. We’ll be spawning lots of gems, and we will want to keep track of how many are left, so let’s make a node to hold them all. Add another `Node` as a child of `main` and call it `gem_container`. Then add a script to the `main` node with the following code:

``````extends Node

var screensize
var score = 0

randomize()
screensize.get_viewport().get_rect().size
set_process(true)
spawn_gems(10)

func spawn_gems(num):
for i in range(num):
var g = gem.instance()
g.set_pos(Vector2(rand_range(40, screensize.width-40),
rand_range(40, screensize.height-40)))

``````

In this script, we use `preload` to load the gem scene into memory so we can use it to create instances. We also assign a variable to the `gem_container` node so we can easily refer to it. Our `spawn_gems` function just takes a number and creates that many gem instances, assigning them as children of `gem_container` and setting `pos` to a random location. Run the scene, and you should see this:

### Area collisions - using signals

We want to have the gem disappear (be picked up) when the player touches it. Click on the `gem` node and then click “Node” in the Inspector:

This is a list of all the signals that an `Area2D` node can produce. The ones labeled `area_*` are for detecting other area nodes, while the `body*` ones are for detecting `PhysicsBody2D` nodes. The one we want to use is `area_enter` which will return the area that entered - in our case the player.

Click on the `area_enter` signal and click the “Connect” button. You will then see the following dialog:

Click to enlarge

This lets us set what node we want the signal to be sent to. `gem` is highlighted in red because it’s the current node. That’s fine, and at the bottom we’ll leave the “Method in Node” name as it is. Godot will now create that function for us. To start, let’s fill it out like this:

``````func _on_gem_area_enter(area):
print(area.get_name())
``````

Now when you move the player over a gem, you will see “player” printed in the output window. However, if you run it a couple of times, you might see something like this as well:

``````@gem@4
@gem@7
``````

What’s happening here? Well, this signal is generated when any area enters the gem’s area. This includes other gems! If we just deleted a gem when this signal happens, then two touching gems would delete each other, and we don’t want that. So we’re going to make sure and check the name of the entering area:

``````func _on_gem_area_enter(area):
if area.get_name() == 'player':
queue_free()
``````

### Spawning more gems

Back in our `main` scene, we want to detect when the player has collected all the gems, so we can spawn more. We do that by looking at the `gem_container` and counting its children:

``````var level = 1

func _process(delta):
if gem_container.get_child_count() == 0:
level += 1
spawn_gems(level * 10)
``````

We add a variable called `level` and whenever the `gem_container` is empty, we increment it and spawn more gems. Collect away!

## Wrapping Up

The next step will be to increment the player’s score when they collect a gem. However, there’s a catch: the code that detects collision and deletes the gem is running on the gem node, while the code that holds the score (and will display it) is on the `main` node. So we need a way to have an instanced node communicate with another node that is farther up the tree. This is a common occurrence, but is often done incorrectly by beginners. In the next lesson, we’ll look at the wrong (but obvious) way to do this, and then show how to do it properly.