Preparing for collisions
The player should detect when it hits a coin or an obstacle, but you haven't made them do so yet. That's OK, because you can use Godot's signal functionality to make it work. Signals are a way for nodes to send out messages that other nodes can detect and react to. Many nodes have built-in signals to alert you when a body collides, for example, or when a button is pressed. You can also define custom signals for your own purposes.
Signals are used by connecting them to the node(s) that you want to listen and respond to. This connection can be made in the Inspector or in the code. Later in the project, you'll learn how to connect signals in both ways.
Add the following to the top of the script (after extends Area2D):
signal pickup
signal hurt
These define custom signals that your player will emit (send out) when they touch a coin or an obstacle. The touches will be detected by the Area2D itself. Select the Player node and click the Node tab next to the Inspector to see the list of signals the player can emit:
Note your custom signals are there as well. Since the other objects will also be Area2D nodes, you want the area_entered() signal. Select it and click Connect. Click Connect on the Connecting Signal window—you don't need to change any of those settings. Godot will automatically create a new function called _on_Player_area_entered() in your script.
When connecting a signal, instead of having Godot create a function for you, you can also give the name of an existing function that you want to link the signal to. Toggle the Make Function switch to Off if you don't want Godot to create the function for you.
Add the following code to this new function:
func _on_Player_area_entered( area ):
if area.is_in_group("coins"):
area.pickup()
emit_signal("pickup")
if area.is_in_group("obstacles"):
emit_signal("hurt")
die()
When another Area2D is detected, it will be passed in to the function (using the area variable). The coin object will have a pickup() function that defines the coin's behavior when picked up (playing an animation or sound, for example). When you create the coins and obstacles, you'll assign them to the appropriate group so they can be detected.
To summarize, here is the complete player script so far:
extends Area2D
signal pickup
signal hurt
export (int) var speed
var velocity = Vector2()
var screensize = Vector2(480, 720)
func get_input():
velocity = Vector2()
if Input.is_action_pressed("ui_left"):
velocity.x -= 1
if Input.is_action_pressed("ui_right"):
velocity.x += 1
if Input.is_action_pressed("ui_up"):
velocity.y -= 1
if Input.is_action_pressed("ui_down"):
velocity.y += 1
if velocity.length() > 0:
velocity = velocity.normalized() * speed
func _process(delta):
get_input()
position += velocity * delta
position.x = clamp(position.x, 0, screensize.x)
position.y = clamp(position.y, 0, screensize.y)
if velocity.length() > 0:
$AnimatedSprite.animation = "run"
$AnimatedSprite.flip_h = velocity.x < 0
else:
$AnimatedSprite.animation = "idle"
func start(pos):
set_process(true)
position = pos
$AnimatedSprite.animation = "idle"
func die():
$AnimatedSprite.animation = "hurt"
set_process(false)
func _on_Player_area_entered( area ):
if area.is_in_group("coins"):
area.pickup()
emit_signal("pickup")
if area.is_in_group("obstacles"):
emit_signal("hurt")
die()