Godot Version
4.4.1.stable
Question
Even if you buy multiple airships, every time you send an airship, it “resets” the airship button instead of making a new airship button after sending a new set of cargo. I’d appreciate feedback on how to fix this.
This video shows how the error happens: https://drive.google.com/file/d/1ye7QXlZm1a0nZP8tYIemnIngeVFgWeB-/view?usp=drive_link
I have the relevant code in the ‘World _Map’ node (which is Autoloaded):
extends Node2D
signal cargo_sent()
var current_city: String = "Los Angeles"
var cargo_income: int
var destination: String
var travel_distance: float
var balance: int = 0
This is the code I had under the “TileMapLayer” node:
func _ready():
calendar.text = str("Week " + str(timer_counter) + ", " + str(year))
camera_2d.global_position = map_to_local(Vector2(78, 165))
balance_label.text = "$ " + str(WorldMap.balance)
populate_cities()
WorldMap.cargo_sent.connect(airship_transit)
if WorldMap.cargo_income != 0:
airship_transit()
func airship_transit():
#Spawns new airship button in World Map
var airship_btn = Button.new()
airship_btn.icon = airship_sprite
airship_btn.flat = true
airship_btn.position = map_to_local(WorldMap.cities[WorldMap.current_city])
add_child(airship_btn)
airship_btn.pressed.connect(self.button_pressed.bind())
#Restarts cargo income variable
WorldMap.cargo_income = 0
#Moves the spawned airship button from the origin to the destination cities
var tween = create_tween()
tween.tween_property(airship_btn, "position", map_to_local(WorldMap.cities[WorldMap.current_city]), WorldMap.travel_distance * travel_time_multiplier)
tween.tween_property(airship_btn, "position", map_to_local(WorldMap.cities[WorldMap.destination]), WorldMap.travel_distance * travel_time_multiplier)
await tween.finished
airship_btn.queue_free()
#Updates airship count at destination city
WorldMap.active_cities[WorldMap.destination] += 1
These are how I have the nodes organized:
This is the code I have in the “loading_cargo” scnee:
func _on_send_cargo_pressed():
WorldMap.balance = WorldMap.balance + WorldMap.cargo_income
WorldMap.cargo_sent.emit()
WorldMap.active_cities[WorldMap.current_city] -= 1
get_tree().change_scene_to_file("res://scenes/World_Map.tscn")
This code is in the “Cargo” node, which is organized below:
Okay, well done for being so detailed about the situation, I think the issue is in this method:
You said that you autoloaded the World_Map, but you’re changing the scene to World_Map, which I believe is creating a new instance of the World_Map scene, so the reason you’re only seeing the one air ship. I would suggest making a “GameManager” global autoload to replace the World_Map, keep the World_Map scene seperate and have the GameManager handle the variables and details you want to share between your scenes.
Hmm…I tried that. I transferred all variables from the “World_Map” script to a script named “Globals” and autoloaded “Globals” while removing “World_Map” script from autoload. That didn’t work.
Hmm, maybe I could have explained myself better. Okay, I assume you still have the “change_scene_to” method to change to the world map scene, it’s still resetting everything. You either need to have some code in your global scene that stores the data you want, or do something instead of changing the scene.
To clarify, here are the two things you could do:
- Create a list or dictionary in your global scene and have it include the buttons/airships you create. Then when you change the scene FROM the world map, have the code remove the button from the scene and not delete it, keeping a reference to in the global script. Then when you change to the new scene, add the buttons back to the scene.
OR
- Instead of using get_tree.change_scene_to_file(), always have your world map in the scene and have it show/hide and set the process mode, or remove the node from the scene tree without freeing it, so you’re always working with the same instance of the world map node.
I hope these make sense and you get your game working the way you want it to!
Understood, thank you! I tried the dictionary option but it still didn’t work. Maybe I got the code wrong, but I decided to try your other option instead.
I managed to copy and paste the nodes from the “loading_cargo” scene to the main “World_Map” scene. The results were…mixed. The video below shows the results:
This is how I have the nodes organized:
(There is a label as a child of the “loading_cargo” node, but the list was too large to show on-screen).
“TileMapLayer” node has the following changes to the code:
func cargo_scene(button_text: String):
Globals.current_city = button_text
#Checks if the city has airships
if Globals.active_cities.has(button_text):
if Globals.active_cities[Globals.current_city] == 0:
window_2.visible = true
else:
loading_cargo.visible = true
hud_2.visible = true
world_map.visible = false
The “Cargo2” node has the following changes to the code:
func _on_send_cargo_pressed():
Globals.balance = Globals.balance + Globals.cargo_income
Globals.cargo_sent.emit()
Globals.active_cities[Globals.current_city] -= 1
loading_cargo.visible = false
hud_2.visible = false
world_map.visible = true
Oddly enough, when the world map’s visibility is toggled off, I cannot even click on the buttons of the Loading_cargo. But when the “World_Map” is shown, the cargo buttons can be clicked on, but the tiles don’t show on-screen, following the mouse. This worked as intended before I did all this node moving.