Godot4.3类星露谷游戏开发之【简易库存】(逻辑部分)

千里之行,始于足下

零、 笔记

制作简易库存,用于存放被收集的物品。在Godot4.3类星露谷游戏开发之【简易库存】(UI部分)的基础上,本章将进一步打通从 “收集物品” 到 “更新物品槽 UI 表现” 与 “同步物品字典数据” 的完整逻辑链;

请添加图片描述

一、设计架构

Godot4.3类星露谷游戏开发之【可收集物品】中,我们​​采用组件化思想,设计并创建了 可收集组件.tscn 。该组件可以作为任意物品的子节点,赋予物品可收集的功能。​现在,为了实现物品被收集后,同步变更物品数据的目标,设计架构如下:

发送收集请求
同步数据变更
可收集组件:
检测碰撞,触发收集
库存管理器:
管理数据,同步变更
库存UI:
展示物品,响应变更

二、附加脚本

(一)更新——可收集组件.gd

class_name 可收集组件
extends Area2D

signal 已收集

@export var 物品名: String
var 物品纹理: Texture2D


func _on_body_entered(body: Node2D) -> void:
	if body.is_in_group("玩家"):
		# 更新库存物品数据,将物品添加到库存面板物品槽
		物品纹理 = get_parent().texture
		if InventoryManager.尝试添加物品(物品名, 物品纹理):
			已收集.emit()
			get_parent().queue_free()
		else:
			print("物品槽已满,无法收集")

(二)库存管理器.gd(单例)

第一步,在路径 res://脚本/全局脚本/ 下创建独立脚本 库存管理器.gd

extends Node

signal 库存变更(物品字典, 物品纹理字典)  # 使用 Texture2D 类型

var 库存: Dictionary = {}  # 键: 物品名, 值: [数量, Texture2D]
var 占用槽位: int = 0  # 实时记录已占用的槽位数(数量>0的物品)

# 尝试添加物品到库存,返回是否成功
func 尝试添加物品(物品名: String, 物品纹理: Texture2D) -> bool:
	# 已有物品:增加数量
	if 库存.has(物品名):
		库存[物品名][0] += 1
		更新并发送库存信号()
		return true
	# 新物品:检查物品槽是否有空位
	elif 占用槽位 < 6:
		库存[物品名] = [1, 物品纹理]
		占用槽位 += 1  # 新增物品,槽位计数+1
		更新并发送库存信号()
		return true
	else:
		print("添加失败:物品槽已满(最多显示6种物品)")
		return false

# 尝试从库存中移除物品,返回是否成功
func 尝试移除物品(物品名: String, 数量: int = 1) -> bool:
	if not 库存.has(物品名):
		return false
	
	库存[物品名][0] -= 数量
	if 库存[物品名][0] <= 0:
		库存.erase(物品名)  # 数量为0时移除物品
		占用槽位 -= 1  # 物品移除,槽位计数-1
	
	更新并发送库存信号()
	return true

# 内部方法:更新并发送库存信号
func 更新并发送库存信号():
	# 准备要发送的数据
	var 物品字典 = {}
	var 物品纹理字典 = {}
	
	# 构建物品数量字典和物品纹理字典(此时库存中所有物品数量都>0)
	for 物品 in 库存.keys():
		物品字典[物品] = 库存[物品][0]  # 物品名: 数量
		物品纹理字典[物品] = 库存[物品][1]  # 物品名: 纹理
	
	库存变更.emit(物品字典, 物品纹理字典)  # 发送变更信号    

第二步,打开 项目->项目设置->全局,设置该脚本为 单例,并命名节点名称为 InventoryManager

在这里插入图片描述

(三)库存UI.gd

切换到 库存UI.tscn 场景,选中根节点 库存UI ,附加脚本;

extends NinePatchRect

