Arrastar e soltar

Fichas passando de um slot para outro. Três métodos fazem tudo: _get_drag_data, _can_drop_data e _drop_data.

O editor acima está rodando este projeto. Mude uma linha e ele recarrega.

Classes do Godot usadas

PanelContainerGridContainerColorRect

O código

scripts/main.gd
extends Node

const COLORS: Array = ['#8da5f3', '#8eef97', '#fc7f7f', '#f3d48d']
const SLOTS: int = 8


func _ready() -> void:
	var column: VBoxContainer = _root()

	var title: Label = Label.new()
	title.text = 'Drag the chips between slots'
	title.add_theme_font_size_override('font_size', 26)
	column.add_child(title)

	var hint: Label = Label.new()
	hint.text = 'three methods do all of it: _get_drag_data, _can_drop_data and _drop_data'
	hint.add_theme_color_override('font_color', Color('#999999'))
	column.add_child(hint)

	var grid: GridContainer = GridContainer.new()
	grid.columns = 4
	grid.add_theme_constant_override('h_separation', 16)
	grid.add_theme_constant_override('v_separation', 16)
	column.add_child(grid)

	var slot_script: GDScript = Get.script('slot')

	for i in SLOTS:
		var slot: PanelContainer = PanelContainer.new()
		slot.set_script(slot_script)
		grid.add_child(slot)

		if i < COLORS.size():
			slot.set_item(Color(COLORS[i]))


func _root() -> VBoxContainer:
	var background: ColorRect = ColorRect.new()
	background.color = Color('#12141a')
	add_child(background)
	background.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)

	var center: CenterContainer = CenterContainer.new()
	add_child(center)
	center.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)

	var column: VBoxContainer = VBoxContainer.new()
	column.add_theme_constant_override('separation', 18)
	center.add_child(column)

	return column
scripts/slot.gd
extends PanelContainer

var chip: ColorRect


func _ready() -> void:
	custom_minimum_size = Vector2(120, 120)

	var style: StyleBoxFlat = StyleBoxFlat.new()
	style.bg_color = Color('#1c1b1b')
	style.border_color = Color('#2a2f3d')
	style.set_border_width_all(1)
	style.set_corner_radius_all(12)
	style.set_content_margin_all(16)
	add_theme_stylebox_override('panel', style)

	chip = ColorRect.new()
	chip.color = Color.TRANSPARENT
	add_child(chip)


func set_item(color: Color) -> void:
	chip.color = color


func has_item() -> bool:
	return chip.color.a > 0.0


func _get_drag_data(_at: Vector2) -> Variant:
	if not has_item():
		return null

	var preview: ColorRect = ColorRect.new()
	preview.color = chip.color
	preview.size = Vector2(60, 60)
	set_drag_preview(preview)

	return {color = chip.color, from = self}


func _can_drop_data(_at: Vector2, data: Variant) -> bool:
	return data is Dictionary and data.has('color') and not has_item()


func _drop_data(_at: Vector2, data: Variant) -> void:
	data.from.set_item(Color.TRANSPARENT)
	set_item(data.color)

Mais exemplos de Interface