0
\$\begingroup\$

Using Godot 3.1, I've written this script for diamonds that the player collects:

extends Area2D

const save_location = "user://data.json"

var details = {
    "diamond": 0,
    "life": 0,
}
func _on_diamondfinal_body_entered(body):
    if body.name == "player":
        loading()
func loading():
    var file = File.new()
    if file.file_exists(save_location):
        file.open(save_location, File.READ)
        var data = parse_json(file.get_as_text())
        details = data
        
        details.diamond += 1
        saving()
        queue_free()

func saving():
    var file = File.new()
    file.open(save_location, File.WRITE)
    file.store_string(to_json(details))
    file.close()

And I have written this script for the "level one" scene:

extends Node2D

const save_location = "user://data.json"
var details = {
    "diamond": 0,
    "life": 0,
    
}


func _process(delta):
    loading()
    $CanvasLayer/Panel/diamond_label.text = str(details.diamond)
    $CanvasLayer/Panel/life_label.text = str(details.life)
    
    
    
    
func loading():
    var file = File.new()
    if file.file_exists(save_location):
        file.open(save_location, File.READ)
        var data = parse_json(file.get_as_text())
        details = data

I have two problems:

  1. When I play the "level one" scene, I collect diamonds, but their number does not increase in the scene and it remains at 00.

  2. In level one, there are 20 diamonds. How can I set it so that when I go back into the "level one" scene, the diamonds I have collected will not be displayed again?

    That means, no matter how many times the player loses and returns to this scene, only the diamonds that they have not already collected will be displayed.

\$\endgroup\$
0

1 Answer 1

0
\$\begingroup\$

You seem to be saving and loading a file in multiple locations on your game, instead of having it centralized (e.g. with an autoload). This leads to repetition. And any fix or update to how you handle, you need to make the changes in every location... Which makes it error prone since you might forget to update some.

My current advice is to use ConfigFile (although I see you have opted for JSON). I recently explained that solution in my answer to: Increment score when player touches a coin's Area2D.

Your code also has a time-to-check to time-to-use bug. While unusual, the save file could be removed after you checked if it exists and before you try to open it. The correct approach is to handle when Godot fails to open the file.


When I play the "level one" scene, I collect diamonds, but their number does not increase in the scene and it remains at 00.

You don't close the file in the second script. The contents of the file might not have been flushed to storage for the other script to read them.

I expect that having all the code that accesses the file in a single location would also fix this. You can then keep a single representation of the data in memory, which is the only one you save or load. And since everybody would be acceding through the same script, there should not be discrepancies in the data they see (barring multi-threading).


In level one, there are 20 diamonds. How can I set it so that when I go back into the "level one" scene, the diamonds I have collected will not be displayed again? That means, no matter how many times the player loses and returns to this scene, only the diamonds that he has not collected will be displayed.

How yo save which diamonds were collected? You save which diamonds were collected (not just how many). The same way you save anything else you save. However you choose to save things.

And then, every diamond on _ready can check if it has already been collected, and if so, erase itself with queue_free.

\$\endgroup\$

You must log in to answer this question.

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