# 物品槽UI元素引用(保持用户定义的变量名)
@onready var 物品纹理: TextureRect = $"MarginContainer/HBoxContainer/物品槽/物品纹理"
@onready var 物品数量: Label = $"MarginContainer/HBoxContainer/物品槽/物品纹理/物品数量"
@onready var 物品纹理2: TextureRect = $"MarginContainer/HBoxContainer/物品槽2/物品纹理2"
@onready var 物品数量2: Label = $"MarginContainer/HBoxContainer/物品槽2/物品纹理2/物品数量2"
@onready var 物品纹理3: TextureRect = $"MarginContainer/HBoxContainer/物品槽3/物品纹理3"
@onready var 物品数量3: Label = $"MarginContainer/HBoxContainer/物品槽3/物品纹理3/物品数量3"
@onready var 物品纹理4: TextureRect = $"MarginContainer/HBoxContainer/物品槽4/物品纹理4"
@onready var 物品数量4: Label = $"MarginContainer/HBoxContainer/物品槽4/物品纹理4/物品数量4"
@onready var 物品纹理5: TextureRect = $"MarginContainer/HBoxContainer/物品槽5/物品纹理5"
@onready var 物品数量5: Label = $"MarginContainer/HBoxContainer/物品槽5/物品纹理5/物品数量5"
@onready var 物品纹理6: TextureRect = $"MarginContainer/HBoxContainer/物品槽6/物品纹理6"
@onready var 物品数量6: Label = $"MarginContainer/HBoxContainer/物品槽6/物品纹理6/物品数量6"

# 物品槽UI元素数组(使用正确的变量名初始化)
var 物品图片数组 = []
var 物品数量数组 = []


func _ready():
	# 初始化物品槽数组(修正变量引用)
	物品图片数组 = [物品纹理, 物品纹理2, 物品纹理3, 物品纹理4, 物品纹理5, 物品纹理6]
	物品数量数组 = [物品数量, 物品数量2, 物品数量3, 物品数量4, 物品数量5, 物品数量6]
	
	# 连接库存变更信号
	InventoryManager.库存变更.connect(_on_库存变更)


func _on_库存变更(物品字典, 物品纹理字典):
	# 清空所有物品槽显示
	for i in range(6):
		物品图片数组[i].visible = false
		物品数量数组[i].text = ""
	
	# 更新有物品的槽位
	var 物品索引 = 0
	for 物品名 in 物品字典.keys():
		if 物品索引 >= 6:
			break
			
		var 数量 = 物品字典[物品名]
		var 纹理: Texture2D = 物品纹理字典[物品名]  # 明确指定 Texture2D 类型
		
		# 设置物品图片
		if 纹理:
			物品图片数组[物品索引].texture = 纹理
			物品图片数组[物品索引].visible = true
			
		# 设置物品数量(始终显示,不隐藏)
		物品数量数组[物品索引].text = str(数量)
		
		物品索引 += 1    

三、搭建测试环境

第一步,参考Godot4.3类星露谷游戏开发之【可收集物品】,创建多个可收集物品;

在这里插入图片描述

第二步,选中各个可收集物品场景中的 可收集组件 节点,并在检查器中填上 物品名 ,这里以 蛋.tscn 为例;

在这里插入图片描述
在这里插入图片描述
第三步,将可收集物品添加到 测试_简易库存.tscn 场景中,完成测试场景搭建;

在这里插入图片描述

四、测试

运行 测试_简易库存.tscn 场景,并收集所有可收集物品以测试;

请添加图片描述
发现收集木屋时,库存UI变形!据此可以定位到 库存UI.tscn 场景存在问题,采取措施如下:
回到 库存UI.tscn 场景中,分别选中各个 物品纹理 节点,更改 Expand Mode 为 Ignore Size,更改 Stretch Mode 为 Keep Aspect Centered

在这里插入图片描述
再次运行场景,问题得到解决;

请添加图片描述
测试完成!

五、免费开源资产包

精灵包链接:点击此处
UI包链接:点击此处

  1. 进入链接后点击下图按钮;
    下载

  2. 然后点击【No thanks,just take me to the downloads】(不了谢谢,只想下载);
    No thanks,just take me to the downloads

  3. 最后点击下图按钮完成下载(注意导入前需解压缩)。
    下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ForBigData

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值