【GDScript】装备栏

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

Goods.tscn 场景里添加一个 TextureRect 节点,节点名称改为 Background,勾选 show_behind_parent 属性,设置 self modulate 属性为黑色,勾选 expand 属性,设置 rect_min_size 属性为 50x50
在这里插入图片描述

rect_min_size 属性

场景节点如下
在这里插入图片描述

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 属性上,用于拖拽时隐藏背景图。

get_drag_data 方法里添加一行代码 drag_node.background_rect.visible = false
在这里插入图片描述


装备面板场景

新建一个场景,添加一个 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 节点下,勾选 VBoxContainerEquipmentPanel 节点的 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 值设置为 100Label 节点名改为 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/1Q9nNBGmPGfkVKwyUIcTKGw
提取码: xw2c

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值