Godot 3.2.4 rc3
接着上一篇 【GDScript】物品的拖拽,我们开始做装备栏。
开始之前先在 Goods.gd 脚本里添加两 信号。swap_goods
方法里进行发出信号,判断物品是否发生改变,修改后的代码如下:
signal swaped_property(old_property, new_property) # 交换属性信号
signal unload(property) # 卸下物品
func swap_goods(a, b):
# 交换物品信号
a.emit_signal("swaped_property", a.goods_property, b.goods_property)
b.emit_signal("swaped_property", b.goods_property, a.goods_property)
# 卸下物品信号
if a == null:
b.emit_signal("unload", b.goods_property)
if b == null:
a.emit_signal("unload", a.goods_property)
# 进行属性交换
var p_temp = a.goods_property
a.goods_property = b.goods_property
b.goods_property = p_temp
get_drag_data
方法里添加一行代码 drag_node.background_rect.visible = false
Goods.tscn 场景里添加一个 TextureRect 节点,节点名称改为 Background,勾选 show_behind_parent
属性,设置 self modulate
属性为黑色,勾选 expand
属性,设置 rect_min_size
属性为 50x50
场景节点如下
在 Goods.gd 脚本 setget 部分添加修改 Background 背景的代码,如下:
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
将 文件系统里的 Godot 图标 icon.png 文件,拖放到根节点 Goods 节点的 Background
属性上
装备面板场景
新建一个场景,添加一个 Panel 节点作为根节点,调整它的大小,修改名称为 EquipmentPanel,保存场景,然后再给它添加一个脚本,脚本创建完先不写代码。如下
选中 Goods 节点按 Ctrl + D,复制 6 个,然后调整位置,完成后的场景如下:
EquipmentPanel 节点脚本中的代码如下:
## Equipment Panel
## 装备面板
extends Panel
signal property_changed(old_value, new_value) # 属性发生改变信号
# 这里也一样,你可以在下面的脚本里添加对应名称的 class_name
# 这样你就可以不用在这里写这两个常量了,我个人不太喜欢,所以我这里使用了这种方式
const GoodsProperty = preload("res://inventory/GoodsProperty.gd")
const Goods = preload("res://inventory/Goods.gd")
## 所有物品属性总和
var all_property := {}
#------------------------------
# 节点带有的方法
#------------------------------
func _init() -> void:
var temp_goods_property = GoodsProperty.new() # 临时属性,用于获取变量判断类型
var GoodsPropertyList = GoodsProperty.GoodsProperty # 属性列表,用于获取变量名
## 以下是为了先将需要的属性记录到 all_property 字典中,方便计算
for property in GoodsPropertyList.values():
var value = temp_goods_property.get(property) # 属性值
var property_type = typeof(value) # 属性类型
# 如果是 int 类型,或是 float 类型则记录到 all_property 中
if property_type == TYPE_INT: # int 类型
all_property[property] = 0
elif property_type == TYPE_REAL: # float 类型
all_property[property] = 0.0
func _ready() -> void:
# 连接物品信号
for goods in get_children():
goods.connect("swaped_property", self, "_on_Goods_swaped_property")
goods.connect("unload", self, "_on_Goods_unload")
#------------------------------
# 自定义方法
#------------------------------
## 改变属性
## @property 物品属性
## @is_add 是否增加,如果为 false 则为减去
func change_property(goods_property: GoodsProperty, is_add: bool):
var temp_all_property = all_property.duplicate(true)
# 加上
if is_add:
for property in all_property.keys():
var value = goods_property.get(property)
all_property[property] += value
# 减去
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)
#------------------------------
# 连接信号
#------------------------------
func _on_Goods_swaped_property(old_property, new_property) -> void:
if old_property != null:
change_property(old_property, false) # 减去旧属性
print("换掉物品:", old_property.goods_name)
if new_property != null:
change_property(new_property, true) # 加上新属性
print("装备物品:", new_property.goods_name)
func _on_Goods_unload(property) -> void:
change_property(property, false) # 减去属性
print("卸下物品:", property.goods_name)
测试物品装备场景
新建一个场景,添加 PanelContainer 为根节点,添加一个 HBoxContainer 节点,HBoxContainer 节点下添加一个 VBoxContainer 节点
然后将 EquipmentPanel 场景添加到 HBoxContainer 节点下面,Inventory 场景添加到 VBoxContainer 节点下,勾选 VBoxContainer 和 EquipmentPanel 节点的 size flag_horizontal
属性的 Expand
-
VBoxContainer 节点的
size_flag_stretch_ratio
属性设置为 0.7(在 Container 类型的节点里的占比为 0.7) -
EquipmentPanel 节点的
size_flag_stretch_ratio
属性设置为 0.3(在 Container 类型的节点里的占比为 0.3)
比如 EquipmentPanel 设置的属性
VBoxContainer 节点再添加一个 Label 节点,Label 节点的 rect_min_size
属性的 y
值设置为 100
,Label 节点名改为 PropertyLabel。根节点 PanelContainer 名称改为 Test,并添加一个脚本
场景的节点结构会是如下这样的:
选中 EquipmentPanel
节点,点击 property_changed
信号,连接到 Test 节点的脚本里。
Test 节点脚本代码如下:
## Test
## 测试物品场景
extends PanelContainer
onready var property_label = $HBoxContainer/VBoxContainer/PropertyLabel
onready var equip_panel = $HBoxContainer/EquipmentPanel
#------------------------------
# 节点带有的方法
#------------------------------
func _ready() -> void:
property_label.text = format_data_to_text(equip_panel.all_property)
#------------------------------
# 自定义方法
#------------------------------
## 格式化数据转为 text
func format_data_to_text(data) -> String:
var text = ""
for key in data:
text += key + ": " + str(data[key]) + "\n"
return text
#------------------------------
# 连接信号
#------------------------------
func _on_EquipmentPanel_property_changed(old_value, new_value) -> void:
# 显示装备栏里的属性这里你也可以自己写属性发生改变时,
# 对角色属性的进行修改的语句,这里我就不再写了。
property_label.text = format_data_to_text(new_value)
完成后 Inventory 场景里的 Goods 节点的 goods_property
属性可能变为空的,需要重新再添加一下,我们测试一下看看效果,下面是 Gif 效果图,注意下面的标签文字发生的改变。
下面是文件下载链接:
链接: https://pan.baidu.com/s/1CJqt37-sAZFIpg4–UWXug
提取码: yric