Godot 3.3 rc6
接着上个教程 【GDScript】装备栏
我们开始给物品数据加载出来,之前使用资源的方式是用来加载小量数据的,如果是大量数据,那就不可避免需要加载文件中的数据。
加载数据代码见上个文章【GDScript】加载 csv 文件,转化为字典
开始设置文件的数据
保存为 csv 文件,我们保存名称为 GoodsData.csv
接下来我们在 文件系统 中创建一个 data 文件夹,将文件 GoodsData.csv 放在里面
可以看到这个显示了 错误的图标,输出中报错。这是因为 Godot 不识别这种文件,导入错误。
我们在 data 文件夹下创建一个名字为 .gdignore
的文件,Godot 会在导入的时候忽略这个文件夹,创建完我们退出项目,按 Ctrl + Shift + Q 或者选择菜单 项目-退出到项目列表 退出。我们再重新打开这个项目。
可以看到文件系统中没有这个文件夹了
我们在 autoload 文件夹中创建一个 GoodsFactory.gd 脚本文件,然后把这个脚本添加到 自动加载 里,用来获取物品节点
(如果不知道 自动加载 在哪里,看上个文章 【GDScript】加载 csv 文件,转化为字典 的下半部分内容
打开之前做的 GoodsProperty.gd 脚本,修改 GoodsProperty 的 AttackRange 为 AttackRange,之前一个小失误
改为
然后我们在 GoodsFactory.gd 脚本里写入如下内容
## GoodsFactory
## 物品工厂
extends Node
## 物品属性
const GoodsProperty = preload("res://inventory/GoodsProperty.gd")
## 物品场景文件
const ScnGoods = preload("res://inventory/Goods.tscn")
## 物品属性列表
const GoodsPropertyList = GoodsProperty.GoodsProperty
# 存放物品图片的文件夹(这里我创建了这些路径)
const GoodsPicturePath = "res://assets/texture/goods/"
## 物品数据
var goods_data = {}
#------------------------------
# 节点带有的方法
#------------------------------
func _ready():
## 获取物品数据
goods_data = FileManager.parse_csv_file("res://data/GoodsData.csv", "Name")
#------------------------------
# 自定义方法
#------------------------------
## 返回一个物品
## @goods_name 物品名称
## @return 返回一个物品的节点
func get_goods(goods_name: String):
if goods_data.has(goods_name):
var data = get_goods_data(goods_name) # 物品数据
var res_property = GoodsProperty.new()
## 设置物品属性资源的属性数据
res_property.set_property(data)
## 返回物品节点
var goods = ScnGoods.instance()
goods.set_goods_property(res_property) # 设置物品属性
return goods
else:
print_debug("没有【%s】这个物品" % goods_name)
return null
## 返回物品数据
## --------------
## 做这个方法的原因是因为,数据的属性可能与文件的属性数据不一致的问题
## 我们在这里将数据转为 符合物品属性数据格式 的数据
func get_goods_data(goods_name: String):
var data = goods_data[goods_name] # 物品数据
var temp = {}
# 设置资源的格式:变量[属性名] = 属性值
temp[GoodsPropertyList.Name] = data['Name']
temp[GoodsPropertyList.Damage] = int(data['Damage'])
temp[GoodsPropertyList.MoveSpeed] = int(data['MoveSpeed'])
temp[GoodsPropertyList.AttackRange] = int(data['AttackRange'])
temp[GoodsPropertyList.Price] = int(data['Price'])
temp[GoodsPropertyList.Texture] = get_goods_texture(data['Picture'])
return temp
## 获取物品图片
## @picture_name 物品图片名称
## @return 返回物品的图片
var file = File.new()
func get_goods_texture(picture_name: String) -> Texture:
var path = GoodsPicturePath + picture_name + ".png" # 物品图片路径
# 如果存在图片,则返回图片
if file.file_exists(path):
return load(path) as Texture
# 如果不存在,则返回默认的 icon 图片
else:
return preload("res://icon.png")
现在我们做好的关于 获取物品 的脚本,在这里我没有在 res://assets/texture/goods/
文件夹下边放图片,但你如果有图片文件,你可以修改为和你的 Picture 名称相同的图片文件,然后它会自己加载
现在我们开始给 Inventory 增加“添加物品”的功能
打开 Inventory.tscn 场景,添加脚本,写入如下代码:
## Inventory
extends PanelContainer
onready var grid = $Margin/Grid
#------------------------------
# 节点带有的方法
#------------------------------
func _ready():
add_goods("金疮药")
add_goods("桃木剑")
add_goods("生锈铁剑")
#------------------------------
# 自定义方法
#------------------------------
## 添加物品
## @item_name 物品名称
func add_goods(item_name: String):
var goods = GoodsFactory.get_goods(item_name)
if goods:
grid.add_child(goods)
我们再打开之前做的 Goods.tscn 场景,选中 TextureRect 节点,添加脚本,代码如下:
extends TextureRect
## 鼠标指上去显示数据
func _make_custom_tooltip(for_text):
var label = Label.new()
var goods_data = get_parent().goods_property.get_property() # 物品数据
label.text = JSON.print(goods_data, '\t')
return label # 返回这个标签,显示数据
然后给 TextureRect 节点的 hint_tooltip
属性添加文字,任何非空格字符串都可以这样鼠标指上去会调用 _make_custom_tooltip
方法,我给它设置成 111,任何字符都无所谓
我们再切回 Inventory.tscn 场景,按 F6 运行测试一下,鼠标指到物品上,然后显示出了物品信息:
我是为了省事演示的方式做成这样,你可以在上面的 Texture 节点的脚本的 _make_custom_tooltip
方法里边设置自己的标签然后让他显示出来。
可以看到中文字体没有显示出来,是因为 Godot 标签内置的还不支持中文,我们需要手动给他设置中文字体
点击 Inventory.tscn 场景的 theme
属性,点击创建 theme 资源
点击下边的 default font ,创建 DynamicFont
资源
在 font_data 属性里拖拽一个字体文件到里面,下方我会给出项目文件,里面有字体,或者你在 windows 里边有 Fonts 字体文件夹(自己百度 Fonts 文件夹位置),选择一个中文字体复制到 Godot 项目的文件夹里,然后设置
然后再按 F6 测试一下场景,这次可以看到有中文字体了
项目文件:
百度网盘链接: https://pan.baidu.com/s/1qq9VGfWCrcDplqC-0tZVFw
提取码: gu6g
文中如有错误,欢迎指正。