Ga naar hoofdinhoud

Inventory UI

Interface voor het beheren van items en containers.

Overzicht

┌─────────────────────────────────────────────────────────────────┐
│ INVENTORY [X] │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ [Rugzak 1] [Rugzak 2] [Buidel] Container ││
│ └─────────────────────────────────────────────────────────────┘│
│ │
│ ┌───┬───┬───┬───┬───┬───┬───┬───┐ │
│ │🍯 │🌰 │🥕 │ │ │ │ │ │ Row 1 │
│ │x5 │x99│x12│ │ │ │ │ │ │
│ ├───┼───┼───┼───┼───┼───┼───┼───┤ │
│ │🪵 │🪨 │ │ │ │ │ │ │ Row 2 │
│ │x45│x23│ │ │ │ │ │ │ │
│ └───┴───┴───┴───┴───┴───┴───┴───┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ Selected: Honingpot ││
│ │ "Zoete honing van de bijen" ││
│ │ [Gebruiken] [Weggooien] ││
│ └─────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────┘

Scene Structuur

InventoryPanel (Control)
├── Background (NinePatchRect)
├── Header (HBoxContainer)
│ ├── Title (Label)
│ └── CloseButton
├── ContainerTabs (HBoxContainer)
│ └── [ContainerTabButton instances]
├── ItemGrid (GridContainer)
│ └── [ItemSlot instances]
├── ItemInfo (VBoxContainer)
│ ├── ItemName (Label)
│ ├── ItemDescription (Label)
│ └── ActionButtons (HBoxContainer)
└── DragPreview (Control)

Item Slot Component

Scene: ui/item_slot.tscn

ItemSlot (Control)
├── Background (TextureRect)
├── ItemIcon (TextureRect)
├── QuantityLabel (Label)
├── RarityBorder (TextureRect)
└── SelectionHighlight (ColorRect)

Script

# item_slot.gd
extends Control

signal item_selected(slot_index: int)
signal item_used(slot_index: int)

@export var slot_index: int = 0
@export var container_id: int = 0

@onready var item_icon: TextureRect = $ItemIcon
@onready var quantity_label: Label = $QuantityLabel
@onready var rarity_border: TextureRect = $RarityBorder

var item_data: Dictionary = {}

func set_item(item_id: String, quantity: int, icon: Texture2D = null) -> void:
if item_id.is_empty():
clear()
return

item_data = {
"item_id": item_id,
"quantity": quantity
}

if icon:
item_icon.texture = icon
else:
item_icon.texture = _load_item_icon(item_id)

quantity_label.text = str(quantity) if quantity > 1 else ""
quantity_label.visible = quantity > 1

func clear() -> void:
item_data = {}
item_icon.texture = null
quantity_label.visible = false

func _load_item_icon(item_id: String) -> Texture2D:
var path = "res://assets/items/%s.png" % item_id
if ResourceLoader.exists(path):
return load(path)
return preload("res://assets/ui/item_placeholder.png")

Drag & Drop

Drag Start

func _get_drag_data(at_position: Vector2) -> Variant:
if item_data.is_empty():
return null

# Create visual preview
var preview = TextureRect.new()
preview.texture = item_icon.texture
preview.custom_minimum_size = Vector2(48, 48)
preview.modulate.a = 0.8
set_drag_preview(preview)

return {
"type": "inventory_item",
"source_slot": slot_index,
"source_container": container_id,
"item": item_data.duplicate()
}

Drop Handling

func _can_drop_data(at_position: Vector2, data: Variant) -> bool:
if not data is Dictionary:
return false
if data.get("type") != "inventory_item":
return false
return true

func _drop_data(at_position: Vector2, data: Variant) -> void:
var source = data as Dictionary

# Same slot - do nothing
if source.source_slot == slot_index and source.source_container == container_id:
return

# Call inventory manager to move
inventory_manager.move_item(
source.source_container,
source.source_slot,
container_id,
slot_index,
source.item.quantity
)

Container Tabs

Tab Component

# container_tab_button.gd
extends Button

signal tab_selected(container_id: int)

var container_id: int = 0
var container_name: String = ""

func setup(id: int, name: String, icon: Texture2D) -> void:
container_id = id
container_name = name
text = name
self.icon = icon

func _pressed() -> void:
tab_selected.emit(container_id)

Tab Switching

# inventory_panel.gd
func _on_tab_selected(container_id: int) -> void:
_current_container = container_id
_rebuild_grid()
_update_tab_visuals()

func _update_tab_visuals() -> void:
for tab in container_tabs.get_children():
if tab is Button:
tab.button_pressed = (tab.container_id == _current_container)

Grid Management

Building the Grid

func _rebuild_grid() -> void:
# Clear existing slots
for child in item_grid.get_children():
child.queue_free()

# Get container info
var container = inventory_manager.get_container_by_id(_current_container)
if container.is_empty():
return

var container_type = _get_container_type(container.container_type)
var slot_count = container_type.slot_count

# Create slots
for i in range(slot_count):
var slot = ITEM_SLOT_SCENE.instantiate()
slot.slot_index = i
slot.container_id = _current_container
slot.item_selected.connect(_on_item_selected)
item_grid.add_child(slot)

# Fill with items
_update_items()

func _update_items() -> void:
var items = inventory_manager.get_container_items(_current_container)

for slot in item_grid.get_children():
var item = items.get(slot.slot_index, {})
if item.is_empty():
slot.clear()
else:
var def = _get_item_definition(item.item_id)
slot.set_item(item.item_id, item.quantity, _load_icon(def.icon_path))

Item Info Panel

Display Selected Item

func _on_item_selected(slot_index: int) -> void:
_selected_slot = slot_index
var items = inventory_manager.get_container_items(_current_container)
var item = items.get(slot_index, {})

if item.is_empty():
_hide_item_info()
return

var def = _get_item_definition(item.item_id)

item_name.text = def.display_name
item_description.text = def.description

# Show appropriate action buttons
use_button.visible = _is_usable(def.category)
drop_button.visible = true

item_info_panel.visible = true

Action Buttons

func _on_use_pressed() -> void:
if _selected_slot < 0:
return

var items = inventory_manager.get_container_items(_current_container)
var item = items.get(_selected_slot)

if item.is_empty():
return

# Use the item
_use_item(item)

func _on_drop_pressed() -> void:
if _selected_slot < 0:
return

# Confirm dialog
confirm_dialog.show_confirmation(
"Item weggooien?",
"Weet je zeker dat je dit item wilt weggooien?",
func(): inventory_manager.remove_item(_current_container, _selected_slot, 1)
)

Keyboard Navigation

func _input(event: InputEvent) -> void:
if not visible:
return

if event.is_action_pressed("ui_cancel"):
hide_panel()
return

# Arrow key navigation
if event.is_action_pressed("ui_right"):
_move_selection(1, 0)
elif event.is_action_pressed("ui_left"):
_move_selection(-1, 0)
elif event.is_action_pressed("ui_down"):
_move_selection(0, 1)
elif event.is_action_pressed("ui_up"):
_move_selection(0, -1)
elif event.is_action_pressed("ui_accept"):
_use_selected_item()

func _move_selection(dx: int, dy: int) -> void:
var columns = item_grid.columns
var current = _selected_slot
var new_slot = current + dx + (dy * columns)

if new_slot >= 0 and new_slot < item_grid.get_child_count():
_select_slot(new_slot)

Volgende