【GDScript】Equipment Bar

Godot 3.2.4 rc3

Following the drag and drop of the previous [GDScript] item , we started to make the equipment bar .

Before we start , add two signals to the Goods.gd script.swap_goodsThe method sends a signal to determine whether the item has changed. The modified code is as follows:

signal swaped_property ( old_property , new_property ) 	# swap property signal
signal unload ( property ) 	# unload item

func swap_goods(a, b):
	# exchange item signal
	a.emit_signal("swaped_property", a.goods_property, b.goods_property)
	b.emit_signal("swaped_property", b.goods_property, a.goods_property)
	
	# unload item signal
	if a == null:
		b.emit_signal("unload", b.goods_property)
	if b == null:
		a.emit_signal("unload", a.goods_property)
	
	# do property exchange
	var p_temp = a.goods_property
	a.goods_property = b.goods_property
	b.goods_property = p_temp
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Add a TextureRect node to the Goods.tscn scene, change the node name to Background , check itshow_behind_parentproperties, settingsself modulateAttribute is black, checkexpandproperties, settingsrect_min_sizeAttributes are 50x50
insert image description here

rect_min_size property

The scene nodes are as follows
insert image description here

Add the code to modify the Background background in the setget section of the Goods.gd script, as follows:

export (Texture) var background setget set_background
onready var background_rect = $Background

func set_background(value):
	background = value
	if background_rect == null:
		yield(self, "ready")
	background_rect.texture = value
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Drag and drop the Godot icon icon.png file in the file system to the root node of the Goods nodeBackgroundOn the property, it is used to hide the background image when dragging.

get_drag_dataAdd a line of code to the methoddrag_node.background_rect.visible = false
insert image description here


equipment panel scene

Create a new scene, add a Panel node as the root node, adjust its size, change the name to EquipmentPanel , save the scene, and then add a script to it. The script is created without writing code. As follows
insert image description here
Select the Goods node and press Ctrl + D , copy 6, and then adjust the position. The completed scene is as follows:
insert image description here

The code in the EquipmentPanel node script is as follows:

## Equipment Panel
## Equipment panel
extends Panel


signal property_changed ( old_value , new_value ) 	# property changed signal


# Same here, you can add the class_name of the corresponding name in the script below
# This way you don't have to write these two constants here, I don't like it very much, so I use this method here
const GoodsProperty = preload("res://inventory/GoodsProperty.gd")
const Goods = preload("res://inventory/Goods.gd")


## Sum of all item attributes
var  all_property  : =  { }



# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# Node with methods
# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
func _init ( )  - >  void : 
	var temp_goods_property = GoodsProperty . new ( ) 	# temporary property , used to get the variable judgment type
	 var GoodsPropertyList = GoodsProperty . GoodsProperty # Property list used to get the variable name
	
	## The following is to first record the required properties into the all_property dictionary for easy calculation
	for property in GoodsPropertyList . values ​​( ) : 
		var value = temp_goods_property . get ( property ) 	# property value
		 var property_type =  typeof ( value ) 	# property type
		
		# If it is an int type or a float type, it will be recorded in all_property
		if property_type ==  TYPE_INT :  	# int type
			all_property [ property ]  =  0 
		elif property_type ==  TYPE_REAL : 	# float type
			all_property[property] = 0.0


func _ready() -> void:
	# connect item signal
	for goods in get_children():
		goods.connect("swaped_property", self, "_on_Goods_swaped_property")
		goods.connect("unload", self, "_on_Goods_unload")



# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# custom method
# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
## change properties
## @property item properties
## @is_add whether to add, if false , subtract
func change_property(goods_property: GoodsProperty, is_add: bool):
	var temp_all_property = all_property.duplicate(true)
	
	# add
	if is_add:
		for property in all_property.keys():
			var value = goods_property.get(property)
			all_property[property] += value
	# minus
	else:
		for property in all_property.keys():
			var value = goods_property.get(property)
			all_property[property] -= value
	
	emit_signal("property_changed", temp_all_property, all_property)



# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# connect the signal
# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
func _on_Goods_swaped_property ( old_property , new_property )  - >  void : 
	if old_property !=  null : 
		change_property ( old_property ,  false ) 	# subtract old properties
		 print ( "Replace items:" , old_property . goods_name )
	
	if new_property !=  null : 
		change_property ( new_property ,  true ) 		# add new properties
		 print ( "equipment items:" , new_property . goods_name )


func _on_Goods_unload ( property )  - >  void : 
	change_property ( property ,  false ) 	# minus property
	 print ( "Unload items:" , property . goods_name )

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

Test item equipment scene

Create a new scene, add PanelContainer as the root node, add an HBoxContainer node, add a VBoxContainer node under the HBoxContainer node ,
insert image description here
then add the EquipmentPanel scene under the HBoxContainer node, add the Inventory scene to the VBoxContainer node, and check the VBoxContainer and EquipmentPanel nodes.size flag_horizontalattributeExpand

  • VBoxContainer node'ssize_flag_stretch_ratioThe property is set to 0.7 (the proportion of Container type nodes is 0.7)
  • EquipmentPanel node'ssize_flag_stretch_ratioThe attribute is set to 0.3 (the proportion of Container type nodes is 0.3)

For example , the properties set by EquipmentPanel
insert image description here

Add a Label node to the VBoxContainer node, and the Label node'srect_min_sizeattributeYvalue is set to100, the Label node name is changed to PropertyLabel . Change the name of the root node PanelContainer to Test and add a script

The node structure of the scene will be as follows:
insert image description here
SelectEquipmentPanelnode, clickproperty_changedSignal, connected to the script in the Test node.

The Test node script code is as follows:

## Test
## Test item scene
extends PanelContainer


onready var property_label = $HBoxContainer/VBoxContainer/PropertyLabel
onready var equip_panel = $HBoxContainer/EquipmentPanel


# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# Node with methods
#------------------------------
func _ready() -> void:
	property_label.text = format_data_to_text(equip_panel.all_property)



# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# custom method
# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
## Format data to text
func format_data_to_text(data) -> String:
	var text = ""
	for key in data:
		text += key + ": " + str(data[key]) + "\n"
	return text



# -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# connect the signal
#------------------------------
func _on_EquipmentPanel_property_changed(old_value, new_value) -> void:
	# Display the attributes in the equipment bar. You can also write your own when the attributes change,
	# The statement for modifying the role attribute, I will not write it here.
	property_label.text = format_data_to_text(new_value)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

After completion , the Goods node in the Inventory scenegoods_propertyThe attribute may become empty and need to be added again. Let's test it to see the effect. The following is the Gif rendering. Note the changes in the label text below.

insert image description here
The following is the file download link:
Link: https://pan.baidu.com/s/1Q9nNBGmPGfkVKwyUIcTKGw
Extraction code: xw2c

Related: 【GDScript】Equipment Bar