Tiles are not showing in the tilemaplayer as intended

Godot Version

4.4.1.stable

Question

I re-created nodes in my World_Map scene, to bring everything into just one scene (with the exception to the main menu, that’s a difference scene). The idea is that the world map would show and when a city is clicked on, the world map would then be hidden, while the cargo loading nodes would then appear on screen. I am trying to write some code so that when the player clicks on a cargo button, a cargo tile would show and be played on-screen. Except that is not happening for some reason. The buttons operate as intended, except that the tiles are not showing. I even have the World_Map scene as the main scene in the Project Settings. Below is the code I have so far:

extends TileMapLayer

@onready var world_map: Node2D = $".."
@onready var cargo: TileMapLayer = $"."
@onready var h_box_container: HBoxContainer = $"../HUD/Panel/HBoxContainer"
@onready var ship_count: Label = $"../HUD/VBoxContainer/Ship_count"
@onready var canvas_layer: CanvasLayer = $"../Camera2D/CanvasLayer"
@onready var hud: CanvasLayer = $"../HUD"
@onready var tile_map_layer: TileMapLayer = $"../TileMapLayer"

var source_id: int
var x_counter: int = 3
var cargo_vector = Vector2i(0, 0)
var qty_ships: int = 0
var selected_cargo = []

func button_pressed(btn: Button, cargo_selector, destination):
	cargo_vector = world_map.cargo[cargo_selector][0]
	selected_cargo.append(cargo_selector)
	cargo.set_cell(Vector2(x_counter, 4), 1, cargo_vector)
	x_counter += 1
	btn.queue_free()
	
	# Finds distance between origin city and destination city, then multiply it with income rate based on cargo.
	Globals.origin_city_vector = Globals.cities[Globals.current_city]
	Globals.destination = destination
	var cargo_rate = world_map.cargo[cargo_selector][1]
	Globals.travel_distance = Globals.origin_city_vector.distance_to(Globals.cities[Globals.destination])
	Globals.cargo_income = Globals.cargo_income + (Globals.travel_distance * cargo_rate)

func _on_send_cargo_pressed():
	x_counter = 3
	Globals.balance = Globals.balance + Globals.cargo_income
	tile_map_layer.airship_transit()
	Globals.active_cities[Globals.current_city] -= 1
	Globals._save()
	canvas_layer.visible = true
	tile_map_layer.visible = true
	hud.visible = false
	cargo.visible = false

func _on_buy_airship_pressed():
	Globals.active_cities[Globals.current_city] += 1
	ship_count.text = "Ship count: " + str(Globals.active_cities[Globals.current_city])
	Globals._save()

Screenshots on the properties of the tilemaplayer:



Screenshots on how I have my nodes organized:


EDIT: If you need more information, please let me know.

Is this button_pressed() function connected to a signal somewhere?

In the line cargo.set_cell() are you sure that the atlas_id parameter is 1 and not 0 for example?

Do you have any error printed in the Output or the Debugger docks?

The signal from “button_pressed()” is from this method, in the TileMapLayer node (which populates cities on the world map as buttons):

func populate_cities():
	for key in Globals.cities:
		var btn = Button.new()
		btn.icon = CITY
		btn.text = str(key)
		btn.flat = true
		btn.alignment = HORIZONTAL_ALIGNMENT_LEFT
		btn.position = map_to_local(Globals.cities[key])
		btn.pressed.connect(cargo_scene.bind(btn.text))
		add_child(btn)
		#Makes the button transparent if it is not an accessible city
		if Globals.active_cities.has(key) == false:
			btn.modulate.a = 0.5

For “cargo.set_cell()” the Atlas ID is in fact, 1:

The error I get in the output when I run the scene is as follows:
image

FYI, I tried to run a plugin for Godot4 but decided it wasn’t needed, so I deleted the folder. Not sure if that’s relevant.

Hi,

I did some more work and found out that I didn’t even have the code to set_cell() of the cargo tiles to begin with. Whoops. Below is the code I typed, so far:

func process(_delta: float):	
	#Creates preview version of building sprite, hovers on mouse position
	new_mouse_position = local_to_map(get_local_mouse_position())
	if old_mouse_position != new_mouse_position:
		erase_cell(old_mouse_position)
		
	set_cell(new_mouse_position, 1, cargo_vector)
	old_mouse_position = new_mouse_position
	
	if Input.is_action_pressed("LEFT_CLICK"):
		set_cell(new_mouse_position, 1, cargo_vector)
		
	if get_cell_atlas_coords(new_mouse_position) != Vector2i(-1, -1):
		modulate = Color.RED

However, despite this attempt, I still don’t see any tiles being shown on screen on the tilemap for some reason. The idea is to have the cargo tile follow the mouse, until the player left clicks to place the cargo on screen. The modulate is to have the tile colored red if it overlaps over an already-placed tile.

Do you make the cargo TileMapLayer visible anywhere? it starts hidden in the scene and I can only see a cargo.visible = false in your code

Hi,

I apologize, I now understand I should’ve shown more of my code. Below is the code I have for the “TileMapLayer” code, which is shown over the World_Map TextureRect. When you click on a city, it showns the Cargo TileMapLayer, while making the TileMapLAyer node invisible (I did this instead of having two separate scenes):

extends TileMapLayer

const CITY = preload("res://sprites/city.png")
const airship_sprite = preload("res://sprites/Airship_icon.png")
const speed = 5

@onready var tile_map_layer: TileMapLayer = $"."
@onready var world_map: TextureRect = $World_Map
@onready var canvas_layer: CanvasLayer = $"../Camera2D/CanvasLayer"
@onready var hud: CanvasLayer = $"../HUD"
@onready var window: Window = $"../Window"
@onready var window_2: Window = $"../Window2"
@onready var camera_2d: Camera2D = $"../Camera2D"
@onready var balance_label: Label = $"../Camera2D/CanvasLayer/HBoxContainer/VBoxContainer/Balance"
@onready var calendar: Label = $"../Camera2D/CanvasLayer/HBoxContainer/VBoxContainer/Calendar"
@onready var airship_count: Label = $"../Camera2D/CanvasLayer/HBoxContainer/VBoxContainer/Airship_Count"
@onready var cargo: TileMapLayer = $"../Cargo"

var button_status: bool = false
var travel_time_multiplier: int = 3
var timer_counter: int = 1
var year: int = 2025
var airship_btn = Button.new()

# Called when the node enters the scene tree for the first time.
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(Globals.balance)
	populate_cities()
	if Globals.cargo_income != 0:
		airship_transit()
	count_ships()

func populate_cities():
	for key in Globals.cities:
		var btn = Button.new()
		btn.icon = CITY
		btn.text = str(key)
		btn.flat = true
		btn.alignment = HORIZONTAL_ALIGNMENT_LEFT
		btn.position = map_to_local(Globals.cities[key])
		btn.pressed.connect(cargo_scene.bind(btn.text))
		add_child(btn)
		#Makes the button transparent if it is not an accessible city
		if Globals.active_cities.has(key) == false:
			btn.modulate.a = 0.5

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:
			cargo.visible = true
			canvas_layer.visible = false
			tile_map_layer.visible = false
			hud.visible = true
	else:
		window.show()

func airship_transit():
	#Spawns new airship button in World Map
	airship_btn.icon = airship_sprite
	airship_btn.flat = true
	airship_btn.position = map_to_local(Globals.cities[Globals.current_city])
	add_child(airship_btn)
	airship_btn.pressed.connect(self.button_pressed.bind())
	
	#Restarts cargo income variable
	Globals.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(Globals.cities[Globals.current_city]), Globals.travel_distance * travel_time_multiplier)
	tween.tween_property(airship_btn, "position", map_to_local(Globals.cities[Globals.destination]), Globals.travel_distance * travel_time_multiplier)
	await tween.finished
	airship_btn.queue_free()
	
	#Updates airship count at destination city
	Globals.active_cities[Globals.destination] += 1
	count_ships()

#Used when player clicks on the airship button
func button_pressed():
	print("1")

#Used to purchase access to a city
func _on_yes_pressed():
	Globals.active_cities[str(Globals.current_city)] = 0
	populate_cities()
	window.hide()

func _on_no_pressed():
	window.hide()

func _on_button_pressed():
	window_2.hide()

var maintenance_cost: int = 5
var fuel_cost: int = 2

func _on_timer_timeout():
	timer_counter += 1
	calendar.text = str("Week " + str(timer_counter) + ", " + str(year))
	Globals.balance = Globals.balance - (maintenance_cost * qty_ships) - (fuel_cost * qty_ships)
	balance_label.text = "$ " + str(Globals.balance)

var qty_ships: int = 0

func count_ships():
	for key in Globals.active_cities:
		qty_ships = qty_ships + Globals.active_cities[key]
	airship_count.text = "Airships available: " + str(qty_ships)

are you sure that the cargo TileMapLayer is visible? You can check the Remote scene tab and see what’s the current status of the runtime nodes.

If it’s visible but you can’t see it make sure that there’s no other graphics covering it.

Hi,

I was able to figure it out. This is what I did:

func _process(_delta: float):
	set_cell(new_mouse_position, 1, cargo_vector)
	new_mouse_position = local_to_map(get_local_mouse_position())
	if old_mouse_position != new_mouse_position:
		erase_cell(old_mouse_position)
		old_mouse_position = new_mouse_position

func _input(event: InputEvent):
	#Creates preview version of building sprite, hovers on mouse position
	if Input.is_action_pressed("LEFT_CLICK"):
		placed_cargo.set_cell(new_mouse_position, 1, cargo_vector)

I made a new tilemaplayer, so the tiles can be permeanantly set on a separate tilemaplayer. It didn’t work when I tried to do that on the cargo tilemaplayer.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.