Use this space for questions related to what you're learning. For any other type of support (website, learning platform, payments, etc...) please get in touch using the contact form.
a few question when translate to godot 4xccdswhen I translate this code to godot 4, I find there a few place needed to update. please check these code are correct or not.
1. The set_cellv function has been changed to set_cell, and set_cell now requires additional parameters. The get_cellv function can be replaced with get_cell_source_id.
2. If there is no tileset in the tilemap like TowerPlacer, the local_to_map and map_to_local functions won't work. In such cases, you need to use the tilemap from _visual_grid and its corresponding methods.
3. The map_to_local function returns the centered position of a cell, so you should position the tower's origin in the center rather than at the top-left corner.
4. Because the "select" and "tower_placement" actions share the same input event, I noticed that when I click the left mouse button to place a tower on the tilemap, two functions run simultaneously: the first is the TowerPlacer's _place_tower function, and the second is SelectableArea2D's _input_event function. This might not be a bug, but I want to know how to ensure that only one function responds to the input event.
```gdscript
extends TileMap
class_name TowerPlacer
signal tower_placed(tower)
# The ID of the tiles where players can place a tower.
const AVAILABLE_CELL_ID := 0
# The ID of cells already occupied or obstructed
const INVALID_CELL_ID := 1
@onready var _visual_grid = $VisualGrid
var _current_tower: Tower
var _current_cell := Vector2.ZERO
# Called when the node enters the scene tree for the first time.
func _ready():
set_process_unhandled_input(false)
# test code
setup_available_cells([Vector2(12, 7), Vector2(13, 8), Vector2(14, 9)])
var tower = load("res://Objects/Towers/tower.tscn").instantiate()
add_new_tower(tower)
func set_cell_unplaceable(cell: Vector2) -> void:
set_cell(0, cell,INVALID_CELL_ID,Vector2i(0,0),0 )
func set_cell_placeable(cell: Vector2) -> void:
set_cell(0, cell,AVAILABLE_CELL_ID,Vector2i(0,0),0 )
func is_cell_placeable(cell: Vector2) -> bool:
return get_cell_source_id(0, cell) == AVAILABLE_CELL_ID
func setup_available_cells(cells_array: PackedVector2Array) -> void:
for cell in cells_array:
set_cell_placeable(cell)
func add_new_tower(tower: Tower) -> void:
# Remove the current tower to work only with the newest one
if _current_tower:
_current_tower.queue_free()
add_child(tower)
_current_tower = tower
set_process_unhandled_input(true)
_visual_grid.visible = true
_snap_tower_to_grid()
func _unhandled_input(event) -> void:
if event is InputEventMouseMotion:
_snap_tower_to_grid()
if event.is_action_pressed("tower_placement"):
_place_tower()
func _snap_tower_to_grid() -> void:
_current_cell = _visual_grid.local_to_map(get_global_mouse_position())
_current_tower.global_position = _visual_grid.map_to_local(_current_cell)
if not is_cell_placeable(_current_cell):
_current_tower.modulate = Color(1, 0.375, 0.375)
else:
_current_tower.modulate = Color.WHITE
func _place_tower() -> void:
set_process_unhandled_input(false)
_visual_grid.visible = false
if not is_cell_placeable(_current_cell):
_current_tower.queue_free()
_current_tower = null
return
set_cell_unplaceable(_current_cell)
tower_placed.emit(_current_tower)
_current_tower.sold.connect(_on_tower_sold)
_current_tower = null
func _on_tower_sold(_price: int, place: Vector2) -> void:
set_cell_placeable(_visual_grid.local_to_map(place))
```10Aug. 15, 2024
Lesson Q&A
Use this space for questions related to what you're learning. For any other type of support (website, learning platform, payments, etc...) please get in touch using the contact form.