1
\$\begingroup\$

I have created and finished my game in Godot, but I want to add a scoring system. Specifically, I want the score to increase by 1 every time the player touches a coin. However, I am not sure how to implement this. Can someone please guide me on how many scenes I need to create and which nodes I need to use? I currently have a scene called ‘coin’ which has an Area2D node

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

You should not need any more scenes than you have.

I'm going to suggest to do this with a Signal Bus, although it is not the only approach.

Mainly you need to do this:

  • Create an autoload with an script that has a score variable. So you can access it from anywhere in the scene tree of your game.

    extends Node
    
    var score := 0
    

    You need to give a name to the autoload, for the purposes of this answer I'll call it Board.

  • In a method connected to the body entered signal of your Area2D increment the variable. I recommend using a method in a script attached to the Area2D itself.

    func _on_coin_body_entered(body) -> void:
        # ...
        Board.score += 1
    

Now, presumably, you don't just want the score to increment. You want to do something with it.

So, I'd suggest you:

  • Declare a signal to notify when the score changed.

    extends Node
    
    signal score_changed(score)
    
    var score := 0
    
  • Then create a setter for the score variable, that emits the signal.

    Godot 3

    extends Node
    
    signal score_changed(score)
    
    var score := 0 setget set_score
    
    func set_score(mod_value:int) -> void:
        if score == mod_value:
            return
    
        score = mod_value
        emit_signal("score_changed", score)
    

    Godot 4

    extends Node
    
    signal score_changed(score:int)
    
    var score := 0:
        set(mod_value):
            if score == mod_value:
                return
    
            score = mod_value
            score_changed.emit(score)
    
  • Then you can connect to the signal from anywhere in the scene tree.

Now, what are you going to do with the score?

  • Presumably you want to show it, right?

    So in your UI (I suppose you have an scene for that, or you can add it to one of your scenes) you could add a Label and have a script that connects to the signal from the autoload, and when it gets it, it changes the text of the label.

    Something like this:

    Godot 3

    extends Label
    
    func _ready() -> void:
        Board.connect("score_changed", self, "_on_score_changed")
    
    func _on_score_changed(score:int) -> void:
        text = str(score)
    

    Godot 4

    extends Label
    
    func _ready() -> void:
        Board.score_changed.connect(_on_score_changed)
    
    func _on_score_changed(score:int) -> void:
        text = str(score)
    
  • Also presumably you want to store it, right?

    So you can add methods to the autoload that save it or load it from storage.

    I could give you the code to read and write the score as text alone in a file (you can still find that in the documentation if you want). However, usually we end up wanting to save multiple things in the file. So let me suggest to use the ConfigFile class, which will make INI-like files:

    Godot 3 or Godot 4

    const save_file := "user://saved.dat"
    
    func load() -> void:
        var file := ConfigFile.new()
        var err := file.load(save_file)
        if err != OK:
            push_error("error loading score " + str(err))
            return
    
        score = int(file.get_value("Player", "score"))
    
    func save() -> void:
        var file := ConfigFile.new()
        file.set_value("Player", "score", score)
        var err := file.save(save_file)
        if err != OK:
            push_error("error saving score " + str(err))
    

I hope you can see that this approach would work if you need to make a save file for your game, or you need to have a blackboard for the enemies to share information, or you want a configuration file, etc.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .